* [PATCH 6.1 0001/1887] io-wq: order the exit bit against worker creation task work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
@ 2026-10-28 16:34 ` Greg Kroah-Hartman
2026-10-28 16:34 ` [PATCH 6.1 0002/1887] io_uring/io-wq: dont lose the signal that ends work Greg Kroah-Hartman
` (997 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:34 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jens Axboe, Oleg Nesterov,
Christian Brauner (Amutable)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
Commit 0e5663856b69219ef2f02e04bac9f5c5be19718a upstream.
io_wq_exit_workers() cancels task work for queued worker creation with
task_work_cancel_match(). That has a plain load of task->task_works.
io_queue_worker_create() adds the new entry and tests IO_WQ_BIT_EXIT to
cancel it if the workqueue is already on its way out.
That must be ordered. task_work_add() has a full barrier via cmpxchg().
But io_wq_exit_start() sets the bit with set_bit() which doesn't have
any memory ordering.
So afaict, on weakly ordered architectures the exiting task may load
task_works before the store of the bit is visible. The other side tests
the bit before the store is visible as well. So the entry remains queued
with worker_refs and the exiting task waits on worker_done indefinitely.
If the task still has rings then io_uring_del_tctx_node() provides the
barrier via test_and_set_bit() in io_wq_set_exit_on_idle(). When it
has closed all rings though that barrier is gone.
Add the barrier after the set_bit().
Fixes: 71a85387546e ("io-wq: check for wq exit after adding new worker task_work")
Cc: stable@vger.kernel.org
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Link: https://patch.msgid.link/20260921-work-coredump-fixes-v3-4-8e4adb1619e6@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 2 ++
1 file changed, 2 insertions(+)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -1251,6 +1251,8 @@ static bool io_task_work_match(struct ca
void io_wq_exit_start(struct io_wq *wq)
{
set_bit(IO_WQ_BIT_EXIT, &wq->state);
+ /* Pairs with task_work_add() in io_queue_worker_create(). */
+ smp_mb__after_atomic();
}
static void io_wq_cancel_tw_create(struct io_wq *wq)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0002/1887] io_uring/io-wq: dont lose the signal that ends work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
2026-10-28 16:34 ` [PATCH 6.1 0001/1887] io-wq: order the exit bit against worker creation task work Greg Kroah-Hartman
@ 2026-10-28 16:34 ` Greg Kroah-Hartman
2026-10-28 16:34 ` [PATCH 6.1 0003/1887] io_uring/io-wq: dont hide a link from cancellations Greg Kroah-Hartman
` (996 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:34 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 63c103279a95e82280092f2f4232e91e8117a252 upstream.
When a thread exits, only its tracked requests are cancelled. Then its
io-wq is torn down. io_wq_exit_workers() signals every worker, to get it
out of an interruptible sleep, and waits for all of them to exit. Before
they do, they go through the work that is left. Unbounded work is
cancelled. Bounded work is run, as it is expected to end by itself.
Not all of it does. An open has no file yet, so it counts as bounded, and
the open of a FIFO waits for the other end. That is what the signal is for.
But the workers are signalled once, and a worker that hasn't started the
work by then loses the signal:
io_wq_exit_workers() io_worker_handle_work()
io_wq_worker_wake()
set TIF_NOTIFY_SIGNAL
io_assign_current_work()
io_run_task_work()
clear TIF_NOTIFY_SIGNAL
io_wq_submit_work()
fifo_open()
wait_for_partner()
wait_for_completion_timeout()
The thread never gets out of do_exit():
IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC
exit of the thread that has submitted it
hangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is
killed.
Set TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT
set. The bit is set before the workers are signalled, and it is tested
after the flag has been cleared, with clear_notify_signal() providing the
barrier. So either the flag stays, or the bit is seen.
Work that is started while the io-wq exits is treated like work that is
being run at that time: it isn't interrupted unless it waits
interruptibly.
[ 6.1: work->flags is not atomic here ]
Fixes: afcc4015d1bf ("io-wq: provide an io_wq_put_and_exit() helper")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-4-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -598,8 +598,15 @@ static void io_worker_handle_work(struct
next_hashed = wq_next_work(work);
+ /*
+ * io_wq_exit_workers() signals us once, so that we
+ * don't sleep for ever. If that was before this work
+ * became the current one, the signal is gone.
+ */
if (unlikely(do_kill) && (work->flags & IO_WQ_WORK_UNBOUND))
work->flags |= IO_WQ_WORK_CANCEL;
+ else if (unlikely(do_kill))
+ set_notify_signal(current);
wq->do_work(work);
io_assign_current_work(worker, NULL);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0003/1887] io_uring/io-wq: dont hide a link from cancellations
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
2026-10-28 16:34 ` [PATCH 6.1 0001/1887] io-wq: order the exit bit against worker creation task work Greg Kroah-Hartman
2026-10-28 16:34 ` [PATCH 6.1 0002/1887] io_uring/io-wq: dont lose the signal that ends work Greg Kroah-Hartman
@ 2026-10-28 16:34 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0004/1887] io_uring: dont flood a cancelling task with task_work Greg Kroah-Hartman
` (995 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:34 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 436d48a2ed13112d2d27085325838e5bce6b4507 upstream.
A task that exits cancels its tracked requests and waits until they are
gone. io_uring_cancel_generic() looks everywhere a request can be, and
goes to sleep if it found nothing to cancel. It is woken up each time
one of the requests of the task is completed by task work or freed.
When io-wq is done with a request that has a link, there is a time in which
the next request of the link can't be found:
io_worker_handle_work()
io_assign_current_work(worker, NULL)
io_wq_free_work(work)
io_req_find_next() // takes the link off the request
io_free_req() // task work for the task
io_assign_current_work(worker, linked)
io_run_task_work()
cond_resched()
worker->cur_work = linked
It is not pending, it is not the current work of a worker, and it is not
yet on the list that it is about to be parked on. If the pass that the
exiting task makes because of io_free_req() falls into that time, it finds
nothing and the task goes to sleep. The worker then runs the link, which
IO_WQ_BIT_EXIT doesn't prevent for bounded work. If that parks the request
nothing is completed or freed, and nobody wakes up the task. If it is the
process that exits it can't be killed any more either.
NOP, IOSQE_ASYNC | IOSQE_IO_LINK
FUTEX_WAIT, FUTEX2_PRIVATE
exit of the thread, or of the process, up to 63us later
With four of these per round 5 to 8 of 10,000 rounds hang (4 CPUs, KVM):
io_uring_cancel_generic
do_exit
Commit f8b632e89a10 ("io_uring: tighten task exit cancellations") is about
the same gap, and makes the task look again for whatever happens before
io_free_req().
Free the request once the link is the current work of the worker, or
pending. Whoever is woken up by that can find the link, until it is parked
where cancellations look as well. To do so split io_wq_free_work() in two.
[ 6.1: io-wq calls back through struct io_wq_data, so the split is a new
->put_work callback next to ->free_work, and io_put_req_find_next() is
folded into io_wq_put_work(). io_wq_put_work() keeps the link check of
6.1, without the REQ_F_CQE_SKIP condition that commit 5530a5102e3c
adds in 7.3 ]
Fixes: 768134d4f481 ("io_uring: don't do flush cancel under inflight_lock")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-5-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 22 ++++++++++++++++++----
io_uring/io-wq.h | 4 +++-
io_uring/io_uring.c | 42 ++++++++++++++++++++++--------------------
io_uring/io_uring.h | 3 ++-
io_uring/tctx.c | 1 +
5 files changed, 46 insertions(+), 26 deletions(-)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -118,6 +118,7 @@ struct io_wqe {
struct io_wq {
unsigned long state;
+ put_work_fn *put_work;
free_work_fn *free_work;
io_wq_work_fn *do_work;
@@ -593,8 +594,9 @@ static void io_worker_handle_work(struct
/* handle a whole dependent link */
do {
bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
- struct io_wq_work *next_hashed, *linked;
+ struct io_wq_work *next_hashed, *linked, *done = work;
unsigned int hash = io_get_work_hash(work);
+ bool last;
next_hashed = wq_next_work(work);
@@ -610,7 +612,7 @@ static void io_worker_handle_work(struct
wq->do_work(work);
io_assign_current_work(worker, NULL);
- linked = wq->free_work(work);
+ last = wq->put_work(work, &linked);
work = next_hashed;
if (!work && linked && !io_wq_is_hashed(linked)) {
work = linked;
@@ -619,6 +621,13 @@ static void io_worker_handle_work(struct
io_assign_current_work(worker, work);
if (linked)
io_wqe_enqueue(wqe, linked);
+ /*
+ * Not before the link is current or pending work again.
+ * This may be the last time that a task is woken up
+ * which exits and looks for requests to cancel.
+ */
+ if (last)
+ wq->free_work(done);
if (hash != -1U && !next_hashed) {
/* serialize hash clear with wake_up() */
@@ -899,9 +908,13 @@ static void io_run_cancel(struct io_wq_w
struct io_wq *wq = wqe->wq;
do {
+ struct io_wq_work *linked;
+
work->flags |= IO_WQ_WORK_CANCEL;
wq->do_work(work);
- work = wq->free_work(work);
+ if (wq->put_work(work, &linked))
+ wq->free_work(work);
+ work = linked;
} while (work);
}
@@ -1170,7 +1183,7 @@ struct io_wq *io_wq_create(unsigned boun
struct io_wq *wq;
cpumask_var_t allowed_mask;
- if (WARN_ON_ONCE(!data->free_work || !data->do_work))
+ if (WARN_ON_ONCE(!data->put_work || !data->free_work || !data->do_work))
return ERR_PTR(-EINVAL);
if (WARN_ON_ONCE(!bounded))
return ERR_PTR(-EINVAL);
@@ -1184,6 +1197,7 @@ struct io_wq *io_wq_create(unsigned boun
refcount_inc(&data->hash->refs);
wq->hash = data->hash;
+ wq->put_work = data->put_work;
wq->free_work = data->free_work;
wq->do_work = data->do_work;
--- a/io_uring/io-wq.h
+++ b/io_uring/io-wq.h
@@ -21,7 +21,8 @@ enum io_wq_cancel {
IO_WQ_CANCEL_NOTFOUND, /* work not found */
};
-typedef struct io_wq_work *(free_work_fn)(struct io_wq_work *);
+typedef bool (put_work_fn)(struct io_wq_work *, struct io_wq_work **);
+typedef void (free_work_fn)(struct io_wq_work *);
typedef void (io_wq_work_fn)(struct io_wq_work *);
struct io_wq_hash {
@@ -40,6 +41,7 @@ struct io_wq_data {
struct io_wq_hash *hash;
struct task_struct *task;
io_wq_work_fn *do_work;
+ put_work_fn *put_work;
free_work_fn *free_work;
};
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -1348,22 +1348,6 @@ static void __io_submit_flush_completion
INIT_WQ_LIST(&state->compl_reqs);
}
-/*
- * Drop reference to request, return next in chain (if there is one) if this
- * was the last reference to this request.
- */
-static inline struct io_kiocb *io_put_req_find_next(struct io_kiocb *req)
-{
- struct io_kiocb *nxt = NULL;
-
- if (req_ref_put_and_test(req)) {
- if (unlikely(req->flags & IO_REQ_LINK_FLAGS))
- nxt = io_req_find_next(req);
- io_free_req(req);
- }
- return nxt;
-}
-
static unsigned io_cqring_events(struct io_ring_ctx *ctx)
{
/* See comment at the top of this file */
@@ -1781,12 +1765,30 @@ int io_poll_issue(struct io_kiocb *req,
return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT);
}
-struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
+/*
+ * io-wq is done with @work. Returns true if it held the last reference, and
+ * hands out the next request of the link then. The caller has to make sure
+ * that cancellations can find the latter before it calls io_wq_free_work().
+ */
+bool io_wq_put_work(struct io_wq_work *work, struct io_wq_work **linked)
{
struct io_kiocb *req = container_of(work, struct io_kiocb, work);
+ struct io_kiocb *nxt = NULL;
+
+ *linked = NULL;
+ if (!req_ref_put_and_test(req))
+ return false;
- req = io_put_req_find_next(req);
- return req ? &req->work : NULL;
+ if (unlikely(req->flags & IO_REQ_LINK_FLAGS))
+ nxt = io_req_find_next(req);
+ if (nxt)
+ *linked = &nxt->work;
+ return true;
+}
+
+void io_wq_free_work(struct io_wq_work *work)
+{
+ io_free_req(container_of(work, struct io_kiocb, work));
}
void io_wq_submit_work(struct io_wq_work *work)
@@ -1797,7 +1799,7 @@ void io_wq_submit_work(struct io_wq_work
bool needs_poll = false;
int ret = 0, err = -ECANCELED;
- /* one will be dropped by ->io_free_work() after returning to io-wq */
+ /* one will be dropped by ->put_work() after returning to io-wq */
if (!(req->flags & REQ_F_REFCOUNT))
__io_req_set_refcount(req, 2);
else
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -70,7 +70,8 @@ int io_do_iopoll(struct io_ring_ctx *ctx
void io_free_batch_list(struct io_ring_ctx *ctx, struct io_wq_work_node *node);
int io_req_prep_async(struct io_kiocb *req);
-struct io_wq_work *io_wq_free_work(struct io_wq_work *work);
+bool io_wq_put_work(struct io_wq_work *work, struct io_wq_work **linked);
+void io_wq_free_work(struct io_wq_work *work);
void io_wq_submit_work(struct io_wq_work *work);
void io_free_req(struct io_kiocb *req);
--- a/io_uring/tctx.c
+++ b/io_uring/tctx.c
@@ -35,6 +35,7 @@ static struct io_wq *io_init_wq_offload(
data.hash = hash;
data.task = task;
+ data.put_work = io_wq_put_work;
data.free_work = io_wq_free_work;
data.do_work = io_wq_submit_work;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0004/1887] io_uring: dont flood a cancelling task with task_work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-10-28 16:34 ` [PATCH 6.1 0003/1887] io_uring/io-wq: dont hide a link from cancellations Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0005/1887] io_uring/io-wq: dont strand work when a worker exits Greg Kroah-Hartman
` (994 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 22e643e61b9b6299b42ff7d88bab48bccada8a5d upstream.
io_ring_exit_work() asks each task which has used the ring to remove its
tctx node, by task_work, and repeats that until the list is empty.
io_tctx_exit_cb() doesn't touch the node while the task is in
io_uring_cancel_generic(), which removes all the nodes at its end. So the
work item queues the callback again as soon as it has completed, for
nothing.
That is more than a waste of time. task_work_run() only returns when it
finds the list empty. If the rings are released from inside the
cancellation, because requests of other rings held the last references to
their files, up to 64 work items keep sending callbacks to the one task
which is running them. It never finds the list empty, never gets back to
the cancellation, the nodes stay, and so it goes on: a task with 60 pairs
of rings which poll each other ran 280000 callbacks in 5 seconds, 20
seconds after exit_group(). It ends when all the senders happen to be late
at the same time. Until then the task keeps a CPU and the work items busy.
An exiting task can't be killed meanwhile. execve() cancels the requests in
the same way, so a live task can get stuck there as well, for minutes. If
it takes more than five, the work items run into the
WARN_ON_ONCE(time_after(jiffies, timeout)) of io_ring_exit_work(). No
privilege is needed for any of this.
If the callback has met a task in cancellation, wait a little before it is
sent again. Nobody has to wake the work item up for that: either the node
is gone by then, or it is the turn of the next round.
Fixes: d56d938b4bef ("io_uring: do ctx initiated file note removal")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-6-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io_uring.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2829,6 +2829,7 @@ struct io_tctx_exit {
struct callback_head task_work;
struct completion completion;
struct io_ring_ctx *ctx;
+ bool in_cancel;
};
static __cold void io_tctx_exit_cb(struct callback_head *cb)
@@ -2843,7 +2844,8 @@ static __cold void io_tctx_exit_cb(struc
* tctx can be NULL if the queueing of this task_work raced with
* work cancelation off the exec path.
*/
- if (tctx && !atomic_read(&tctx->in_idle))
+ work->in_cancel = tctx && atomic_read(&tctx->in_idle);
+ if (tctx && !work->in_cancel)
io_uring_del_tctx_node((unsigned long)work->ctx);
complete(&work->completion);
}
@@ -2931,6 +2933,14 @@ static __cold void io_ring_exit_work(str
* wait is marked as interruptible.
*/
wait_for_completion_interruptible(&exit.completion);
+ /*
+ * The task removes the node when it is done with its
+ * cancellation. Give it the time for that: it doesn't get back
+ * to it as long as it finds new task_work each time it has run
+ * the old one, and we may be one of many who send it.
+ */
+ if (exit.in_cancel)
+ schedule_timeout_idle(HZ / 20);
mutex_lock(&ctx->uring_lock);
}
mutex_unlock(&ctx->uring_lock);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0005/1887] io_uring/io-wq: dont strand work when a worker exits
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0004/1887] io_uring: dont flood a cancelling task with task_work Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0006/1887] io_uring/io-wq: dont exit with a creation pending Greg Kroah-Hartman
` (993 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit ad41f325be1271b22d99353819c90f0d5e45acc8 upstream.
A worker exits if its idle timeout fired and it isn't the last one, if
its affinity was changed, or if the wq is marked exit-on-idle. It decides
so after it found the work list empty, and until io_worker_exit() is
through it stays on the free list and in ->nr_running:
worker io_wq_enqueue()
io_acct_run_queue() == false
queues work
io_acct_activate_free_worker()
wake_up_process(worker)
// found one, nothing to create
acct->nr_workers--
break
io_worker_exit()
Nobody is going to look at the work. If other workers exist, it has to
wait until one of them finishes what it is blocked on or hits its idle
timeout. If not, which is possible for the affinity and the exit-on-idle
case, it sits there until something else is queued. For exit-on-idle it
takes a task that closes its last ring and sets up a new one while the
workers are on their way out.
Make the worker take itself off the free list when it gives up its
->nr_workers slot, then leave ->nr_running, and only then take the final
look at the work list. That look and queueing work are both done under
acct->lock, so either the worker sees the work and stays, or the enqueue
side sees that the worker is gone and wakes or creates another one. If it
wants to stay and finds that its slot has been taken, a worker has been
created in its place, which is going to look at the work list, and it can
leave after all.
[ 6.1: no exit-on-idle state, per-node io_wqe with ->lock for the
workers and non-atomic worker flags; io_acct_run_queue() drops
acct->lock itself here ]
Fixes: 38aa434ab933 ("io_uring/io-wq: add exit-on-idle state")
Fixes: 05c5f4ee4da7 ("io-wq: get rid of FIXED worker flag")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-11-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -642,6 +642,36 @@ static void io_worker_handle_work(struct
} while (1);
}
+/*
+ * The worker has decided to exit, and has given up its ->nr_workers slot and
+ * its place on the free list. io_wqe_enqueue() may have picked it from that
+ * list, or seen it running, after it last looked at the work list. Leave
+ * ->nr_running as well and check again. Returns false if the worker has to
+ * stay.
+ */
+static bool io_worker_retire(struct io_wqe *wqe, struct io_worker *worker)
+{
+ struct io_wqe_acct *acct = io_wqe_get_acct(worker);
+
+ /* turns io_wqe_dec_running() and the scheduler hooks into no-ops */
+ worker->flags &= ~IO_WORKER_F_UP;
+ atomic_dec(&acct->nr_running);
+ if (!io_acct_run_queue(acct))
+ return true;
+
+ raw_spin_lock(&wqe->lock);
+ if (acct->nr_workers >= acct->max_workers) {
+ /* a worker was created in our place, the work is its business */
+ raw_spin_unlock(&wqe->lock);
+ return true;
+ }
+ acct->nr_workers++;
+ raw_spin_unlock(&wqe->lock);
+ atomic_inc(&acct->nr_running);
+ worker->flags |= IO_WORKER_F_UP;
+ return false;
+}
+
static int io_wqe_worker(void *data)
{
struct io_worker *worker = data;
@@ -670,9 +700,16 @@ static int io_wqe_worker(void *data)
*/
if (last_timeout && (exit_mask || acct->nr_workers > 1)) {
acct->nr_workers--;
+ if (worker->flags & IO_WORKER_F_FREE) {
+ worker->flags &= ~IO_WORKER_F_FREE;
+ hlist_nulls_del_init_rcu(&worker->nulls_node);
+ }
raw_spin_unlock(&wqe->lock);
__set_current_state(TASK_RUNNING);
- break;
+ if (io_worker_retire(wqe, worker))
+ break;
+ last_timeout = false;
+ continue;
}
last_timeout = false;
__io_worker_idle(wqe, worker);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0006/1887] io_uring/io-wq: dont exit with a creation pending
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0005/1887] io_uring/io-wq: dont strand work when a worker exits Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0007/1887] io_uring/io-wq: let cancel find picked up hashed work Greg Kroah-Hartman
` (992 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit e231d2e8f80d3649ecd3851b7f2abdfbe606c04b upstream.
A worker that is the last one to go to sleep while work is pending asks
for another worker. io_wq_dec_running() bumps ->nr_running on behalf of
the new worker and queues create_worker_cb() as task_work for the owner
of the io-wq. Until that has run, everybody else takes it that a worker
is running which is going to look after the work list: io_wq_enqueue()
doesn't create one, and other workers that go to sleep don't find
themselves to be the last.
If the worker that made the request exits, io_worker_exit() cancels the
task_work, and io_worker_cancel_cb() drops ->nr_running without a look at
the work list:
worker A worker B io_wq_enqueue()
blocks, work is pending
nr_running++
queues create_worker_cb()
wakes, handles the work
idle timeout, decides to exit
picks up work 1
queues work 2
B is on the free list
still: wakes B
work 1 blocks
nr_running 2 -> 1
io_worker_exit()
io_worker_cancel_cb()
nr_running 1 -> 0
Work 2 has to wait for work 1, although there is room for more workers.
It takes an owner that doesn't get around to run its task_work for the
time of the idle timeout, less if the worker exits because its affinity
was changed or the io-wq is marked exit-on-idle.
Let the worker stay around until its request has been dealt with. Only
the worker itself sets ->create_state, so it can't be set behind its
back once it has decided to leave.
[ 6.1: no exit-on-idle state ]
Fixes: 1d5f5ea7cb7d ("io-wq: remove worker to owner tw dependency")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-12-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -697,8 +697,12 @@ static int io_wqe_worker(void *data)
/*
* Last sleep timed out. Exit if we're not the last worker,
* or if someone modified our affinity.
+ * Not as long as a request of ours for another worker is
+ * pending, though. It is accounted as a running worker, which
+ * others rely on, and io_worker_exit() would cancel it.
*/
- if (last_timeout && (exit_mask || acct->nr_workers > 1)) {
+ if (last_timeout && (exit_mask || acct->nr_workers > 1) &&
+ !test_bit(0, &worker->create_state)) {
acct->nr_workers--;
if (worker->flags & IO_WORKER_F_FREE) {
worker->flags &= ~IO_WORKER_F_FREE;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0007/1887] io_uring/io-wq: let cancel find picked up hashed work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0006/1887] io_uring/io-wq: dont exit with a creation pending Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0008/1887] io_uring/poll: dont lose a cancel as io-wq arms poll Greg Kroah-Hartman
` (991 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit e9efeb4fc97b0879512a3c3b995ed448f2487e12 upstream.
io_get_next_work() takes all the work items that share a hash off the
work list in one go, and the worker runs them one after the other. Only
the one it is working on is visible as ->cur_work. The others are neither
on the list nor current, so io_wq_cancel_cb() can't find them.
IORING_OP_ASYNC_CANCEL and IORING_REGISTER_SYNC_CANCEL return -ENOENT for
a request that has not even been started, e.g. a buffered write queued
behind another write to the same file that is blocked, and the request is
carried out. The cancellation done for a task or ring that goes away gets
there in the end, as it keeps trying, but it has to wait for each item to
become current.
Keep a pointer to the remainder of the chain next to ->cur_work, and have
io_wq_worker_cancel() look at it. The items on it belong to the worker,
which needs ->lock to move on to the next one. Matching work is flagged
with IO_WQ_WORK_CANCEL and fails with -ECANCELED when its turn comes. The
worker isn't signalled for it, that would interrupt the unrelated work it
is busy with. As the request isn't gone yet, it is reported like running
work, with -EALREADY.
[ 6.1: ->next_work is the item being picked up here, which
io_wq_worker_cancel() checks next to ->cur_work, so the chain
remainder is a new ->chain_work, set when the item is picked up as
well. work->flags is not atomic here ]
Fixes: 86f3cd1b589a ("io-wq: handle hashed writes in chains")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-13-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io-wq.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -53,6 +53,8 @@ struct io_worker {
struct io_wq_work *cur_work;
struct io_wq_work *next_work;
+ /* rest of the hashed chain ->next_work or ->cur_work came with */
+ struct io_wq_work *chain_work;
raw_spinlock_t lock;
struct completion ref_done;
@@ -548,6 +550,9 @@ static void io_assign_current_work(struc
raw_spin_lock(&worker->lock);
worker->cur_work = work;
worker->next_work = NULL;
+ /* stays valid while in between two items of a chain */
+ if (work)
+ worker->chain_work = wq_next_work(work);
raw_spin_unlock(&worker->lock);
}
@@ -584,6 +589,7 @@ static void io_worker_handle_work(struct
*/
raw_spin_lock(&worker->lock);
worker->next_work = work;
+ worker->chain_work = wq_next_work(work);
raw_spin_unlock(&worker->lock);
} else {
break;
@@ -1073,6 +1079,7 @@ static bool __io_wq_worker_cancel(struct
static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
{
struct io_cb_cancel_data *match = data;
+ struct io_wq_work *work;
/*
* Hold the lock to avoid ->cur_work going out of scope, caller
@@ -1082,6 +1089,19 @@ static bool io_wq_worker_cancel(struct i
if (__io_wq_worker_cancel(worker, match, worker->cur_work) ||
__io_wq_worker_cancel(worker, match, worker->next_work))
match->nr_running++;
+ /*
+ * Hashed work is taken off the work list a chain at a time, what the
+ * worker hasn't started yet can only be found here. It doesn't move on
+ * without the lock. Just mark the work, it fails once it is its turn.
+ */
+ for (work = worker->chain_work; work; work = wq_next_work(work)) {
+ if (match->nr_running && !match->cancel_all)
+ break;
+ if (match->fn(work, match->data)) {
+ work->flags |= IO_WQ_WORK_CANCEL;
+ match->nr_running++;
+ }
+ }
raw_spin_unlock(&worker->lock);
return match->nr_running && !match->cancel_all;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0008/1887] io_uring/poll: dont lose a cancel as io-wq arms poll
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0007/1887] io_uring/io-wq: let cancel find picked up hashed work Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0009/1887] io_uring/cancel: dont forget that the work was running Greg Kroah-Hartman
` (990 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 6d2d4c2530e95ff6ddeb98195d49d99dbca14369 upstream.
A request on a pollable file that was forced to io-wq is issued without
blocking there. If that ends in -EAGAIN, io_wq_submit_work() arms poll
for it and returns. It looks at IO_WQ_WORK_CANCEL once, before it issues
the request.
Somebody who wants to cancel the request in between finds it running:
io-wq worker io_try_cancel()
io_wq_submit_work()
IO_WQ_WORK_CANCEL isn't set
io_issue_sqe() = -EAGAIN
io_async_cancel_one()
sets IO_WQ_WORK_CANCEL
signals the worker
= -EALREADY
io_poll_cancel() = -ENOENT
...
= -ENOENT
io_arm_poll_handler() = IO_APOLL_OK
return
Nobody looks at the flag again, and the signal doesn't matter to a
worker that doesn't sleep. The request is armed as if nothing had
happened:
- a linked timeout completes with -ENOENT, and the request it was
meant to limit waits for as long as it takes.
- IORING_OP_ASYNC_CANCEL returns -EALREADY, and the request stays.
- IORING_REGISTER_SYNC_CANCEL waits for the request to complete if it
gets -EALREADY. Since commit 5623eb1ed035 ("io_uring/tctx: add
separate lock for list of tctx's in ctx") it doesn't sleep but spins,
so its next attempt finds the armed poll.
The same goes for a multishot poll, recv or accept that is armed from
io-wq.
With a read of an empty pipe, IOSQE_ASYNC, and a linked timeout of 5ms
or a cancel in the same submission, in a guest that is slow enough (TCG,
KASAN), the request is lost in 21 of 24 rounds of 40 or 100 attempts.
While it arms poll from io-wq, __io_arm_poll_handler() owns the request.
Look at the flag once the request is in the hash table. The table is
searched and the request is added with ->uring_lock held, and the flag is
set before the search. So either the search finds the request, or it
came first and the flag is seen. With the request marked as cancelled, the
task work that is queued, right away or because ownership can't be
released, fails it with -ECANCELED.
What the canceller is told doesn't change. In this window a linked timeout
still completes with -ENOENT rather than -ETIME, a cancel request with
-EALREADY, and one with IORING_ASYNC_CANCEL_ALL or _ANY with a count that
doesn't include the request. But the request is cancelled, so what is new
is a request that completes with -ECANCELED after such a result.
This doesn't help in two cases:
- IORING_ASYNC_CANCEL_ALL and _ANY, if the work is flagged after the
test added here, while io-wq still has it as the current work of the
worker. io_cancel_cb() stamps it with the sequence of the cancel, so the
search of the hash table on behalf of the same cancel takes it for
done and skips it.
- requests that are parked elsewhere by io-wq, like IORING_OP_FUTEX_WAIT
and IORING_OP_WAITID. They have the same problem.
[ 6.1: work->flags is not atomic here, the hash table has its own locks
]
Fixes: 90fa02883f06 ("io_uring: implement async hybrid mode for pollable requests")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-14-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/poll.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -652,6 +652,17 @@ static int __io_arm_poll_handler(struct
io_poll_add_hash(req);
+ /*
+ * Whoever tried to cancel the request while io-wq was running it has
+ * flagged the work item. If it searched the hash table before the
+ * request got there it found nothing, and it won't come back. Both
+ * the search and the insertion are done with the hash bucket lock
+ * held, and the flag is set before the search. If the search came
+ * first, the flag is visible by now.
+ */
+ if (ipt->owning && (req->work.flags & IO_WQ_WORK_CANCEL))
+ io_poll_mark_cancelled(req);
+
if (mask && (poll->events & EPOLLET) &&
io_poll_can_finish_inline(req, ipt)) {
__io_poll_execute(req, mask);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0009/1887] io_uring/cancel: dont forget that the work was running
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0008/1887] io_uring/poll: dont lose a cancel as io-wq arms poll Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0010/1887] io_uring/cancel: recognize "no timeout" on 32-bit Greg Kroah-Hartman
` (989 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 8aa0e5db4845fb5ac11abe40d7b1cac0656c3ee3 upstream.
If the request to be cancelled is being run by io-wq,
io_async_cancel_one() flags the work, signals the worker and returns
-EALREADY. Since commit ccbf726171b7 ("io_uring: perform poll removal even
if async work removal is successful") io_try_cancel() goes on regardless,
as poll may be armed for the request. If it isn't, and nothing else turns
up, the result is the -ENOENT of the last search.
__io_async_cancel() makes up for that. On -ENOENT it tries the io-wq of
every task that uses the ring, and that of the caller is one of them. So
the work is found a second time, and the result is -EALREADY after all.
Unless the worker is done with it by then. If the work is flagged before
io_wq_submit_work() looks at IO_WQ_WORK_CANCEL, all the worker does is to
queue the request to be failed by task work. Then it isn't anywhere to be
found until the task work has run, and
- IORING_REGISTER_SYNC_CANCEL returns -ENOENT,
- IORING_OP_ASYNC_CANCEL completes with -ENOENT,
for a request that they have just cancelled, and that completes with
-ECANCELED.
With a read of an empty pipe, IOSQE_ASYNC, and a sync cancel right behind
it, 1 to 3 of 1,000,000 calls return -ENOENT, and 50 to 110 with
IORING_SETUP_DEFER_TASKRUN (4 CPUs, KVM). Nothing is written to the pipe,
and all of these reads end with -ECANCELED.
Remember that the work was found. IORING_OP_ASYNC_CANCEL completes with
-EALREADY, as it does if the worker is a bit slower. For
IORING_REGISTER_SYNC_CANCEL it means to try again, which ends with 0.
The result of a linked timeout, which calls io_try_cancel() by itself,
and the number that is returned for IORING_ASYNC_CANCEL_ALL and _ANY don't
change.
Fixes: ccbf726171b7 ("io_uring: perform poll removal even if async work removal is successful")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-16-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/cancel.c | 13 ++++++++++++-
io_uring/cancel.h | 2 ++
2 files changed, 14 insertions(+), 1 deletion(-)
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -114,6 +114,8 @@ int io_try_cancel(struct io_uring_task *
*/
if (!ret)
return 0;
+ if (ret == -EALREADY)
+ cd->running = true;
ret = io_poll_cancel(ctx, cd, issue_flags);
if (ret != -ENOENT)
@@ -162,6 +164,7 @@ static int __io_async_cancel(struct io_c
struct io_tctx_node *node;
int ret, nr = 0;
+ cd->running = false;
do {
ret = io_try_cancel(tctx, cd, issue_flags);
if (ret == -ENOENT)
@@ -185,7 +188,15 @@ static int __io_async_cancel(struct io_c
}
}
io_ring_submit_unlock(ctx, issue_flags);
- return all ? nr : ret;
+ if (all)
+ return nr;
+ /*
+ * The worker may be done with the work that was found running, and
+ * flagged, above. That isn't the same as not having found it.
+ */
+ if (ret == -ENOENT && cd->running)
+ ret = -EALREADY;
+ return ret;
}
int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags)
--- a/io_uring/cancel.h
+++ b/io_uring/cancel.h
@@ -9,6 +9,8 @@ struct io_cancel_data {
u8 opcode;
u32 flags;
int seq;
+ /* io_try_cancel() has found it being run by io-wq, and flagged it */
+ bool running;
};
int io_async_cancel_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0010/1887] io_uring/cancel: recognize "no timeout" on 32-bit
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0009/1887] io_uring/cancel: dont forget that the work was running Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0011/1887] io_uring/cancel: let CANCEL_ALL find parked requests Greg Kroah-Hartman
` (988 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 3774e4d4c8533da2caae95556c4d635c7c4f45b8 upstream.
IORING_REGISTER_SYNC_CANCEL waits without a limit if both fields of
io_uring_sync_cancel_reg::timeout are -1. io_sync_cancel() compares them
with -1UL. They are of type long long. With a long of 32 bits -1UL is
4294967295, which is what it stays when it is converted for the
comparison, and the fields are never equal to it.
So { -1, -1 } is taken for a timeout. ktime_set() takes the nanoseconds as
an unsigned long, so what becomes of it is -1s + 4294967295ns = 3.29s.
If the request is being run by io-wq and can't be interrupted, the call
returns -ETIME after that time, rather than waiting for the request to be
gone. On i386, with a buffered read from a null_blk device that takes 4s
to complete a request, IOSQE_ASYNC, that is what each call does.
Fixes: 78a861b94959 ("io_uring: add sync cancelation API through io_uring_register()")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-17-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/cancel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -306,7 +306,7 @@ int io_sync_cancel(struct io_ring_ctx *c
if (ret != -EALREADY)
goto out;
- if (sc.timeout.tv_sec != -1UL || sc.timeout.tv_nsec != -1UL) {
+ if (sc.timeout.tv_sec != -1 || sc.timeout.tv_nsec != -1) {
struct timespec64 ts = {
.tv_sec = sc.timeout.tv_sec,
.tv_nsec = sc.timeout.tv_nsec
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0011/1887] io_uring/cancel: let CANCEL_ALL find parked requests
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0010/1887] io_uring/cancel: recognize "no timeout" on 32-bit Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0012/1887] io_uring/wait: look at all CQ waiters on wake up Greg Kroah-Hartman
` (987 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit fe6ca13c98b1223f6005f32913ebd32e4df64b77 upstream.
A cancellation with IORING_ASYNC_CANCEL_ALL or _ANY goes on until it finds
nothing more. A request may stay where it was found for a while after it
has been cancelled, so each one that matches is stamped with the sequence
number of the cancellation, and is skipped from then on.
io_cancel_cb() does so for io-wq work as well. There is no need to:
pending work is taken off the list, and the workers are looked at once per
call. And it does harm. A request that is run by io-wq may be parked
while it still is the current work of the worker: poll gets armed for it,
or it is put on ->futex_list or ->waitid_list.
io-wq worker io_try_cancel()
io_wq_submit_work()
io_arm_poll_handler()
io_poll_add_hash()
io_async_cancel_one()
io_cancel_cb()
stamps the request
sets IO_WQ_WORK_CANCEL
= -EALREADY
io_poll_cancel()
skips the request
= -ENOENT
io_assign_current_work(NULL)
The flag comes too late for the worker to see it, and the search that
would have found the request takes it for done. The cancellation returns,
and the request stays.
With a multishot poll, IOSQE_ASYNC, and IORING_OP_ASYNC_CANCEL with
IORING_ASYNC_CANCEL_ALL up to 63us later, that happens to 4 of 1,000
requests (4 CPUs, KVM).
Take the stamp off again if the work matches. If the request is found
on one of the lists it gets a new one, and io_cancel_cb() doesn't match it
a second time.
__io_async_cancel() tries the io-wq of the caller twice. So far the stamp
has kept it from counting work that is running there the second time.
Skip it instead, so that the number that is returned stays the same.
[ 6.1: no ->cancel_seq_set, a request is skipped when ->work.cancel_seq
equals the sequence of the cancellation, so set it back to the one
before ]
Fixes: 8e29da69fead ("io_uring: add support for IORING_ASYNC_CANCEL_ALL")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-18-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/cancel.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -69,7 +69,16 @@ static bool io_cancel_cb(struct io_wq_wo
struct io_kiocb *req = container_of(work, struct io_kiocb, work);
struct io_cancel_data *cd = data;
- return io_cancel_req_match(req, cd);
+ if (!io_cancel_req_match(req, cd))
+ return false;
+ /*
+ * Pending work is gone once it has matched. Work that is running may
+ * park the request where the same cancellation looks next. Don't make
+ * it skip the request as one that it has dealt with.
+ */
+ if (cd->flags & (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY))
+ req->work.cancel_seq = cd->seq - 1;
+ return true;
}
static int io_async_cancel_one(struct io_uring_task *tctx,
@@ -178,9 +187,10 @@ static int __io_async_cancel(struct io_c
io_ring_submit_lock(ctx, issue_flags);
ret = -ENOENT;
list_for_each_entry(node, &ctx->tctx_list, ctx_node) {
- struct io_uring_task *tctx = node->task->io_uring;
-
- ret = io_async_cancel_one(tctx, cd);
+ /* has been done above, don't count what is running there */
+ if (all && node->task->io_uring == tctx)
+ continue;
+ ret = io_async_cancel_one(node->task->io_uring, cd);
if (ret != -ENOENT) {
if (!all)
break;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0012/1887] io_uring/wait: look at all CQ waiters on wake up
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0011/1887] io_uring/cancel: let CANCEL_ALL find parked requests Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0013/1887] io_uring/poll: drop stale double poll entry on rearm Greg Kroah-Hartman
` (986 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 356f92f2412686f822383b784fa102924407457a upstream.
io_wake_function() returns -1 if the waiter it is called for doesn't have
enough events yet, which makes __wake_up_common() stop walking the wait
queue. That assumes that the waiters behind it can't be satisfied either.
Each waiter has its own target though, computed from the min_complete it
passed in:
thread A: io_uring_enter(GETEVENTS, min_complete = 10) // queued first
thread B: io_uring_enter(GETEVENTS, min_complete = 1)
one CQE is posted: A isn't woken, and B isn't even considered
B keeps sleeping with the event it asked for sitting in the CQ ring, until
A's demand is met or a timeout or signal ends the wait.
Return 0 to carry on with the next waiter. Only waiters whose condition
is met are woken, like before.
[ 6.1: io_wake_function() lives in io_uring/io_uring.c ]
Fixes: bda521624e75 ("io_uring: make CQ ring wakeups be more efficient")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-20-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io_uring.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2368,7 +2368,8 @@ static int io_wake_function(struct wait_
*/
if (io_should_wake(iowq) || io_has_work(ctx))
return autoremove_wake_function(curr, mode, wake_flags, key);
- return -1;
+ /* keep going, a waiter further down may be content with less */
+ return 0;
}
int io_run_task_work_sig(struct io_ring_ctx *ctx)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0013/1887] io_uring/poll: drop stale double poll entry on rearm
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0012/1887] io_uring/wait: look at all CQ waiters on wake up Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0014/1887] io_uring/timeout: dont skip over reached sequences Greg Kroah-Hartman
` (985 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit f2dbe87968a3aef74a11c025776d293b80964d3f upstream.
A file that uses two wait queues for poll, e.g. a tty, gets a second
io_poll entry, which IORING_OP_POLL_ADD keeps in ->async_data until the
request is freed. io_poll_add() can run more than once for a request
though: IORING_OP_POLL_REMOVE with one of the update flags disarms and
rearms it, and io_poll_task_func() reissues it if a wake up turns out to
be spurious. The second poll_wait() of the new round then finds
*poll_ptr set, with ->head cleared by the disarm, and __io_queue_proc()
fails what it takes for a third wait queue with -EINVAL.
For an update that means that the poll request is completed with
-ECANCELED, while the update itself reports success. For a spurious wake
up, e.g. tcsetattr() on the polled tty, the poll request fails with
-EINVAL.
Free the old entry and clear the poll flags before arming, which is what
io_arm_apoll() does for internal polling. All entries have been removed
from their wait queues at that point.
[ 6.1: no io_req_async_data_free(), open-coded ]
Fixes: b69de288e913 ("io_uring: allow events and user_data update of running poll requests")
Fixes: 6e5aedb9324a ("io_uring/poll: attempt request issue after racy poll wakeup")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-21-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/poll.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -999,6 +999,18 @@ int io_poll_add(struct io_kiocb *req, un
if (req->ctx->flags & (IORING_SETUP_SQPOLL|IORING_SETUP_SINGLE_ISSUER))
req->flags |= REQ_F_HASH_LOCKED;
+ /*
+ * A poll update or a spurious wake up arms the request again. Forget
+ * the entries of the previous round like io_arm_apoll() does, a stale
+ * second entry would be taken for a third wait queue.
+ */
+ if (req_has_async_data(req)) {
+ kfree(req->async_data);
+ req->async_data = NULL;
+ req->flags &= ~REQ_F_ASYNC_DATA;
+ }
+ req->flags &= ~(REQ_F_SINGLE_POLL | REQ_F_DOUBLE_POLL);
+
ret = __io_arm_poll_handler(req, poll, &ipt, poll->events, issue_flags);
if (ret > 0) {
io_req_set_res(req, ipt.result_mask, 0);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0014/1887] io_uring/timeout: dont skip over reached sequences
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0013/1887] io_uring/poll: drop stale double poll entry on rearm Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0015/1887] io_uring/sqpoll: let the thread sleep on disabled rings Greg Kroah-Hartman
` (984 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit c6c0b3eba88c3b13ca11ea112404982e86d58f7a upstream.
io_flush_timeouts() copes with the wrap of the CQ sequence by looking at
the distance from ->cq_last_tm_flush. That relies on the target of each
pending timeout being at or ahead of the last flush.
io_timeout() breaks that. It sets ->cq_last_tm_flush to the current
sequence, on the assumption that nothing has been posted since the last
flush. That isn't true. A multishot request posts its CQEs right when it
is issued or retried, but they are committed, and the timeouts flushed,
at the end of the submission or task_work run:
X: IORING_OP_TIMEOUT, off == 1 target_seq == N + 1
io_submit_sqes()
multishot recv, posts two CQEs sequence == N + 2
Y: IORING_OP_TIMEOUT, off == 100 ->cq_last_tm_flush = N + 2
io_flush_timeouts()
X: events_needed = N + 1 - (N + 2) // 0xffffffff
events_got = 0 // not yet
X isn't completed although the completions it was waiting for have
happened, only its timer can end it now. And as the list is sorted and
the walk ends at the first timeout that isn't due, it gets in the way of
the ones behind it. The insertion sort has the same problem, it measures
the distance of the pending targets from the current sequence.
->cq_last_tm_flush only needs to be brought up to date if no timeout is
waiting for a sequence, as io_flush_timeouts() isn't called before the
first one is set up. Otherwise it is current enough. Timeouts with a
sequence come first in the list, so looking at the first entry will do.
Use the last flush as the base for the insertion sort as well.
Fixes: f010505b78a4 ("io_uring: flush timeouts that should already have expired")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-29-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/timeout.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -534,8 +534,9 @@ int io_timeout(struct io_kiocb *req, uns
struct io_timeout *timeout = io_kiocb_to_cmd(req, struct io_timeout);
struct io_ring_ctx *ctx = req->ctx;
struct io_timeout_data *data = req->async_data;
+ struct io_timeout *first;
struct list_head *entry;
- u32 tail, off = timeout->off;
+ u32 tail, base, off = timeout->off;
spin_lock_irq(&ctx->timeout_lock);
@@ -552,11 +553,17 @@ int io_timeout(struct io_kiocb *req, uns
tail = data_race(ctx->cached_cq_tail) - atomic_read(&ctx->cq_timeouts);
timeout->target_seq = tail + off;
- /* Update the last seq here in case io_flush_timeouts() hasn't.
- * This is safe because ->completion_lock is held, and submissions
- * and completions are never mixed in the same ->completion_lock section.
+ /*
+ * Update the last seq here in case io_flush_timeouts() hasn't, it only
+ * gets called once sequences are in use. Leave it alone if there are
+ * timeouts waiting for one. CQEs may have been posted since the last
+ * flush, and a target that has been reached must not fall behind it.
*/
- ctx->cq_last_tm_flush = tail;
+ first = list_first_entry_or_null(&ctx->timeout_list, struct io_timeout,
+ list);
+ if (!first || io_is_timeout_noseq(cmd_to_io_kiocb(first)))
+ ctx->cq_last_tm_flush = tail;
+ base = ctx->cq_last_tm_flush;
/*
* Insertion sort, ensuring the first entry in the list is always
@@ -568,8 +575,8 @@ int io_timeout(struct io_kiocb *req, uns
if (io_is_timeout_noseq(nxt))
continue;
- /* nxt.seq is behind @tail, otherwise would've been completed */
- if (off >= nextt->target_seq - tail)
+ /* no target is behind the last flush, see io_flush_timeouts() */
+ if (timeout->target_seq - base >= nextt->target_seq - base)
break;
}
add:
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0015/1887] io_uring/sqpoll: let the thread sleep on disabled rings
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0014/1887] io_uring/timeout: dont skip over reached sequences Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0016/1887] io_uring: dont pass restart error codes to userspace Greg Kroah-Hartman
` (983 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit d492dcbb3b81c1c2d0aabef41fa1307093f3a556 upstream.
__io_sq_thread() doesn't submit anything as long as the ring has
IORING_SETUP_R_DISABLED set. The check that keeps the SQPOLL thread from
going to sleep while the SQ ring holds entries doesn't know about that.
If an application fills in SQEs first and enables the ring later, the
thread finds that there is work each time it is about to sleep, goes
around, doesn't submit it, and so on. It uses up a CPU until the ring
gets enabled.
Entries in the SQ ring of a disabled ring are no reason to stay awake.
io_register_enable_rings() clears the flag and then wakes the thread, and
the flag is looked at after prepare_to_wait(), so the thread can't miss
that.
Fixes: 0298ef969a11 ("io_uring: clean R_DISABLED startup mess")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-37-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/sqpoll.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -293,6 +293,13 @@ static int io_sq_thread(void *data)
*/
smp_mb__after_atomic();
+ /*
+ * Nothing gets submitted before the ring is
+ * enabled, which comes with a wake up.
+ */
+ if (READ_ONCE(ctx->flags) & IORING_SETUP_R_DISABLED)
+ continue;
+
if (io_sqring_entries(ctx)) {
needs_sched = false;
break;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0016/1887] io_uring: dont pass restart error codes to userspace
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0015/1887] io_uring/sqpoll: let the thread sleep on disabled rings Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0017/1887] io_uring: look up the file before queueing to io-wq Greg Kroah-Hartman
` (982 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit e1a64bc64897f4c2fe460922c345f2ed8f889b5f upstream.
-ERESTARTSYS and friends are instructions for the system call exit code,
which either restarts the call or turns them into -EINTR. They are not
supposed to be seen by applications. A request isn't a system call,
nobody looks at what it returns before that is put into a CQE.
The read/write and the networking opcodes convert these codes to -EINTR
by hand. The others don't. An io-wq worker that is blocked in the open of
a FIFO, a tty or some other device, or in a splice from an empty pipe,
and that gets interrupted because the request is cancelled, completes it
with -512:
IORING_OP_OPENAT, IOSQE_ASYNC // FIFO without a writer
IORING_OP_ASYNC_CANCEL // -EALREADY, worker is signalled
CQE of the open: res == -512
There are more candidates, like whatever a file system or driver returns
from ->flush(), ->fsync(), ->fallocate() or ->uring_cmd(), or breaking a
lease or delegation.
Take care of it in io_issue_sqe(), which all of them go through. The
helper is moved from rw.c as is. The cost is a compare and a branch that
is not taken per request.
[ 6.1: io_issue_sqe() returns IOU_OK and an error straight away ]
Fixes: 15b71abe7b52 ("io_uring: add support for IORING_OP_OPENAT")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-39-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io_uring.c | 8 +++++++-
io_uring/io_uring.h | 18 ++++++++++++++++++
io_uring/rw.c | 18 ------------------
3 files changed, 25 insertions(+), 19 deletions(-)
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -1741,12 +1741,18 @@ static int io_issue_sqe(struct io_kiocb
}
if (ret == IOU_OK) {
+ /* not all handlers take care of the internal restart codes */
+ if (unlikely(req->cqe.res <= -ERESTARTSYS))
+ req->cqe.res = io_fixup_restart_res(req->cqe.res);
if (issue_flags & IO_URING_F_COMPLETE_DEFER)
io_req_complete_defer(req);
else
io_req_complete_post(req);
- } else if (ret != IOU_ISSUE_SKIP_COMPLETE)
+ } else if (ret != IOU_ISSUE_SKIP_COMPLETE) {
+ if (unlikely(ret <= -ERESTARTSYS))
+ ret = io_fixup_restart_res(ret);
return ret;
+ }
/* If the op doesn't have a file, we're not polling for it */
if ((req->ctx->flags & IORING_SETUP_IOPOLL) && def->iopoll_queue)
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -155,6 +155,24 @@ static inline bool __io_fill_cqe_req(str
return true;
}
+static inline ssize_t io_fixup_restart_res(ssize_t ret)
+{
+ switch (ret) {
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ case -ERESTARTNOHAND:
+ case -ERESTART_RESTARTBLOCK:
+ /*
+ * We can't just restart the syscall, since previously
+ * submitted sqes may already be in progress. Just fail
+ * this IO with EINTR.
+ */
+ return -EINTR;
+ default:
+ return ret;
+ }
+}
+
static inline void req_set_fail(struct io_kiocb *req)
{
req->flags |= REQ_F_FAIL;
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -129,24 +129,6 @@ void io_readv_writev_cleanup(struct io_k
kfree(io->free_iovec);
}
-static inline ssize_t io_fixup_restart_res(ssize_t ret)
-{
- switch (ret) {
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- case -ERESTARTNOHAND:
- case -ERESTART_RESTARTBLOCK:
- /*
- * We can't just restart the syscall, since previously
- * submitted sqes may already be in progress. Just fail
- * this IO with EINTR.
- */
- return -EINTR;
- default:
- return ret;
- }
-}
-
static inline void io_rw_done(struct kiocb *kiocb, ssize_t ret)
{
/* IO was queued async, completion will happen later */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0017/1887] io_uring: look up the file before queueing to io-wq
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0016/1887] io_uring: dont pass restart error codes to userspace Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0018/1887] io_uring/poll: avoid retry wakeup loss when dropping ownership Greg Kroah-Hartman
` (981 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jens Axboe,
Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
Commit 98bc044d5a5374f8d3605fe55a8e2df6d6fc3f82 upstream.
io_prep_async_work() decides by the file of a request what kind of work
it is for io-wq. I/O on regular files and block devices is bounded work,
limited to min(SQ entries, 4 * CPUs) workers, for anything else that may
block indefinitely the limit is RLIMIT_NPROC. Writes to a regular file
are hashed by the inode, so that they are run one after the other instead
of having a bunch of workers fight for the inode lock.
Since the file is only assigned when a request is issued, a request that
is queued without an attempt to issue it, REQ_F_FORCE_ASYNC, doesn't have
one at that point. io_prep_async_work() takes that for "not a regular
file or block device":
- Reads and writes end up as unbound work. 32 reads with IOSQE_ASYNC from
a slow block device on a ring with 4 SQ entries get 32 workers, not 4.
- Writes aren't hashed. Four buffered writes to one file get four
workers, three of which do nothing but wait for the lock.
The late assignment is for the benefit of links, where a request may use
a fixed file that one of its predecessors installs. By the time a request
gets to io_queue_iowq() these are done, it is as good as issued. Assign
the file there.
io_assign_file() moves up and is forced inline. With a third caller the
compiler may stop inlining it, and every request that is issued would
pay for a call.
IORING_OP_SPLICE is left as it is, unbound and not hashed. The file of
the request is where it writes to, which says nothing about how long it
takes: a splice from an empty pipe or a socket into a regular file waits
for its input. As bounded work, four of these on a ring with 4 SQ entries
keep all other bounded work of the task from running, and as hashed work
one of them blocks all writes to that file.
REQ_F_FORCE_ASYNC is not only set for IOSQE_ASYNC. What changes, and
brings back what was the case before the file assignment was deferred:
- Requests with IOSQE_ASYNC or IOSQE_IO_DRAIN, and all requests that are
submitted while a drain is active: reads and writes on regular files
and block devices count against the limit for bounded workers, including
the one set with IORING_REGISTER_IOWQ_MAX_WORKERS, so fewer of them run
at the same time.
- Of these, writes to one regular file are run one at a time, unless they
are O_DIRECT and the filesystem has FOP_DIO_PARALLEL_WRITE.
- IORING_OP_FALLOCATE and IORING_OP_FTRUNCATE, which always go to io-wq,
are run one at a time per file, and in turn with these writes.
- The descriptor or the fixed file slot is looked up when the request is
queued, not when a worker gets around to it, so closing or replacing it
in between no longer has an effect on the request.
[ 6.1: io_assign_file() takes no def argument here ]
Fixes: 6bf9c47a3989 ("io_uring: defer file assignment")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261015-b4-io-uring-fixes-v1-43-c1556f5d7bf5@toxicpanda.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io_uring.c | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -417,17 +417,45 @@ static void io_prep_async_link(struct io
}
}
+/* Called for every request that is issued: keep it inline */
+static __always_inline bool io_assign_file(struct io_kiocb *req,
+ unsigned int issue_flags)
+{
+ if (req->file || !io_op_defs[req->opcode].needs_file)
+ return true;
+
+ if (req->flags & REQ_F_FIXED_FILE)
+ req->file = io_file_get_fixed(req, req->cqe.fd, issue_flags);
+ else
+ req->file = io_file_get_normal(req, req->cqe.fd);
+
+ return !!req->file;
+}
+
static void io_queue_iowq(struct io_kiocb *req)
{
struct io_uring_task *tctx = req->task->io_uring;
BUG_ON(!tctx);
+ lockdep_assert_held(&req->ctx->uring_lock);
if ((current->flags & PF_KTHREAD) || !tctx->io_wq) {
io_req_task_queue_fail(req, -ECANCELED);
return;
}
+ /*
+ * The file is looked up as late as possible, as it may be the result
+ * of an earlier request of the link. This one is up now, and what kind
+ * of work it is depends on the file. If that fails, leave the error
+ * handling to the worker.
+ *
+ * Not for a splice: whatever it writes to, it may wait for its input
+ * for ever. It has to remain unbound work that isn't hashed.
+ */
+ if (req->opcode != IORING_OP_SPLICE)
+ io_assign_file(req, 0);
+
/* init ->work of the whole link before punting */
io_prep_async_link(req);
@@ -1693,19 +1721,6 @@ static void io_clean_op(struct io_kiocb
req->flags &= ~IO_REQ_CLEAN_FLAGS;
}
-static bool io_assign_file(struct io_kiocb *req, unsigned int issue_flags)
-{
- if (req->file || !io_op_defs[req->opcode].needs_file)
- return true;
-
- if (req->flags & REQ_F_FIXED_FILE)
- req->file = io_file_get_fixed(req, req->cqe.fd, issue_flags);
- else
- req->file = io_file_get_normal(req, req->cqe.fd);
-
- return !!req->file;
-}
-
#define REQ_ISSUE_SLOW_FLAGS (REQ_F_CREDS | REQ_F_ARM_LTIMEOUT)
static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0018/1887] io_uring/poll: avoid retry wakeup loss when dropping ownership
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0017/1887] io_uring: look up the file before queueing to io-wq Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0019/1887] io_uring/timeout: dont put a sequence target behind the last flush Greg Kroah-Hartman
` (980 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Juanlu Herrero, Anand Natarajan,
Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juanlu Herrero <juanlu@fastmail.com>
Commit 937d38dcacd675dc0572d6c9b6743960df3128ed upstream.
If a wakeup sets IO_POLL_RETRY_FLAG between the owning task consuming
the existing instance of IO_POLL_RETRY_FLAG and the loop check
of io_poll_check_events(), then we stall on processing the request
until an unrelated wakeup comes along.
Using atomic_cmpxchg instead of atomic_sub_return to guarantee both the
count v and poll_refs are 0 and no wake-ups are missed.
Cc: stable@vger.kernel.org
Fixes: a26a35e9019f ("io_uring: make poll refs more robust")
Signed-off-by: Juanlu Herrero <juanlu@fastmail.com>
Assisted-by: LLM
Suggested-by: Anand Natarajan <anand@meta.com>
Link: https://patch.msgid.link/20261013-pu-cmpxchg-v1-1-4ddc10fd8a03@fastmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/poll.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -325,8 +325,8 @@ static int io_poll_check_events(struct i
* Release all references, retry if someone tried to restart
* task_work while we were executing it.
*/
- } while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs) &
- IO_POLL_REF_MASK);
+ v &= IO_POLL_REF_MASK;
+ } while (atomic_cmpxchg(&req->poll_refs, v, 0) != v);
return IOU_POLL_NO_ACTION;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0019/1887] io_uring/timeout: dont put a sequence target behind the last flush
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0018/1887] io_uring/poll: avoid retry wakeup loss when dropping ownership Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0020/1887] io_uring/timeout: dont flush with the sequence " Greg Kroah-Hartman
` (979 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit fdfce905a58edea053ee7b68b5bd4348dd1b36e0 upstream.
io_timeout_fn() and io_kill_timeout() bump ->cq_timeouts when a timeout
fires, but its CQE is only posted later from task_work. Until then the
sequence io_timeout() computes is one below the last flush per fired
timeout. Now that ->cq_last_tm_flush is kept while sequence timeouts are
pending, a timeout armed in that window with a small offset gets a target
behind the base. Its distance from the base wraps, and it's never
completed by events, only by its timer. With DEFER_TASKRUN that window
is as wide as the application makes it, as submission runs before the
local task_work.
Nothing but those in flight CQEs separates the two, so use the last
flush as the base for the target when the sequence is behind it.
Fixes: c6c0b3eba88c ("io_uring/timeout: don't skip over reached sequences")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/timeout.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -551,7 +551,6 @@ int io_timeout(struct io_kiocb *req, uns
}
tail = data_race(ctx->cached_cq_tail) - atomic_read(&ctx->cq_timeouts);
- timeout->target_seq = tail + off;
/*
* Update the last seq here in case io_flush_timeouts() hasn't, it only
@@ -566,6 +565,15 @@ int io_timeout(struct io_kiocb *req, uns
base = ctx->cq_last_tm_flush;
/*
+ * A fired timeout bumps ->cq_timeouts before its CQE is posted, which
+ * leaves the sequence behind the last flush until it is. Nothing else
+ * separates the two then, so count from the flush.
+ */
+ if ((s32)(tail - base) < 0)
+ tail = base;
+ timeout->target_seq = tail + off;
+
+ /*
* Insertion sort, ensuring the first entry in the list is always
* the one we need first.
*/
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0020/1887] io_uring/timeout: dont flush with the sequence behind the last flush
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0019/1887] io_uring/timeout: dont put a sequence target behind the last flush Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0021/1887] io_uring/timeout: dont lose a cancel as io-wq arms a timeout Greg Kroah-Hartman
` (978 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jens Axboe
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit 85f85d573ffa7772e1ad4504d0cec5113a5c5cf1 upstream.
io_flush_timeouts() measures the events since the last flush as the
distance of the current sequence from ->cq_last_tm_flush. A fired
timeout bumps ->cq_timeouts before its CQE is posted, so until it is
the sequence can be behind the last flush, and the distance wraps:
last flush: seq 100, cq_last_tm_flush = 100
Y: IORING_OP_TIMEOUT, off 50, target_seq 150
pure timeout A fires, cq_timeouts = 1
task_work posts A's CQE, cached_cq_tail = 101
pure timeout B fires before the flush, cq_timeouts = 2
io_flush_timeouts(): seq = 99, events_got = 0xffffffff
Y, and every sequence timeout behind it, is ended with -ETIME although
no event happened. Two timeouts expiring close together is all it takes,
a completion with IOSQE_CQE_SKIP_SUCCESS after a single one does it too.
Nothing but those in flight CQEs separates the two, so count from the
last flush when the sequence is behind it, as io_timeout() does.
Fixes: f010505b78a4 ("io_uring: flush timeouts that should already have expired")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/timeout.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -78,6 +78,14 @@ __cold void io_flush_timeouts(struct io_
spin_lock_irq(&ctx->timeout_lock);
seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
+ /*
+ * A fired timeout bumps ->cq_timeouts before its CQE is posted, which
+ * leaves the sequence behind the last flush until it is. No event has
+ * happened then, see io_timeout().
+ */
+ if ((s32)(seq - ctx->cq_last_tm_flush) < 0)
+ seq = ctx->cq_last_tm_flush;
+
list_for_each_entry_safe(timeout, tmp, &ctx->timeout_list, list) {
struct io_kiocb *req = cmd_to_io_kiocb(timeout);
u32 events_needed, events_got;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0021/1887] io_uring/timeout: dont lose a cancel as io-wq arms a timeout
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0020/1887] io_uring/timeout: dont flush with the sequence " Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0022/1887] io_uring/poll: dont loop on HUP with multiple references Greg Kroah-Hartman
` (977 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jens Axboe, Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit 89f193dc3ef462059387e9691bf6af4b1808379a upstream.
An IORING_OP_TIMEOUT run by io-wq, because of IOSQE_ASYNC, has the same
problem as poll, futex and waitid. io_wq_submit_work() looks at
IO_WQ_WORK_CANCEL once, before it issues the request. A cancel in between
flags the work, gets -EALREADY, and searches ->timeout_list in vain,
while the worker then adds the request and starts the timer:
io-wq worker io_try_cancel()
io_wq_submit_work()
IO_WQ_WORK_CANCEL isn't set
io_async_cancel_one()
sets IO_WQ_WORK_CANCEL
= -EALREADY
io_timeout_cancel() = -ENOENT
io_timeout()
adds the request to ->timeout_list
hrtimer_start()
= IOU_ISSUE_SKIP_COMPLETE
Nobody looks at the flag again, and the timeout runs its course. At ring
exit, io_uring_try_cancel_requests() cancels io-wq work and then kills
the timeouts the same way, so an exiting task can get stuck for the full
duration of such a timeout.
Look at the flag under ->timeout_lock, which the search takes as well,
and fail the request if it is set. If the search came first, the flag is
visible. If it comes later, it finds the request on the list.
[ 6.1: adds IO_URING_F_IOWQ, which io_wq_submit_work() didn't pass yet,
and the __io_wq_cancel_seen()/io_wq_cancel_seen() helpers that the
futex/waitid fix 5cb049d2203d brought upstream; work->flags is not
atomic and ->timeout_lock isn't raw here ]
Fixes: ce35a47a3a02 ("io_uring: add IOSQE_ASYNC")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/io_uring.h | 2 ++
io_uring/io_uring.c | 2 +-
io_uring/io_uring.h | 23 +++++++++++++++++++++++
io_uring/timeout.c | 7 +++++++
4 files changed, 33 insertions(+), 1 deletion(-)
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -19,6 +19,8 @@ enum io_uring_cmd_flags {
/* the request is executed from poll, it should not be freed */
IO_URING_F_MULTISHOT = 32,
+ /* executed by io-wq */
+ IO_URING_F_IOWQ = 64,
};
struct io_uring_cmd {
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -1816,7 +1816,7 @@ void io_wq_submit_work(struct io_wq_work
{
struct io_kiocb *req = container_of(work, struct io_kiocb, work);
const struct io_op_def *def = &io_op_defs[req->opcode];
- unsigned int issue_flags = IO_URING_F_UNLOCKED;
+ unsigned int issue_flags = IO_URING_F_UNLOCKED | IO_URING_F_IOWQ;
bool needs_poll = false;
int ret = 0, err = -ECANCELED;
--- a/io_uring/io_uring.h
+++ b/io_uring/io_uring.h
@@ -221,6 +221,29 @@ static inline void io_ring_submit_lock(s
lockdep_assert_held(&ctx->uring_lock);
}
+/*
+ * For a handler that is run by io-wq and parks the request on a list where
+ * cancellations find it, rather than completing it. Whoever tried to cancel
+ * the request before that found it running. It has flagged the work item,
+ * has searched the list in vain, and won't come back. To be called with
+ * the lock the search takes held: if the search came first, the flag is
+ * visible. For most lists that is ->uring_lock, timeouts use ->timeout_lock.
+ */
+static inline bool __io_wq_cancel_seen(struct io_kiocb *req,
+ unsigned int issue_flags)
+{
+ return (issue_flags & IO_URING_F_IOWQ) &&
+ (req->work.flags & IO_WQ_WORK_CANCEL);
+}
+
+static inline bool io_wq_cancel_seen(struct io_kiocb *req,
+ unsigned int issue_flags)
+{
+ lockdep_assert_held(&req->ctx->uring_lock);
+
+ return __io_wq_cancel_seen(req, issue_flags);
+}
+
static inline void io_commit_cqring(struct io_ring_ctx *ctx)
{
/* order cqe stores with ring update */
--- a/io_uring/timeout.c
+++ b/io_uring/timeout.c
@@ -548,6 +548,13 @@ int io_timeout(struct io_kiocb *req, uns
spin_lock_irq(&ctx->timeout_lock);
+ /* the list is searched under ->timeout_lock, see io_wq_cancel_seen() */
+ if (__io_wq_cancel_seen(req, issue_flags)) {
+ spin_unlock_irq(&ctx->timeout_lock);
+ io_req_task_queue_fail(req, -ECANCELED);
+ return IOU_ISSUE_SKIP_COMPLETE;
+ }
+
/*
* sqe->off holds how many events that need to occur for this
* timeout event to be satisfied. If it isn't set, then this is
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0022/1887] io_uring/poll: dont loop on HUP with multiple references
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0021/1887] io_uring/timeout: dont lose a cancel as io-wq arms a timeout Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0023/1887] mips: unhide uasm_in_compat_space_p() declaration Greg Kroah-Hartman
` (976 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jens Axboe, Claude Fable 5.1
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit cf1d5c9d335e2c673811da641531da82cb01393a upstream.
io_poll_check_events() drops down to one reference when a multishot
request sees HUP with more than one, so that the loop goes around once
more. It did so by subtracting one less than it had. With the cmpxchg
that only takes the local count down: the exchange fails, the next pass
reads the unchanged count, and goes through the same motions again. The
loop then only ends once io_poll_issue() stops the request.
Drop the extra references from the counter instead, and loop once more
without trying the exchange. The next pass sees one reference, like it
did before, and ends unless a wake up came in.
[ 6.1: v still carries the flag bits here, mask it for the subtraction ]
Fixes: 937d38dcacd6 ("io_uring/poll: avoid retry wakeup loss when dropping ownership")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/poll.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -239,12 +239,14 @@ enum {
static int io_poll_check_events(struct io_kiocb *req, bool *locked)
{
struct io_ring_ctx *ctx = req->ctx;
+ bool again;
int v;
if (unlikely(io_should_terminate_tw(ctx)))
return -ECANCELED;
do {
+ again = false;
v = atomic_read(&req->poll_refs);
/* tw handler should be the owner, and so have some references */
@@ -305,10 +307,17 @@ static int io_poll_check_events(struct i
} else {
int ret;
- /* multiple refs and HUP, ensure we loop once more */
+ /*
+ * Multiple refs and HUP, ensure we loop once more. Drop
+ * down to one ref now, so the next pass ends unless a
+ * wake up came in.
+ */
if ((req->cqe.res & (POLLHUP | POLLRDHUP)) &&
- (v & IO_POLL_REF_MASK) != 1)
- v--;
+ (v & IO_POLL_REF_MASK) != 1) {
+ atomic_sub((v & IO_POLL_REF_MASK) - 1,
+ &req->poll_refs);
+ again = true;
+ }
ret = io_poll_issue(req, locked);
io_kbuf_recycle(req, 0);
@@ -326,7 +335,7 @@ static int io_poll_check_events(struct i
* task_work while we were executing it.
*/
v &= IO_POLL_REF_MASK;
- } while (atomic_cmpxchg(&req->poll_refs, v, 0) != v);
+ } while (again || atomic_cmpxchg(&req->poll_refs, v, 0) != v);
return IOU_POLL_NO_ACTION;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0023/1887] mips: unhide uasm_in_compat_space_p() declaration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0022/1887] io_uring/poll: dont loop on HUP with multiple references Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0024/1887] apparmor: fix out-of-bounds write when null terminating a label vec Greg Kroah-Hartman
` (975 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arnd Bergmann, Stephen Rothwell,
Thomas Bogendoerfer, Andrew Morton
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <arnd@arndb.de>
commit e9f98feb17207addcd66435d8211ccf9c0a563dd upstream.
uasm_in_compat_space_p() has a conditional declaration but is defined
unconditionally because of another local user, which causes a warning:
arch/mips/mm/uasm.c:421:5: error: no previous prototype for 'uasm_in_compat_space_p' [-Werror=missing-prototypes]
Make the declaration unconditional to avoid this.
Link: https://lkml.kernel.org/r/20231204115710.2247097-10-arnd@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Stephen Rothwell <sfr@rothwell.id.au>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/include/asm/uasm.h | 2 --
1 file changed, 2 deletions(-)
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -193,9 +193,7 @@ struct uasm_label {
void uasm_build_label(struct uasm_label **lab, u32 *addr,
int lid);
-#ifdef CONFIG_64BIT
int uasm_in_compat_space_p(long addr);
-#endif
int uasm_rel_hi(long val);
int uasm_rel_lo(long val);
void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0024/1887] apparmor: fix out-of-bounds write when null terminating a label vec
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0023/1887] mips: unhide uasm_in_compat_space_p() declaration Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0025/1887] nfsd: fix nfsd_file leak on inter-server COPY setup failure Greg Kroah-Hartman
` (974 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, John Johansen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <imv4bel@gmail.com>
[ Upstream commit 9f1e40193eef7f047e6b77cfb4b4cafdecd7a123 ]
aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE
is passed. If the components are all distinct no duplicates are dropped,
dups is 0 and the terminator goes to vec[n], so the caller has to provide
room for n + 1 entries.
aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len,
gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but
vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES
it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it
allocates exactly len pointers. The terminator therefore lands one entry
past the end of the local array when len is LOCAL_VEC_ENTRIES, and one
entry past the end of the allocation when len is larger.
len comes from the number of "//&" separated components in the label name
and label_count_strn_entries() does not bound it. An unprivileged task
reaches the parse by writing to /proc/self/attr/apparmor/current or through
lsm_set_self_attr(2), both of which go through do_setattr(), and the name
is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is
mode 0666, performs no permission check at all. Every component has to
resolve to a loaded profile, so a system with policy loaded is required.
The other two VEC_FLAG_TERMINATE users work on a label vec that
aa_label_alloc() has already sized with "+ 1 for null terminator entry on
vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing
len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of
the local array and into kzalloc().
Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
[ replaced unavailable kzalloc_objs() with equivalent kcalloc() allocation ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/apparmor/include/label.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 9887bfbab0f3d..43565faae2ba5 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -22,7 +22,7 @@ struct aa_ns;
#define LOCAL_VEC_ENTRIES 8
#define DEFINE_VEC(T, V) \
- struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES]; \
+ struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES + 1]; \
struct aa_ ## T **(V)
#define vec_setup(T, V, N, GFP) \
@@ -30,10 +30,10 @@ struct aa_ns;
if ((N) <= LOCAL_VEC_ENTRIES) { \
typeof(N) i; \
(V) = (_ ## V ## _localtmp); \
- for (i = 0; i < (N); i++) \
+ for (i = 0; i <= (N); i++) \
(V)[i] = NULL; \
} else \
- (V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP)); \
+ (V) = kcalloc((N) + 1, sizeof(struct aa_ ## T *), (GFP)); \
(V) ? 0 : -ENOMEM; \
})
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0025/1887] nfsd: fix nfsd_file leak on inter-server COPY setup failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0024/1887] apparmor: fix out-of-bounds write when null terminating a label vec Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0026/1887] ceph: bound copied dentry name length in NFS export get_name Greg Kroah-Hartman
` (973 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 88a76145451d703eedd867b5989bf73d17340399 ]
When nfsd4_setup_inter_ssc() fails, nfsd4_copy() returns
nfserr_offload_denied directly, bypassing the out: label where
release_copy_files() would drop the nf_dst reference taken by
nfs4_preprocess_stateid_op(). Each failed inter-server COPY
leaks one nfsd_file, pinning file/inode/dentry/vfsmount.
Fix by setting status and jumping to out: instead of returning
directly.
Fixes: ce0887ac96d3 ("NFSD add nfs4 inter ssc to nfsd4_copy")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-3-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[ adjusted cleanup paths to omit unavailable trace_nfsd_copy_*() calls ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4proc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 20c3869a9ab91..7486c470fe6f1 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1777,12 +1777,14 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
}
status = nfsd4_setup_inter_ssc(rqstp, cstate, copy);
- if (status)
- return nfserr_offload_denied;
+ if (status) {
+ status = nfserr_offload_denied;
+ goto out;
+ }
} else {
status = nfsd4_setup_intra_ssc(rqstp, cstate, copy);
if (status)
- return status;
+ goto out;
}
memcpy(©->fh, &cstate->current_fh.fh_handle,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0026/1887] ceph: bound copied dentry name length in NFS export get_name
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0025/1887] nfsd: fix nfsd_file leak on inter-server COPY setup failure Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0027/1887] smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2() Greg Kroah-Hartman
` (972 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito,
Viacheslav Dubeyko, Ilya Dryomov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit eff8013c5a8916613c742ae5a2cc341cb605c0ae ]
ceph_get_name() copies the MDS-supplied name into the caller's
NAME_MAX-sized buffer with memcpy(name, rinfo->dname, rinfo->dname_len)
and then writes name[rinfo->dname_len] = 0, without checking dname_len
against NAME_MAX. A malicious or buggy MDS that returns a LOOKUPNAME reply
with dname_len > NAME_MAX overflows the buffer. __get_snap_name() copies
rde->name / rde->name_len the same unchecked way.
Impact: a malicious or compromised Ceph MDS overflows the NAME_MAX name
buffer in a client's NFS-export get_name path, a slab out-of-bounds write
reported by KASAN. Reachable when a CephFS mount is re-exported over NFS.
Add ceph_export_copy_name(), which rejects lengths above NAME_MAX with
-ENAMETOOLONG before the copy, and use it in both ceph_get_name() and
__get_snap_name().
Cc: stable@vger.kernel.org
Fixes: 19913b4eac4a ("ceph: add get_name() NFS export callback")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
[ adapted the bounds check to the older ceph_get_name() flow without encrypted-name handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/export.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 23b945320c554..c2d3ca5417e9c 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -433,6 +433,16 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb,
return dentry;
}
+static int ceph_export_copy_name(char *name, const char *src, u32 len)
+{
+ if (len > NAME_MAX)
+ return -ENAMETOOLONG;
+
+ memcpy(name, src, len);
+ name[len] = '\0';
+ return 0;
+}
+
static int __get_snap_name(struct dentry *parent, char *name,
struct dentry *child)
{
@@ -498,9 +508,8 @@ static int __get_snap_name(struct dentry *parent, char *name,
BUG_ON(!rde->inode.in);
if (ceph_snap(inode) ==
le64_to_cpu(rde->inode.in->snapid)) {
- memcpy(name, rde->name, rde->name_len);
- name[rde->name_len] = '\0';
- err = 0;
+ err = ceph_export_copy_name(name, rde->name,
+ rde->name_len);
goto out;
}
}
@@ -562,8 +571,12 @@ static int ceph_get_name(struct dentry *parent, char *name,
if (!err) {
struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
- memcpy(name, rinfo->dname, rinfo->dname_len);
- name[rinfo->dname_len] = 0;
+
+ err = ceph_export_copy_name(name, rinfo->dname,
+ rinfo->dname_len);
+ }
+
+ if (!err) {
dout("get_name %p ino %llx.%llx name %s\n",
child, ceph_vinop(inode), name);
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0027/1887] smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0026/1887] ceph: bound copied dentry name length in NFS export get_name Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0028/1887] HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind Greg Kroah-Hartman
` (971 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shen Yongchao, Frank Sorenson,
Namjae Jeon, Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
[ Upstream commit 6343c1da561962688f203362d80d6a3bfa39fa1b ]
coalesce_t2() computes data pointers directly from server-supplied
DataOffset fields with no validation against buffer bounds:
data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
data_area_of_src = (char *)&pSMBs->hdr.Protocol +
get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
data_area_of_tgt += total_in_tgt;
...
memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
A small DataOffset can push a pointer below the actual byte area,
overwriting header fields; a large one can push it past the buffer
end, causing out-of-bounds heap reads (source) or writes (target).
The BCC overflow guard does not prevent this: BCC reflects how much
data is present, while DataOffset controls where in the buffer it
starts.
The "validate target area" comment present since the function was
first written in 2005 was a placeholder that was never implemented.
Add lower- and upper-bound checks for both data pointers before the
memcpy, and before any target header fields are modified.
Fixes: e4eb295d38b5 ("[PATCH] cifs: Handle multiple response transact2 part 1 of 2")
Cc: stable@vger.kernel.org
Reported-by: Shen Yongchao <grayhat@foxmail.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ transplanted the bounds validation to coalesce_t2() in smb1ops.c due to code relocation ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb1ops.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 1489b9d21b609..5c570cd238845 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -325,12 +325,31 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
- /* validate target area */
data_area_of_src = (char *)&pSMBs->hdr.Protocol +
get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
data_area_of_tgt += total_in_tgt;
+ /*
+ * DataOffset fields are server-supplied and not validated against
+ * buffer bounds; check both data pointers before mutating the
+ * target header.
+ */
+ if (data_area_of_tgt < (char *)target_hdr +
+ sizeof(struct smb_t2_rsp) + sizeof(__le16) ||
+ data_area_of_tgt + total_in_src >
+ (char *)target_hdr + CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
+ cifs_dbg(VFS, "%s: target data area out of bounds\n", __func__);
+ return -EPROTO;
+ }
+ if (data_area_of_src < second_buf +
+ sizeof(struct smb_t2_rsp) + sizeof(__le16) ||
+ data_area_of_src + total_in_src >
+ second_buf + smbCalcSize((struct smb_hdr *)second_buf)) {
+ cifs_dbg(VFS, "%s: secondary data area out of bounds\n", __func__);
+ return -EPROTO;
+ }
+
total_in_tgt += total_in_src;
/* is the result too big for the field? */
if (total_in_tgt > USHRT_MAX) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0028/1887] HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0027/1887] smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0029/1887] nouveau/gem: reserve the bo in the info ioctl around the vma lookup Greg Kroah-Hartman
` (970 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Jiri Kosina,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
[ Upstream commit a26705bd2e2728833e7a538ce91e58a5eeff496a ]
For GHL (Guitar Hero Live) dongles, sony_probe() arms a periodic timer:
ghl_magic_poke() (the timer callback) submits sc->ghl_urb, and the URB
completion ghl_magic_poke_cb() re-arms the timer with mod_timer().
sony_remove() drained the timer with timer_delete_sync() and then freed
the URB with usb_free_urb():
timer_delete_sync(&sc->ghl_poke_timer);
usb_free_urb(sc->ghl_urb);
timer_delete_sync() does not block re-arming, and while the URB is in
flight the timer is not pending, so the sync delete is a no-op. A URB
completion that runs after the delete re-arms the timer, and usb_free_urb()
only drops a reference -- it does not kill an in-flight URB. sc is
allocated with devm_kzalloc() and freed once sony_remove() returns, so the
re-armed ghl_poke_timer (embedded in sc) then fires on freed memory, a
use-after-free from timer softirq. This is a disconnect/rmmod race.
Poison the URB first, then shut the timer down, before freeing the URB.
usb_poison_urb() kills any in-flight URB and permanently rejects further
submissions, so a poke timer that is still pending cannot re-submit the
URB from ghl_magic_poke() in the window before timer_shutdown_sync() runs.
usb_kill_urb() would not suffice: it only cancels the in-flight URB and
leaves it submittable once it returns, so the pending timer could
re-submit it and put a fresh URB in flight over the freed sc.
timer_shutdown_sync() then drains any last callback and blocks re-arming.
The probe error path is unaffected: it is only reached before the timer
is armed.
Reproduced under KASAN on next-20260710 via dummy_hcd + raw-gadget
emulation of the GHL PS4 dongle (VID 0x1430 / PID 0x07bb): hid-sony binds
and arms the poke timer, the poke URB is held in flight, the driver is
unbound (freeing sc), then the URB is released. The completion re-arms the
timer on the freed sc, and the re-armed timer fires ~8 s later:
BUG: KASAN: slab-use-after-free in ghl_magic_poke+0x98/0xb0
Read of size 8 at addr ffff88810b02fd50 by task swapper/0/0
ghl_magic_poke+0x98/0xb0
call_timer_fn+0x35/0x2b0
__run_timers+0x69c/0x9a0
run_timer_softirq+0x173/0x2a0
Allocated by task 169: sony_probe
Freed by task 338: devres_release_group <- hid_device_remove (sony_remove)
Found by 0sec (https://0sec.ai) using automated source analysis.
Fixes: cc894ac55360 ("HID: sony: support for ghlive ps3/wii u dongles")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[ changed the old del_timer_sync() call to timer_shutdown_sync() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-sony.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f7f7252d839ee..01745b5df2e4e 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -3085,7 +3085,9 @@ static void sony_remove(struct hid_device *hdev)
struct sony_sc *sc = hid_get_drvdata(hdev);
if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) {
- del_timer_sync(&sc->ghl_poke_timer);
+ /* poison, not kill: a pending timer must not re-submit during teardown */
+ usb_poison_urb(sc->ghl_urb);
+ timer_shutdown_sync(&sc->ghl_poke_timer);
usb_free_urb(sc->ghl_urb);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0029/1887] nouveau/gem: reserve the bo in the info ioctl around the vma lookup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0028/1887] HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0030/1887] ocfs2: validate dx_root extent list fields during block read Greg Kroah-Hartman
` (969 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Airlie, Danilo Krummrich,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <airlied@redhat.com>
[ Upstream commit 5e17160d41d92823f3379c1982e1369680c5ce4d ]
In the non-uvmm path, there could be a race between the info lookup
finding the vma, and the gem close path closing the vma leading
to a use-after-free.
Spotted with the help of Opus 4.6.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Fixes: e758a3111914 ("drm/nouveau: fixup gem_info ioctl to return client-specific bo virtual")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260612020658.3176270-1-airlied@gmail.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
[ adapted VMM and UVMM handling to the legacy direct VMM selection and condition. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/nouveau/nouveau_gem.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index cde21cc0083b1..4c9942f651b6f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -277,11 +277,20 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
rep->offset = nvbo->offset;
if (vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
+ int ret;
+
+ ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
+ if (ret)
+ return ret;
+
vma = nouveau_vma_find(nvbo, vmm);
- if (!vma)
+ if (!vma) {
+ ttm_bo_unreserve(&nvbo->bo);
return -EINVAL;
+ }
rep->offset = vma->addr;
+ ttm_bo_unreserve(&nvbo->bo);
}
rep->size = nvbo->bo.base.size;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0030/1887] ocfs2: validate dx_root extent list fields during block read
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0029/1887] nouveau/gem: reserve the bo in the info ioctl around the vma lookup Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0031/1887] ocfs2: validate directory-index entry counts when reading metadata Greg Kroah-Hartman
` (968 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Heming Zhao, Mark Fasheh,
Joel Becker, Junxiao Bi, Changwei Ge, Jun Piao, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit 775c17386a6fd695f999d4cda90e3931386570dd ]
Patch series "ocfs2: consolidate extent list validation into block read
callbacks".
ocfs2 validates extent list fields (l_count, l_next_free_rec) at various
points during extent tree traversal. This is fragile because each caller
must remember to check for corrupted on-disk data before using it.
This series moves those checks into the block read validation callbacks
(ocfs2_validate_dx_root and ocfs2_validate_extent_block), so corrupted
fields are caught early at block read time. Redundant post-read checks
are then removed.
This patch (of 4):
Move the extent list l_count validation from ocfs2_dx_dir_lookup_rec()
into ocfs2_validate_dx_root(), so that corrupted on-disk fields are caught
early at block read time rather than during directory lookups.
Additionally, add a l_next_free_rec <= l_count check to prevent
out-of-bounds access when iterating over extent records.
Both checks are skipped for inline dx roots (OCFS2_DX_FLAG_INLINE), which
use dr_entries instead of dr_list.
Link: https://lkml.kernel.org/r/20260403090803.3860971-1-joseph.qi@linux.alibaba.com
Link: https://lkml.kernel.org/r/20260403090803.3860971-2-joseph.qi@linux.alibaba.com
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: bc70726ddad5 ("ocfs2: validate directory-index entry counts when reading metadata")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/dir.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index c85ad5999e848..b758f11738c65 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -580,7 +580,7 @@ static int ocfs2_validate_dx_root(struct super_block *sb,
mlog(ML_ERROR,
"Checksum failed for dir index root block %llu\n",
(unsigned long long)bh->b_blocknr);
- return ret;
+ goto bail;
}
if (!OCFS2_IS_VALID_DX_ROOT(dx_root)) {
@@ -588,8 +588,32 @@ static int ocfs2_validate_dx_root(struct super_block *sb,
"Dir Index Root # %llu has bad signature %.*s\n",
(unsigned long long)le64_to_cpu(dx_root->dr_blkno),
7, dx_root->dr_signature);
+ goto bail;
+ }
+
+ if (!(dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)) {
+ struct ocfs2_extent_list *el = &dx_root->dr_list;
+
+ if (le16_to_cpu(el->l_count) != ocfs2_extent_recs_per_dx_root(sb)) {
+ ret = ocfs2_error(sb,
+ "Dir Index Root # %llu has invalid l_count %u (expected %u)\n",
+ (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+ le16_to_cpu(el->l_count),
+ ocfs2_extent_recs_per_dx_root(sb));
+ goto bail;
+ }
+
+ if (le16_to_cpu(el->l_next_free_rec) > le16_to_cpu(el->l_count)) {
+ ret = ocfs2_error(sb,
+ "Dir Index Root # %llu has invalid l_next_free_rec %u (l_count %u)\n",
+ (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+ le16_to_cpu(el->l_next_free_rec),
+ le16_to_cpu(el->l_count));
+ goto bail;
+ }
}
+bail:
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0031/1887] ocfs2: validate directory-index entry counts when reading metadata
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0030/1887] ocfs2: validate dx_root extent list fields during block read Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0032/1887] wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop Greg Kroah-Hartman
` (967 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Joseph Qi,
Joel Becker, Kees Cook, Mark Fasheh, Junxiao Bi, Changwei Ge,
Jun Piao, Heming Zhao, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
[ Upstream commit bc70726ddad53c7e9a9a85915bf2415b0d4f42f9 ]
ocfs2_validate_dx_leaf() and ocfs2_validate_dx_root() check the ECC and
signature of an indexed-directory block before it reaches higher-level
callers, but neither validator bounds the ocfs2_dx_entry_list counts
against the capacity of the block that holds them.
ocfs2_dx_dir_search() then walks
for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++)
dx_entry = &entry_list->de_entries[i];
over de_num_used entries with no bounds check. entry_list is either
dx_leaf->dl_list (from ocfs2_read_dx_leaf) or, for an inline root,
dx_root->dr_entries. A crafted on-disk image can set de_num_used (and
de_count, which is the __counted_by_le() bound of de_entries) to 0xffff
and make the walk read far past the end of the 4KB metadata block, giving
a slab out-of-bounds read reachable from any path lookup, stat() or open()
on an indexed directory once the image is mounted.
Commit 775c17386a6f ("ocfs2: validate dx_root extent list fields during
block read") already bounds dr_list for the non-inline dx_root, but left
the inline dr_entries path and the dx_leaf dl_list unchecked. Add the
same read-time validation for both entry lists: de_count must equal the
capacity of the block (ocfs2_dx_entries_per_leaf()/per_root()) and
de_num_used must not exceed de_count, rejecting corrupted metadata with
-EFSCORRUPTED before ocfs2_dx_dir_search() can walk an out-of-range entry
array.
de_count is always written as exactly the block capacity when a leaf or
inline root is formatted, so the equality check does not reject any valid
image.
Found by 0sec automated security-research tooling (https://0sec.ai).
Link: https://lore.kernel.org/20260713205625.92391-1-doruk@0sec.ai
Fixes: 9b7895efac90 ("ocfs2: Add a name indexed b-tree to directory inodes")
Fixes: 4ed8a6bb083b ("ocfs2: Store dir index records inline")
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/dir.c | 45 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index b758f11738c65..bb3a67b9edff0 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -611,6 +611,28 @@ static int ocfs2_validate_dx_root(struct super_block *sb,
le16_to_cpu(el->l_count));
goto bail;
}
+ } else {
+ struct ocfs2_dx_entry_list *dl_list = &dx_root->dr_entries;
+
+ if (le16_to_cpu(dl_list->de_count) !=
+ ocfs2_dx_entries_per_root(sb)) {
+ ret = ocfs2_error(sb,
+ "Dir Index Root # %llu has invalid de_count %u (expected %u)\n",
+ (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+ le16_to_cpu(dl_list->de_count),
+ ocfs2_dx_entries_per_root(sb));
+ goto bail;
+ }
+
+ if (le16_to_cpu(dl_list->de_num_used) >
+ le16_to_cpu(dl_list->de_count)) {
+ ret = ocfs2_error(sb,
+ "Dir Index Root # %llu has invalid de_num_used %u (de_count %u)\n",
+ (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+ le16_to_cpu(dl_list->de_num_used),
+ le16_to_cpu(dl_list->de_count));
+ goto bail;
+ }
}
bail:
@@ -650,10 +672,25 @@ static int ocfs2_validate_dx_leaf(struct super_block *sb,
return ret;
}
- if (!OCFS2_IS_VALID_DX_LEAF(dx_leaf)) {
- ret = ocfs2_error(sb, "Dir Index Leaf has bad signature %.*s\n",
- 7, dx_leaf->dl_signature);
- }
+ if (!OCFS2_IS_VALID_DX_LEAF(dx_leaf))
+ return ocfs2_error(sb, "Dir Index Leaf has bad signature %.*s\n",
+ 7, dx_leaf->dl_signature);
+
+ if (le16_to_cpu(dx_leaf->dl_list.de_count) !=
+ ocfs2_dx_entries_per_leaf(sb))
+ return ocfs2_error(sb,
+ "Dir Index Leaf # %llu has invalid de_count %u (expected %u)\n",
+ (unsigned long long)le64_to_cpu(dx_leaf->dl_blkno),
+ le16_to_cpu(dx_leaf->dl_list.de_count),
+ ocfs2_dx_entries_per_leaf(sb));
+
+ if (le16_to_cpu(dx_leaf->dl_list.de_num_used) >
+ le16_to_cpu(dx_leaf->dl_list.de_count))
+ return ocfs2_error(sb,
+ "Dir Index Leaf # %llu has invalid de_num_used %u (de_count %u)\n",
+ (unsigned long long)le64_to_cpu(dx_leaf->dl_blkno),
+ le16_to_cpu(dx_leaf->dl_list.de_num_used),
+ le16_to_cpu(dx_leaf->dl_list.de_count));
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0032/1887] wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0031/1887] ocfs2: validate directory-index entry counts when reading metadata Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0033/1887] usb: storage: realtek_cr: fix use-after-free on disconnect Greg Kroah-Hartman
` (966 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ping-Ke Shih, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 6c080026ecc17eecb103f8927c64ea73a74bb818 ]
rtl8xxxu arms rx_urb_wq from the RX completion path:
rtl8xxxu_rx_complete() hands the URB to rtl8xxxu_queue_rx_urb(), which
queues it on rx_urb_pending_list and, once the list grows past
RTL8XXXU_RX_URB_PENDING_WATER, schedules rx_urb_wq. The worker
rtl8xxxu_rx_urb_work() drains rx_urb_pending_list, recovers priv through
container_of, and resubmits each URB through rtl8xxxu_submit_rx_urb(),
which anchors it on rx_anchor and dereferences priv->udev.
rtl8xxxu_stop() cancels the sibling work items (c2hcmd_work, ra_watchdog,
update_beacon_work) but never cancels rx_urb_wq, so a worker armed during
the last burst of RX traffic can run rtl8xxxu_rx_urb_work() after
rtl8xxxu_disconnect() has called ieee80211_free_hw(), which frees priv,
producing a use-after-free. The window opens under active RX traffic
(pending count above the watermark) followed by a disconnect.
There are two teardown races to close:
* rtl8xxxu_queue_rx_urb() decided whether to enqueue under rx_urb_lock
but called schedule_work() after dropping the lock. A completion
that observed shutdown == false and released the lock could then call
schedule_work() after rtl8xxxu_stop() had set shutdown and
cancel_work_sync() had already returned, arming the worker to run
after the teardown. Move schedule_work() under the same !shutdown
branch so the arming decision is atomic with the shutdown check.
* rtl8xxxu_rx_urb_work() anchors every URB it drained back onto
rx_anchor through rtl8xxxu_submit_rx_urb(). A worker still running
when usb_kill_anchored_urbs(&priv->rx_anchor) returned would submit a
URB that escaped the kill. In rtl8xxxu_stop(), call
cancel_work_sync(&priv->rx_urb_wq) before the kill so the worker is
drained first.
After priv->shutdown is set under rx_urb_lock, completions can no longer
queue rx_urb_wq. cancel_work_sync() then drains the last queued or running
worker, and the following usb_kill_anchored_urbs() kills the URBs it may
have submitted.
rtl8xxxu_disconnect() is covered because ieee80211_unregister_hw()
guarantees .stop() runs for a live interface before ieee80211_free_hw()
frees priv. The probe error path needs no cancel: rx_urb_wq is
INIT_WORK()'d there but cannot have been scheduled, since no URB is
submitted before ieee80211_register_hw() succeeds.
This bug was found by static analysis.
Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
Cc: stable@vger.kernel.org
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260630033117.3377-1-fanwu01@zju.edu.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index c1bc55f0e4c01..20a7537d2cae8 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -5263,14 +5263,19 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
{
struct sk_buff *skb;
unsigned long flags;
- int pending = 0;
spin_lock_irqsave(&priv->rx_urb_lock, flags);
if (!priv->shutdown) {
list_add_tail(&rx_urb->list, &priv->rx_urb_pending_list);
priv->rx_urb_pending_count++;
- pending = priv->rx_urb_pending_count;
+ /*
+ * Arm the worker under rx_urb_lock so this is atomic with the
+ * shutdown check: moving it out of the lock would let a
+ * completion arm the work after rtl8xxxu_stop() canceled it.
+ */
+ if (priv->rx_urb_pending_count > RTL8XXXU_RX_URB_PENDING_WATER)
+ schedule_work(&priv->rx_urb_wq);
} else {
skb = (struct sk_buff *)rx_urb->urb.context;
dev_kfree_skb_irq(skb);
@@ -5278,9 +5283,6 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv,
}
spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
-
- if (pending > RTL8XXXU_RX_URB_PENDING_WATER)
- schedule_work(&priv->rx_urb_wq);
}
static void rtl8xxxu_rx_urb_work(struct work_struct *work)
@@ -6529,6 +6531,13 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
priv->shutdown = true;
spin_unlock_irqrestore(&priv->rx_urb_lock, flags);
+ /*
+ * Cancel before killing rx_anchor: the worker re-anchors every URB
+ * it drained via rtl8xxxu_submit_rx_urb(), so a worker still running
+ * after the kill could submit a URB that escapes it.
+ */
+ cancel_work_sync(&priv->rx_urb_wq);
+
usb_kill_anchored_urbs(&priv->rx_anchor);
usb_kill_anchored_urbs(&priv->tx_anchor);
if (priv->usb_interrupts)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0033/1887] usb: storage: realtek_cr: fix use-after-free on disconnect
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0032/1887] wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0034/1887] staging: rtl8723bs: fix spacing around operators Greg Kroah-Hartman
` (965 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 4ffee1aebb0c0ffcda9faffd17834ea9b00d42cc ]
realtek_cr_destructor() calls timer_delete() before the chip containing
the timer is freed. The timer callback may still be running and can
rearm itself, resulting in a use-after-free.
Use timer_shutdown_sync() to wait for the callback and prevent further
rearming. Do this unconditionally because ss_en may be changed after
the timer is armed.
Move timer_setup() into init_realtek_cr() so the timer is initialized
before any failure path can invoke the destructor.
Found by static analysis.
Fixes: e931830bb877 ("Realtek cr: Add autosuspend function.")
Cc: stable <stable@kernel.org>
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260727123414.44700-1-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ adapted the timer_delete() removal to the branch’s del_timer() spelling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/storage/realtek_cr.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index a026c6cb6e684..de82d8260d729 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -915,7 +915,6 @@ static int realtek_cr_autosuspend_setup(struct us_data *us)
us->proto_handler = rts51x_invoke_transport;
chip->timer_expires = 0;
- timer_setup(&chip->rts51x_suspend_timer, rts51x_suspend_timer_fn, 0);
fw5895_init(us);
/* enable autosuspend function of the usb device */
@@ -933,10 +932,7 @@ static void realtek_cr_destructor(void *extra)
return;
#ifdef CONFIG_REALTEK_AUTOPM
- if (ss_en) {
- del_timer(&chip->rts51x_suspend_timer);
- chip->timer_expires = 0;
- }
+ timer_shutdown_sync(&chip->rts51x_suspend_timer);
#endif
kfree(chip->status);
}
@@ -981,6 +977,9 @@ static int init_realtek_cr(struct us_data *us)
us->extra = chip;
us->extra_destructor = realtek_cr_destructor;
+#ifdef CONFIG_REALTEK_AUTOPM
+ timer_setup(&chip->rts51x_suspend_timer, rts51x_suspend_timer_fn, 0);
+#endif
us->max_lun = chip->max_lun = rts51x_get_max_lun(us);
chip->us = us;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0034/1887] staging: rtl8723bs: fix spacing around operators
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0033/1887] usb: storage: realtek_cr: fix use-after-free on disconnect Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0035/1887] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie() Greg Kroah-Hartman
` (964 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vivek BalachandharTN, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vivek BalachandharTN <vivek.balachandhar@gmail.com>
[ Upstream commit 2038fe84b8bdf894b634f777096685e78e8f3774 ]
Fix several instances where operators lacked spaces around them.
This improves readability and brings the driver closer to kernel
coding-style guidelines. No functional change.
Signed-off-by: Vivek BalachandharTN <vivek.balachandhar@gmail.com>
Link: https://patch.msgid.link/20251205021417.2705864-3-vivek.balachandhar@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
For this stable dependency, retain only the spacing change to the IE
advance in rtw_restruct_wmm_ie(). This supplies the exact context needed
by target commit 28a289beaf226 ("staging: rtl8723bs: fix OOB read in
rtw_restruct_wmm_ie()"). Drop the unrelated operator-spacing hunks.
Keep the existing bounds-first WMM match condition from stable commit
4dd2d9cf563c5 (upstream a75281626fc8f); applying the older condition
would undo its out-of-bounds-read fix. No functional change.
Stable-dep-of: 28a289beaf22 ("staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/rtl8723bs/core/rtw_mlme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
index d7fdac14e73dc..0c8b1541f243e 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -2025,7 +2025,7 @@ int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_
break;
}
- i += (in_ie[i+1]+2); /* to the next IE element */
+ i += (in_ie[i + 1] + 2); /* to the next IE element */
}
return ielength;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0035/1887] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0034/1887] staging: rtl8723bs: fix spacing around operators Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0036/1887] ftrace: Take trace_array reference before accessing its ftrace_ops Greg Kroah-Hartman
` (963 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <meatuni001@gmail.com>
[ Upstream commit 28a289beaf226b30b1e6e7d7b1a2946fe2d6e852 ]
rtw_restruct_wmm_ie() scans in_ie for a WMM IE with:
while (i < in_len) {
...
if (i + 5 < in_len && in_ie[i] == 0xDD && ...) {
...
break;
}
i += (in_ie[i + 1] + 2); /* to the next IE element */
}
When the "i + 5 < in_len" match check fails simply because i is
within 5 bytes of the end of the buffer (i.e. no WMM IE was found
near the tail of in_ie), execution falls through to
"i += (in_ie[i + 1] + 2)", which reads in_ie[i + 1]. If i == in_len
- 1 at that point, this is a 1-byte out-of-bounds read of an
attacker-influenced IE buffer built from association/scan data.
Commit a75281626fc8f ("staging: rtl8723bs: fix potential
out-of-bounds read in rtw_restruct_wmm_ie") added the "i + 5 <
in_len" guard to the match condition itself, but did not add an
equivalent guard before the fallthrough advance, so the same class
of OOB read remained reachable through the non-matching path.
Add an explicit bounds check before advancing to the next IE.
Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260728125456.32359-4-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/rtl8723bs/core/rtw_mlme.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
index 0c8b1541f243e..258972f6de3fa 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -2025,6 +2025,9 @@ int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_
break;
}
+ if (i + 1 >= in_len)
+ break;
+
i += (in_ie[i + 1] + 2); /* to the next IE element */
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0036/1887] ftrace: Take trace_array reference before accessing its ftrace_ops
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0035/1887] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0037/1887] nvme: add missing SRCU grace period in error path Greg Kroah-Hartman
` (962 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Steven Rostedt,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 9100191e5acb2e5ea2313f436667bb5fce129f47 ]
The trace instance files set_ftrace_filter and set_ftrace_notrace was
updated to work with specific trace instances (trace_arrays). The issue is
that when these files are opened, there is a small race window where it
will use the ftrace_ops from the inode->private pointer to get a reference
to the trace_array and then take its reference. The problem is that the
ftrace_ops itself could be freed. If the rmdir on the instance happens at
the same time the set_ftrace_filter file is opened, the rmdir could have
also freed the ftrace_ops and referencing it will cause a use-after-free
bug and crash the kernel.
Instead, pass in the trace_array as the file private data (NULL for the
top level instance), and then pass both the trace_array and the ftrace_ops
to the ftrace_regex_open() function. If the trace_array is NULL, then it
just uses the ftrace_ops without the need to take its reference (like
normal). If the ftrace_ops is NULL, that is only the case for the top
level instance and the global_ops can be used.
This allows the trace_array to have its reference incremented before
touching the ftrace_ops that could also be freed when the instance is.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260828223901.29e26edb@robin
Fixes: 591dffdade9f0 ("ftrace: Allow for function tracing instance to filter functions")
Reported-by: Breno Leitao <leitao@debian.org>
Tested-by: Breno Leitao <leitao@debian.org>
Closes: https://lore.kernel.org/all/apGORjltZgAiAYHT@gmail.com/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ Replaced kzalloc_obj(*iter) with kzalloc(sizeof(*iter), GFP_KERNEL). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ftrace.h | 5 +--
kernel/trace/ftrace.c | 59 ++++++++++++++++++++++------------
kernel/trace/trace.h | 4 +--
kernel/trace/trace_functions.c | 2 +-
kernel/trace/trace_stack.c | 2 +-
5 files changed, 46 insertions(+), 26 deletions(-)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index d29b74e4e7c3d..07003b68b7b28 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -644,8 +644,9 @@ unsigned long ftrace_get_addr_new(struct dyn_ftrace *rec);
unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec);
extern ftrace_func_t ftrace_trace_function;
+struct trace_array;
-int ftrace_regex_open(struct ftrace_ops *ops, int flag,
+int ftrace_regex_open(struct trace_array *tr, struct ftrace_ops *ops, int flag,
struct inode *inode, struct file *file);
ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
size_t cnt, loff_t *ppos);
@@ -859,7 +860,7 @@ static inline unsigned long ftrace_location(unsigned long ip)
* have them defined when ftrace is not enabled, but these
* functions may still be called. Use a macro instead of inline.
*/
-#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; })
+#define ftrace_regex_open(tr, ops, flag, inode, file) ({ -ENODEV; })
#define ftrace_set_early_filter(ops, buf, enable) do { } while (0)
#define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; })
#define ftrace_set_filter_ips(ops, ips, cnt, remove, reset) ({ -ENODEV; })
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index ad112022dad78..eee7bb2843940 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3889,7 +3889,8 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
/**
* ftrace_regex_open - initialize function tracer filter files
- * @ops: The ftrace_ops that hold the hash filters
+ * @tr: The trace_array that holds the ftrace_ops [optional]
+ * @ops: The ftrace_ops that hold the hash filters [optional]
* @flag: The type of filter to process
* @inode: The inode, usually passed in to your open routine
* @file: The file, usually passed in to your open routine
@@ -3902,25 +3903,46 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
* ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set.
* tracing_lseek() should be used as the lseek routine, and
* release must call ftrace_regex_release().
+ *
+ * Note, If @tr is not NULL, its reference has to be taken before
+ * @ops may be referenced.
+ * If @ops is NULL and @tr is not, then @tr->ops is used.
+ * If @tr is NULL and @ops is not then @ops->private is uesd for @tr.
+ * If both @tr and @ops are NULL, then the &global_ops is
+ * to be used, and @tr will be the global_ops.private pointer.
+ *
+ * Returns: 0 on success or a negative errno value on failure
*/
int
-ftrace_regex_open(struct ftrace_ops *ops, int flag,
+ftrace_regex_open(struct trace_array *tr, struct ftrace_ops *ops, int flag,
struct inode *inode, struct file *file)
{
- struct ftrace_iterator *iter;
+ struct ftrace_iterator *iter = NULL;
struct ftrace_hash *hash;
struct list_head *mod_head;
- struct trace_array *tr = ops->private;
- int ret = -ENOMEM;
-
- ftrace_ops_init(ops);
+ int ret = -ENODEV;
if (unlikely(ftrace_disabled))
return -ENODEV;
+ if (!tr) {
+ if (!ops)
+ ops = &global_ops;
+ tr = ops->private;
+ }
+
if (tracing_check_open_get_tr(tr))
return -ENODEV;
+ if (!ops)
+ ops = tr->ops;
+
+ if (WARN_ON_ONCE(!ops))
+ goto out;
+
+ ftrace_ops_init(ops);
+
+ ret = -ENOMEM;
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
if (!iter)
goto out;
@@ -3998,21 +4020,19 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
static int
ftrace_filter_open(struct inode *inode, struct file *file)
{
- struct ftrace_ops *ops = inode->i_private;
+ struct trace_array *tr = inode->i_private;
- /* Checks for tracefs lockdown */
- return ftrace_regex_open(ops,
- FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
- inode, file);
+ return ftrace_regex_open(tr, NULL,
+ FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+ inode, file);
}
static int
ftrace_notrace_open(struct inode *inode, struct file *file)
{
- struct ftrace_ops *ops = inode->i_private;
+ struct trace_array *tr = inode->i_private;
- /* Checks for tracefs lockdown */
- return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
+ return ftrace_regex_open(tr, NULL, FTRACE_ITER_NOTRACE,
inode, file);
}
@@ -6621,15 +6641,15 @@ static const struct file_operations ftrace_graph_notrace_fops = {
};
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
struct dentry *parent)
{
trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
- ops, &ftrace_filter_fops);
+ tr, &ftrace_filter_fops);
trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent,
- ops, &ftrace_notrace_fops);
+ tr, &ftrace_notrace_fops);
}
/*
@@ -6654,14 +6674,13 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops)
static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
{
-
trace_create_file("available_filter_functions", TRACE_MODE_READ,
d_tracer, NULL, &ftrace_avail_fops);
trace_create_file("enabled_functions", TRACE_MODE_READ,
d_tracer, NULL, &ftrace_enabled_fops);
- ftrace_create_filter_files(&global_ops, d_tracer);
+ ftrace_create_filter_files(NULL, d_tracer);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
trace_create_file("set_graph_function", TRACE_MODE_WRITE, d_tracer,
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 8cdb8e1a33c1e..f86b6f263ddf6 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1092,7 +1092,7 @@ extern void clear_ftrace_function_probes(struct trace_array *tr);
int register_ftrace_command(struct ftrace_func_command *cmd);
int unregister_ftrace_command(struct ftrace_func_command *cmd);
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
struct dentry *parent);
void ftrace_destroy_filter_files(struct ftrace_ops *ops);
@@ -1115,11 +1115,11 @@ static inline void clear_ftrace_function_probes(struct trace_array *tr)
{
}
+#define ftrace_create_filter_files(tr, parent) do { } while (0)
/*
* The ops parameter passed in is usually undefined.
* This must be a macro.
*/
-#define ftrace_create_filter_files(ops, parent) do { } while (0)
#define ftrace_destroy_filter_files(ops) do { } while (0)
#endif /* CONFIG_FUNCTION_TRACER && CONFIG_DYNAMIC_FTRACE */
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 44ae51d1dc45d..eecac19a2bcbb 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -90,7 +90,7 @@ int ftrace_create_function_files(struct trace_array *tr,
if (!tr->ops)
return -EINVAL;
- ftrace_create_filter_files(tr->ops, parent);
+ ftrace_create_filter_files(tr, parent);
return 0;
}
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 5a48dba912eae..c6b2f622ffa12 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -499,7 +499,7 @@ stack_trace_filter_open(struct inode *inode, struct file *file)
struct ftrace_ops *ops = inode->i_private;
/* Checks for tracefs lockdown */
- return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
+ return ftrace_regex_open(NULL, ops, FTRACE_ITER_FILTER,
inode, file);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0037/1887] nvme: add missing SRCU grace period in error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0036/1887] ftrace: Take trace_array reference before accessing its ftrace_ops Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0038/1887] KVM: s390: Zero initialize data structures for inject_pfault_token Greg Kroah-Hartman
` (961 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tristan Madani, Sagi Grimberg,
John Garry, Christoph Hellwig, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <tristan@talencesecurity.com>
[ Upstream commit ef248d5de4469fb6bbaf8dbe0c4c47800080d648 ]
nvme_alloc_ns() error path at out_unlink_ns removes ns from the
namespace head siblings list with list_del_rcu(&ns->siblings) but
does not wait for SRCU readers before freeing the namespace struct.
Multipath code iterates the head->list under srcu_read_lock() in
nvme_find_path() and nvme_mpath_revalidate_paths(), so a concurrent
reader can still hold a reference to ns when kfree(ns) runs.
The normal removal path in nvme_ns_remove() correctly calls
synchronize_srcu(&ns->head->srcu) after list_del_rcu() to wait for
in-progress readers. Add the same grace period in the error path.
Fixes: ed754e5deeb1 ("nvme: track shared namespaces")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Adjusted patch context to account for missing last_path reference-counting code. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 66600341bd6aa..1faef93ce4ba6 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4437,6 +4437,9 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
if (list_empty(&ns->head->list))
list_del_init(&ns->head->entry);
mutex_unlock(&ctrl->subsys->lock);
+
+ /* guarantee not available in head->list */
+ synchronize_srcu(&ns->head->srcu);
nvme_put_ns_head(ns->head);
out_cleanup_disk:
put_disk(disk);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0038/1887] KVM: s390: Zero initialize data structures for inject_pfault_token
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0037/1887] nvme: add missing SRCU grace period in error path Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0039/1887] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak Greg Kroah-Hartman
` (960 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Borntraeger,
Matthew Rosato, Claudio Imbrenda, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Borntraeger <borntraeger@linux.ibm.com>
[ Upstream commit 4e2c7f7cbc27418f9a290399b986c1b85ff93b90 ]
__kvm_inject_pfault_token() only sets .type and .u.ext.ext_params2 of
the on-stack struct kvm_s390_irq but the full ext substructure is copied
into the cpu local variable on inject. ext_params and pad contain stale
stack values.
Interrupt delivery only uses ext_params2, so nothing leaks to the guest,
but a host user can use the migration ioctls to get to the data.
Fix by zero-initializing the irq struct.
Do the same for the inti data structure.
Fixes: 383d0b050106 ("KVM: s390: handle pending local interrupts via bitmap")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20260805110455.7200-3-borntraeger@linux.ibm.com>
[ Adjusted context for missing inti_mem and ret declarations in __kvm_inject_pfault_token(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kvm/kvm-s390.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index c7b4c0d37c87b..9b9d8d37bcc41 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -4430,8 +4430,8 @@ long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable)
static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token,
unsigned long token)
{
- struct kvm_s390_interrupt inti;
- struct kvm_s390_irq irq;
+ struct kvm_s390_interrupt inti = {};
+ struct kvm_s390_irq irq = {};
if (start_token) {
irq.u.ext.ext_params2 = token;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0039/1887] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0038/1887] KVM: s390: Zero initialize data structures for inject_pfault_token Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0040/1887] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
` (959 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit a152edab3854f01dd2daf3eaf8f32cbabdb3834e ]
qla2x00_do_dport_diagnostics() allocates the qla_dport_diag response
buffer with kmalloc_obj() (non-zeroing) and, on success, copies the full
sizeof(*dd) back to user space via sg_copy_from_buffer(). The inbound
sg_copy_to_buffer() only fills as many bytes as the user request payload
provides, and qla26xx_dport_diagnostics() zeroes only dd->buf. The
options and unused[] fields are therefore copied out uninitialized,
leaking kernel heap contents to user space.
Allocate with kzalloc_obj(), matching qla2x00_do_dport_diagnostics_v2().
Fixes: ec89146215d1 ("qla2xxx: Add bsg interface to support D_Port Diagnostics.")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-54-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adapted kzalloc_obj(*dd) to kzalloc(sizeof(*dd), GFP_KERNEL) to match the branch’s allocation syntax. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_bsg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 3982f7d576a83..8e859d79bdee1 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2412,7 +2412,7 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
!IS_QLA28XX(vha->hw))
return -EPERM;
- dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+ dd = kzalloc(sizeof(*dd), GFP_KERNEL);
if (!dd) {
ql_log(ql_log_warn, vha, 0x70db,
"Failed to allocate memory for dport.\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0040/1887] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0039/1887] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0041/1887] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
` (958 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 34a40e0dff940ac5eba494a69b553ea571e24873 ]
qla25xx_free_req_que() and qla25xx_free_rsp_que() have two pre-existing
bugs exposed on the error path of qla25xx_create_{req,rsp}_que():
1. When dma_alloc_coherent() fails during queue creation, the error
path calls the free function with req->ring / rsp->ring still NULL
(from kzalloc). The unconditional dma_free_coherent() with a NULL
cpu_addr is undefined behavior and can panic.
2. The free functions clear req_qid_map / rsp_qid_map under vport_lock,
but the create functions protect the same bitmaps with mq_lock.
This provides no mutual exclusion. Additionally, the create error
path clears the bit and releases mq_lock before calling the free
function, creating a window where another thread can allocate the
same que_id and have its ha->req_q_map entry clobbered by the
subsequent lockless NULL assignment in the free function.
Fix by:
- Guarding dma_free_coherent() with a NULL check on the ring pointer.
- Using mq_lock (the lock held by all creators) in the free functions
to atomically NULL the map entry and clear the bitmap bit.
- Removing the now-redundant clear_bit blocks from the create error
paths since the free functions handle it atomically.
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-41-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Backport adaptation for the stable tree: the 29xx IOCB size-selection
helpers are absent, and queue creation still allocates fixed-size entries.
Initialize the local req_entry_size and rsp_entry_size values with
sizeof(request_t) and sizeof(response_t), respectively, so DMA freeing
continues to match allocation without adding helper functions or 29xx
support. Retain all NULL-ring guards, mq_lock protection, and removal of
the premature bitmap clears.
Keep the response-ring cleanup layout used by upstream so target commit
19788a55cab61d78e33e0914a5a31d27843e8a4a applies unchanged.
Stable-dep-of: 19788a55cab6 ("scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_mid.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 79e4319bbbd28..b25439db6867d 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -583,16 +583,19 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req)
{
struct qla_hw_data *ha = vha->hw;
uint16_t que_id = req->id;
+ size_t req_entry_size = sizeof(request_t);
- dma_free_coherent(&ha->pdev->dev, (req->length + 1) *
- sizeof(request_t), req->ring, req->dma);
+ if (req->ring)
+ dma_free_coherent(&ha->pdev->dev,
+ (req->length + 1) * req_entry_size,
+ req->ring, req->dma);
req->ring = NULL;
req->dma = 0;
if (que_id) {
+ mutex_lock(&ha->mq_lock);
ha->req_q_map[que_id] = NULL;
- mutex_lock(&ha->vport_lock);
clear_bit(que_id, ha->req_qid_map);
- mutex_unlock(&ha->vport_lock);
+ mutex_unlock(&ha->mq_lock);
}
kfree(req->outstanding_cmds);
kfree(req);
@@ -603,6 +606,7 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
{
struct qla_hw_data *ha = vha->hw;
uint16_t que_id = rsp->id;
+ size_t rsp_entry_size = sizeof(response_t);
if (rsp->msix && rsp->msix->have_irq) {
free_irq(rsp->msix->vector, rsp->msix->handle);
@@ -610,15 +614,18 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
rsp->msix->in_use = 0;
rsp->msix->handle = NULL;
}
- dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) *
- sizeof(response_t), rsp->ring, rsp->dma);
+
+ if (rsp->ring)
+ dma_free_coherent(&ha->pdev->dev,
+ (rsp->length + 1) * rsp_entry_size,
+ rsp->ring, rsp->dma);
rsp->ring = NULL;
rsp->dma = 0;
if (que_id) {
+ mutex_lock(&ha->mq_lock);
ha->rsp_q_map[que_id] = NULL;
- mutex_lock(&ha->vport_lock);
clear_bit(que_id, ha->rsp_qid_map);
- mutex_unlock(&ha->vport_lock);
+ mutex_unlock(&ha->mq_lock);
}
kfree(rsp);
}
@@ -803,9 +810,6 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
if (ret != QLA_SUCCESS) {
ql_log(ql_log_fatal, base_vha, 0x00df,
"%s failed.\n", __func__);
- mutex_lock(&ha->mq_lock);
- clear_bit(que_id, ha->req_qid_map);
- mutex_unlock(&ha->mq_lock);
goto que_failed;
}
vha->flags.qpairs_req_created = 1;
@@ -917,9 +921,6 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
if (ret != QLA_SUCCESS) {
ql_log(ql_log_fatal, base_vha, 0x00e7,
"%s failed.\n", __func__);
- mutex_lock(&ha->mq_lock);
- clear_bit(que_id, ha->rsp_qid_map);
- mutex_unlock(&ha->mq_lock);
goto que_failed;
}
vha->flags.qpairs_rsp_created = 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0041/1887] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0040/1887] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0042/1887] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
` (957 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 19788a55cab61d78e33e0914a5a31d27843e8a4a ]
The response queue MSI-X handler qla2xxx_msix_rsp_q() schedules
qla_do_work() via queue_work(ha->wq, &qpair->q_work). qla_do_work()
dereferences the qpair (vha, rsp) and takes qpair->qp_lock.
During teardown, qla2xxx_delete_qpair() deletes the response queue, which
calls free_irq() in qla25xx_free_rsp_que(), and then frees the queue and
the qpair. free_irq() waits for running hardirq handlers but does not
cancel work already placed on ha->wq. A still-pending q_work then runs
qla_do_work() against the freed qpair and response queue, causing a
use-after-free. This is especially likely during full adapter teardown,
where destroy_workqueue(ha->wq) forces pending work to run after the queue
pairs have been freed.
Flush the work item with cancel_work_sync() in qla25xx_free_rsp_que()
after free_irq() has released the interrupt (so no new work can be
queued) and before the response queue and qpair memory are freed (so the
flushed handler still sees valid memory). Guard on rsp->qpair and ha->wq
to match the INIT_WORK() condition and avoid operating on an
uninitialized work_struct.
Fixes: 68ca949cdb04 ("[SCSI] qla2xxx: Add CPU affinity support.")
Reported-by: Sashiko <sashiko-dev@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-5-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_mid.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index b25439db6867d..11434b695b037 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -615,6 +615,10 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
rsp->msix->handle = NULL;
}
+ /* Flush any queued response work before freeing the queue/qpair. */
+ if (rsp->qpair && ha->wq)
+ cancel_work_sync(&rsp->qpair->q_work);
+
if (rsp->ring)
dma_free_coherent(&ha->pdev->dev,
(rsp->length + 1) * rsp_entry_size,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0042/1887] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[]
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0041/1887] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0043/1887] f2fs: embed f2fs_gc_kthread in f2fs_sb_info Greg Kroah-Hartman
` (956 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 4cf38dd9465736141263ebb63375868311a0ec81 ]
The FC BSG transport allocates job->request via memdup_user() using the
exact user-supplied request_len. For FC_BSG_HST_VENDOR,
fc_bsg_host_dispatch() only guarantees request_len covers msgcode and
vendor_id; it does not account for the vendor_cmd[] flexible array.
qla2xxx then reads the command selector vendor_cmd[0] and, in several
sub-handlers, vendor_cmd[1]/[2] or structures overlaid on the vendor
command area without verifying request_len. A caller holding
CAP_SYS_RAWIO can submit a short request whose vendor_id matches the
host, triggering out-of-bounds heap reads (KASAN-detectable, and able to
mis-select a command or panic).
Add a central guard in qla2x00_process_vendor_specific() so the selector
is always in bounds, restrict the early vendor_cmd[0] read in
qla24xx_bsg_request() to sufficiently long vendor messages, and add
request_len checks to the sub-handlers that read further:
qla24xx_proc_fcp_prio_cfg_cmd(), qla2x00_process_loopback(),
qla84xx_reset(), qla84xx_updatefw(), qla2x00_read_optrom(),
qla2x00_update_optrom(), qlafx00_mgmt_cmd() and
qla28xx_validate_flash_image().
Fixes: 01e0e15c8b3b ("scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-31-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adapted hunks to the existing OPTROM helper and absence of qla28xx_validate_flash_image(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_bsg.c | 45 ++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 8e859d79bdee1..0fbf6dba5a368 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -158,6 +158,12 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
goto exit_fcp_prio_cfg;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t)) {
+ ret = -EINVAL;
+ goto exit_fcp_prio_cfg;
+ }
+
/* Get the sub command */
oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
@@ -756,6 +762,10 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
return -EIO;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 3 * sizeof(uint32_t))
+ return -EINVAL;
+
memset(&elreq, 0, sizeof(elreq));
elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
@@ -988,6 +998,10 @@ qla84xx_reset(struct bsg_job *bsg_job)
return -EINVAL;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
@@ -1032,6 +1046,10 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
return -EINVAL;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!sg_cnt) {
@@ -1482,6 +1500,10 @@ qla2x00_read_optrom(struct bsg_job *bsg_job)
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
if (ha->flags.nic_core_reset_hdlr_active)
return -EBUSY;
@@ -1519,6 +1541,10 @@ qla2x00_update_optrom(struct bsg_job *bsg_job)
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
mutex_lock(&ha->optrom_mutex);
rval = qla2x00_optrom_setup(bsg_job, vha, 1);
if (rval) {
@@ -2010,6 +2036,11 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
struct fc_port *fcport;
char *type = "FC_BSG_HST_FX_MGMT";
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t) +
+ sizeof(struct qla_mt_iocb_rqst_fx00))
+ return -EINVAL;
+
/* Copy the IOCB specific information */
piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
&bsg_request->rqst_data.h_vendor.vendor_cmd[1];
@@ -2899,6 +2930,13 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j
{
struct fc_bsg_request *bsg_request = bsg_job->request;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t)) {
+ ql_log(ql_log_warn, vha, 0x7000,
+ "BSG request too small for vendor cmd.\n");
+ return -EINVAL;
+ }
+
ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
__func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
@@ -3024,8 +3062,11 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
}
/* Disable port will bring down the chip, allow enable command */
- if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
- bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
+ if (bsg_request->msgcode == FC_BSG_HST_VENDOR &&
+ bsg_job->request_len >=
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t) &&
+ (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
+ bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS))
goto skip_chip_chk;
if (vha->hw->flags.port_isolated) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0043/1887] f2fs: embed f2fs_gc_kthread in f2fs_sb_info
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0042/1887] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0044/1887] Bluetooth: btqcomsmd: Convert to platform remove callback returning void Greg Kroah-Hartman
` (955 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 3d7bca9d583793bb7d0bac0d95a24ddd2e129eed ]
Instead of allocating f2fs_gc_kthread dynamically, embed it in
f2fs_sb_info. This simplifies lifetime management and prepares for
fixing race conditions during teardown.
- __sbi_store - remount|shutdown
- f2fs_stop_gc_thread
- access sbi->gc_thread
- sbi->gc_thread = NULL
- access sbi->gc_thread->f2fs_gc_task
Fixes: 52190933c37a ("f2fs: sysfs: introduce critical_task_priority")
Fixes: 7950e9ac638e ("f2fs: stop gc/discard thread after fs shutdown")
Cc: stable@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ adapted to the 6.1 GC-thread structure without newer zoned-GC fields. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/debug.c | 4 ----
fs/f2fs/f2fs.h | 22 +++++++++++++++++++++-
fs/f2fs/gc.c | 33 ++++++++++++---------------------
fs/f2fs/gc.h | 20 --------------------
fs/f2fs/segment.c | 9 ++++-----
fs/f2fs/super.c | 4 ++--
fs/f2fs/sysfs.c | 14 +++++++-------
7 files changed, 46 insertions(+), 60 deletions(-)
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index dd6e8a10193b4..711b4262a0c75 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -280,10 +280,6 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
get_cache:
si->cache_mem = 0;
- /* build gc */
- if (sbi->gc_thread)
- si->cache_mem += sizeof(struct f2fs_gc_kthread);
-
/* build merge flush thread */
if (SM_I(sbi)->fcc_info)
si->cache_mem += sizeof(struct flush_cmd_control);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index cbf4032b5b7ee..3b1d99d03ab1b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1599,6 +1599,26 @@ struct decompress_io_ctx {
#define MAX_COMPRESS_LOG_SIZE 8
#define MAX_COMPRESS_WINDOW_SIZE(log_size) ((PAGE_SIZE) << (log_size))
+struct f2fs_gc_kthread {
+ struct task_struct *f2fs_gc_task;
+ wait_queue_head_t gc_wait_queue_head;
+
+ /* for gc sleep time */
+ unsigned int urgent_sleep_time;
+ unsigned int min_sleep_time;
+ unsigned int max_sleep_time;
+ unsigned int no_gc_sleep_time;
+
+ /* for changing gc mode */
+ unsigned int gc_wake;
+
+ /* for GC_MERGE mount option */
+ wait_queue_head_t fggc_wq; /*
+ * caller of f2fs_balance_fs()
+ * will wait on this wait queue.
+ */
+};
+
struct f2fs_sb_info {
struct super_block *sb; /* pointer to VFS super block */
struct proc_dir_entry *s_proc; /* proc entry */
@@ -1715,7 +1735,7 @@ struct f2fs_sb_info {
* semaphore for GC, avoid
* race between GC and GC or CP
*/
- struct f2fs_gc_kthread *gc_thread; /* GC thread */
+ struct f2fs_gc_kthread gc_thread; /* GC thread */
struct atgc_management am; /* atgc management */
unsigned int cur_victim_sec; /* current victim section num */
unsigned int gc_mode; /* current GC state */
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 687b2ce82c854..0254e3116e552 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -31,9 +31,9 @@ static unsigned int count_bits(const unsigned long *addr,
static int gc_thread_func(void *data)
{
struct f2fs_sb_info *sbi = data;
- struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
- wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head;
- wait_queue_head_t *fggc_wq = &sbi->gc_thread->fggc_wq;
+ struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
+ wait_queue_head_t *wq = &sbi->gc_thread.gc_wait_queue_head;
+ wait_queue_head_t *fggc_wq = &sbi->gc_thread.fggc_wq;
unsigned int wait_ms;
struct f2fs_gc_control gc_control = {
.victim_segno = NULL_SEGNO,
@@ -169,16 +169,10 @@ static int gc_thread_func(void *data)
int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
{
- struct f2fs_gc_kthread *gc_th;
+ struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
dev_t dev = sbi->sb->s_bdev->bd_dev;
int err = 0;
- gc_th = f2fs_kmalloc(sbi, sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
- if (!gc_th) {
- err = -ENOMEM;
- goto out;
- }
-
gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
@@ -186,30 +180,27 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
gc_th->gc_wake = 0;
- sbi->gc_thread = gc_th;
- init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
- init_waitqueue_head(&sbi->gc_thread->fggc_wq);
- sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
+ init_waitqueue_head(&gc_th->gc_wait_queue_head);
+ init_waitqueue_head(&gc_th->fggc_wq);
+ gc_th->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
"f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev));
if (IS_ERR(gc_th->f2fs_gc_task)) {
err = PTR_ERR(gc_th->f2fs_gc_task);
- kfree(gc_th);
- sbi->gc_thread = NULL;
+ gc_th->f2fs_gc_task = NULL;
}
-out:
return err;
}
void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi)
{
- struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
+ struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
- if (!gc_th)
+ if (!gc_th->f2fs_gc_task)
return;
+
kthread_stop(gc_th->f2fs_gc_task);
+ gc_th->f2fs_gc_task = NULL;
wake_up_all(&gc_th->fggc_wq);
- kfree(gc_th);
- sbi->gc_thread = NULL;
}
static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index 47357101b03cd..0ff8138f0174f 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -32,26 +32,6 @@
#define NR_GC_CHECKPOINT_SECS (3) /* data/node/dentry sections */
-struct f2fs_gc_kthread {
- struct task_struct *f2fs_gc_task;
- wait_queue_head_t gc_wait_queue_head;
-
- /* for gc sleep time */
- unsigned int urgent_sleep_time;
- unsigned int min_sleep_time;
- unsigned int max_sleep_time;
- unsigned int no_gc_sleep_time;
-
- /* for changing gc mode */
- unsigned int gc_wake;
-
- /* for GC_MERGE mount option */
- wait_queue_head_t fggc_wq; /*
- * caller of f2fs_balance_fs()
- * will wait on this wait queue.
- */
-};
-
struct gc_inode_list {
struct list_head ilist;
struct radix_tree_root iroot;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index d185b209f89a5..db126347ca057 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -415,15 +415,14 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
f2fs_submit_merged_write(sbi, DATA);
f2fs_submit_all_merged_ipu_writes(sbi);
- if (test_opt(sbi, GC_MERGE) && sbi->gc_thread &&
- sbi->gc_thread->f2fs_gc_task) {
+ if (test_opt(sbi, GC_MERGE) && sbi->gc_thread.f2fs_gc_task) {
DEFINE_WAIT(wait);
- prepare_to_wait(&sbi->gc_thread->fggc_wq, &wait,
+ prepare_to_wait(&sbi->gc_thread.fggc_wq, &wait,
TASK_UNINTERRUPTIBLE);
- wake_up(&sbi->gc_thread->gc_wait_queue_head);
+ wake_up(&sbi->gc_thread.gc_wait_queue_head);
io_schedule();
- finish_wait(&sbi->gc_thread->fggc_wq, &wait);
+ finish_wait(&sbi->gc_thread.fggc_wq, &wait);
} else {
struct f2fs_gc_control gc_control = {
.victim_segno = NULL_SEGNO,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 9d1b5699f5bf1..dc06771fb1e9e 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2393,11 +2393,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
if ((*flags & SB_RDONLY) ||
(F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF &&
!test_opt(sbi, GC_MERGE))) {
- if (sbi->gc_thread) {
+ if (sbi->gc_thread.f2fs_gc_task) {
f2fs_stop_gc_thread(sbi);
need_restart_gc = true;
}
- } else if (!sbi->gc_thread) {
+ } else if (!sbi->gc_thread.f2fs_gc_task) {
err = f2fs_start_gc_thread(sbi);
if (err)
goto restore_opts;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 503a50542ac53..b0607fdd5ad40 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -68,7 +68,7 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
{
if (struct_type == GC_THREAD)
- return (unsigned char *)sbi->gc_thread;
+ return (unsigned char *)&sbi->gc_thread;
else if (struct_type == SM_INFO)
return (unsigned char *)SM_I(sbi);
else if (struct_type == DCC_INFO)
@@ -543,20 +543,20 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
sbi->gc_mode = GC_NORMAL;
} else if (t == 1) {
sbi->gc_mode = GC_URGENT_HIGH;
- if (sbi->gc_thread) {
- sbi->gc_thread->gc_wake = 1;
+ if (sbi->gc_thread.f2fs_gc_task) {
+ sbi->gc_thread.gc_wake = 1;
wake_up_interruptible_all(
- &sbi->gc_thread->gc_wait_queue_head);
+ &sbi->gc_thread.gc_wait_queue_head);
wake_up_discard_thread(sbi, true);
}
} else if (t == 2) {
sbi->gc_mode = GC_URGENT_LOW;
} else if (t == 3) {
sbi->gc_mode = GC_URGENT_MID;
- if (sbi->gc_thread) {
- sbi->gc_thread->gc_wake = 1;
+ if (sbi->gc_thread.f2fs_gc_task) {
+ sbi->gc_thread.gc_wake = 1;
wake_up_interruptible_all(
- &sbi->gc_thread->gc_wait_queue_head);
+ &sbi->gc_thread.gc_wait_queue_head);
}
} else {
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0044/1887] Bluetooth: btqcomsmd: Convert to platform remove callback returning void
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0043/1887] f2fs: embed f2fs_gc_kthread in f2fs_sb_info Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0045/1887] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev Greg Kroah-Hartman
` (954 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit 4a62832f565c950d645a4f7b199a0a7985815940 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Stable-dep-of: f5a427b16e45 ("Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btqcomsmd.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
index 11c7e04bf3947..88dbb2f3fabf9 100644
--- a/drivers/bluetooth/btqcomsmd.c
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -197,7 +197,7 @@ static int btqcomsmd_probe(struct platform_device *pdev)
return ret;
}
-static int btqcomsmd_remove(struct platform_device *pdev)
+static void btqcomsmd_remove(struct platform_device *pdev)
{
struct btqcomsmd *btq = platform_get_drvdata(pdev);
@@ -206,8 +206,6 @@ static int btqcomsmd_remove(struct platform_device *pdev)
rpmsg_destroy_ept(btq->cmd_channel);
rpmsg_destroy_ept(btq->acl_channel);
-
- return 0;
}
static const struct of_device_id btqcomsmd_of_match[] = {
@@ -218,7 +216,7 @@ MODULE_DEVICE_TABLE(of, btqcomsmd_of_match);
static struct platform_driver btqcomsmd_driver = {
.probe = btqcomsmd_probe,
- .remove = btqcomsmd_remove,
+ .remove_new = btqcomsmd_remove,
.driver = {
.name = "btqcomsmd",
.of_match_table = btqcomsmd_of_match,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0045/1887] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0044/1887] Bluetooth: btqcomsmd: Convert to platform remove callback returning void Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0046/1887] genetlink: pin family module during policy dump Greg Kroah-Hartman
` (953 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bartosz Golaszewski,
Dmitry Baryshkov, Xu Rao, Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
[ Upstream commit f5a427b16e45210dee656b0860728f3d496dee85 ]
The command and ACL RPMsg endpoints store struct btqcomsmd as their
callback private data. The receive callbacks dereference btq->hdev
without taking an hci_dev reference.
The current teardown order frees the hci_dev before destroying the RPMsg
endpoints in both the hci_register_dev() error path and the driver remove
path. If WCNSS delivers data in that window, the endpoint callback can
run with an already freed hci_dev and pass it to the Bluetooth core.
For qcom_smd endpoints, rpmsg_destroy_ept() closes the channel and clears
the callback under the channel recv_lock. The receive path holds the same
lock while invoking the callback, so destroying the endpoints first both
prevents new callbacks and serializes with any callback already running.
Destroy the command and ACL endpoints before hci_free_dev(). Keep
hci_unregister_dev() first during remove so the HCI core stops issuing
operations before the transport endpoints are shut down. In the full
registration-error cleanup path, return directly after freeing the hci_dev
to avoid falling through to the partial-construction labels and destroying
the endpoints twice.
Fixes: 5052de8deff5 ("soc: qcom: smd: Transition client drivers from smd to rpmsg")
Fixes: 9a39a927be01 ("Bluetooth: btqcomsmd: Fix a resource leak in error handling paths in the probe function")
Cc: stable@vger.kernel.org
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btqcomsmd.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
index 88dbb2f3fabf9..4ce8354ebb86b 100644
--- a/drivers/bluetooth/btqcomsmd.c
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -188,7 +188,10 @@ static int btqcomsmd_probe(struct platform_device *pdev)
return 0;
hci_free_dev:
+ rpmsg_destroy_ept(btq->cmd_channel);
+ rpmsg_destroy_ept(btq->acl_channel);
hci_free_dev(hdev);
+ return ret;
destroy_cmd_channel:
rpmsg_destroy_ept(btq->cmd_channel);
destroy_acl_channel:
@@ -202,10 +205,11 @@ static void btqcomsmd_remove(struct platform_device *pdev)
struct btqcomsmd *btq = platform_get_drvdata(pdev);
hci_unregister_dev(btq->hdev);
- hci_free_dev(btq->hdev);
rpmsg_destroy_ept(btq->cmd_channel);
rpmsg_destroy_ept(btq->acl_channel);
+
+ hci_free_dev(btq->hdev);
}
static const struct of_device_id btqcomsmd_of_match[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0046/1887] genetlink: pin family module during policy dump
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0045/1887] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0047/1887] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
` (952 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, XingWang Xiang, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: XingWang Xiang <v3rdant.xiang@gmail.com>
[ Upstream commit 6a1094c34d176827b2b173e163dcc964a13af93f ]
The generic netlink controller's policy dump keeps pointers to the target
family's operation and policy tables in its callback state. A dump may be
split across multiple skbs and remain pending after the initial request.
Netlink pins the module which owns the dump callback, but in this case
that is the controller's owner rather than the target family's owner. The
target family can consequently be unregistered and its module unloaded
while a policy dump is pending. Advancing the dump then dereferences
policy memory from the unloaded module.
Take a reference to the target family's module when the dump starts.
Drop it from the error and done paths. This matches the lifetime for which
the dump context retains the family and policy pointers.
Fixes: d07dcf9aadd6 ("netlink: add infrastructure to expose policies to userspace")
Cc: stable@vger.kernel.org
Signed-off-by: XingWang Xiang <v3rdant.xiang@gmail.com>
Link: https://patch.msgid.link/20260902084317.4092542-1-v3rdant.xiang@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted split-operation iterator handling to the older genl_ops and opidx interfaces. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netlink/genetlink.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 3a3b29ff63b31..4ededd793767c 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1159,6 +1159,7 @@ static int genl_ctrl_event(int event, const struct genl_family *family,
struct ctrl_dump_policy_ctx {
struct netlink_policy_dump_state *state;
const struct genl_family *rt;
+ struct module *owner;
unsigned int opidx;
u32 op;
u16 fam_id;
@@ -1202,6 +1203,9 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
return -ENOENT;
ctx->rt = rt;
+ ctx->owner = rt->module;
+ if (!try_module_get(ctx->owner))
+ return -ENOENT;
if (tb[CTRL_ATTR_OP]) {
ctx->single_op = true;
@@ -1210,14 +1214,19 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
err = genl_get_cmd(ctx->op, rt, &op);
if (err) {
NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
- return err;
+ goto err_put_owner;
}
- if (!op.policy)
- return -ENODATA;
+ if (!op.policy) {
+ err = -ENODATA;
+ goto err_put_owner;
+ }
- return netlink_policy_dump_add_policy(&ctx->state, op.policy,
- op.maxattr);
+ err = netlink_policy_dump_add_policy(&ctx->state, op.policy,
+ op.maxattr);
+ if (err)
+ goto err_free_state;
+ return 0;
}
for (i = 0; i < genl_get_cmd_cnt(rt); i++) {
@@ -1232,12 +1241,16 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
}
}
- if (!ctx->state)
- return -ENODATA;
+ if (!ctx->state) {
+ err = -ENODATA;
+ goto err_put_owner;
+ }
return 0;
err_free_state:
netlink_policy_dump_free(ctx->state);
+err_put_owner:
+ module_put(ctx->owner);
return err;
}
@@ -1372,6 +1385,7 @@ static int ctrl_dumppolicy_done(struct netlink_callback *cb)
struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
netlink_policy_dump_free(ctx->state);
+ module_put(ctx->owner);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0047/1887] net: bridge: use option bits for CFM/MRP frame handlers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0046/1887] genetlink: pin family module during policy dump Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0048/1887] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
` (951 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Nikolay Aleksandrov, Yilin Zhu,
Zhiling Zou, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 7a49e6b16f36b8e085521699adbca3e321b6dd0c ]
CFM and MRP register a global br_frame_type whose hlist_node is linked
into the per-bridge frame_type_list when the first MEP/MRP instance is
created. Enabling the protocol on multiple bridges therefore inserts the
same node into multiple lists. Unregistering it on one bridge then
corrupts list state belonging to another.
These handlers can only be installed once per bridge, and they are
uncommon. Track their per-bridge enable state with net_bridge option
bits, which already live on the Rx hot cache line, and dispatch the
matching handler directly from the receive path. Check both bits
together first as an unlikely case.
Remove the generic frame_type_list and br_frame_type helpers, which
have had no other users since CFM and MRP were added. That shrinks
struct net_bridge by 8 bytes and drops the list walk from the fast
path. When neither protocol is compiled in, BR_CFM_MRP_OPTS is 0 and
the compiler prunes the branch.
Fixes: 90c628dd47ff ("net: bridge: extend the process of special frames")
Fixes: dc32cbb3dbd7 ("bridge: cfm: Kernel space implementation of CFM. CCM frame RX added.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Nikolay Aleksandrov <razor@blackwall.org>
Co-developed-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/0345b9d5aa60ba416f6738ff1b87140f0a749cb8.1788417901.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Adjusted bridge option enum context because BROPT_MDB_OFFLOAD_FAIL_NOTIFICATION and BROPT_FDB_LOCAL_VLAN_0 are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/br_cfm.c | 11 +++--------
net/bridge/br_device.c | 1 -
net/bridge/br_input.c | 35 ++++++++++++++---------------------
net/bridge/br_mrp.c | 13 +++----------
net/bridge/br_private.h | 26 +++++++++++++++-----------
5 files changed, 35 insertions(+), 51 deletions(-)
diff --git a/net/bridge/br_cfm.c b/net/bridge/br_cfm.c
index a89aec8314164..b9a3546fb4b44 100644
--- a/net/bridge/br_cfm.c
+++ b/net/bridge/br_cfm.c
@@ -367,7 +367,7 @@ static u32 ccm_tlv_extract(struct sk_buff *skb, u32 index,
}
/* note: already called with rcu_read_lock */
-static int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
{
u32 mdlevel, interval, size, index, max;
const struct br_cfm_common_hdr *hdr;
@@ -489,11 +489,6 @@ static int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
return 1;
}
-static struct br_frame_type cfm_frame_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_CFM),
- .frame_handler = br_cfm_frame_rx,
-};
-
int br_cfm_mep_create(struct net_bridge *br,
const u32 instance,
struct br_cfm_mep_create *const create,
@@ -559,7 +554,7 @@ int br_cfm_mep_create(struct net_bridge *br,
INIT_DELAYED_WORK(&mep->ccm_tx_dwork, ccm_tx_work_expired);
if (hlist_empty(&br->mep_list))
- br_add_frame(br, &cfm_frame_type);
+ br_opt_toggle(br, BROPT_CFM_ENABLED, true);
hlist_add_tail_rcu(&mep->head, &br->mep_list);
@@ -588,7 +583,7 @@ static void mep_delete_implementation(struct net_bridge *br,
kfree_rcu(mep, rcu);
if (hlist_empty(&br->mep_list))
- br_del_frame(br, &cfm_frame_type);
+ br_opt_toggle(br, BROPT_CFM_ENABLED, false);
}
int br_cfm_mep_delete(struct net_bridge *br,
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 052986e05e620..9966a3e093232 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -508,7 +508,6 @@ void br_dev_setup(struct net_device *dev)
spin_lock_init(&br->lock);
INIT_LIST_HEAD(&br->port_list);
INIT_HLIST_HEAD(&br->fdb_list);
- INIT_HLIST_HEAD(&br->frame_type_list);
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
INIT_HLIST_HEAD(&br->mrp_list);
#endif
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index aca6db6f95355..bfc7de46a7054 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -286,17 +286,25 @@ static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb)
return RX_HANDLER_CONSUMED;
}
+#define BR_CFM_MRP_OPTS \
+ ((IS_ENABLED(CONFIG_BRIDGE_CFM) ? BIT(BROPT_CFM_ENABLED) : 0UL) | \
+ (IS_ENABLED(CONFIG_BRIDGE_MRP) ? BIT(BROPT_MRP_ENABLED) : 0UL))
+
/* Return 0 if the frame was not processed otherwise 1
* note: already called with rcu_read_lock
*/
static int br_process_frame_type(struct net_bridge_port *p,
struct sk_buff *skb)
{
- struct br_frame_type *tmp;
+ struct net_bridge *br = p->br;
+
+ if (skb->protocol == htons(ETH_P_CFM) &&
+ br_opt_get(br, BROPT_CFM_ENABLED))
+ return br_cfm_frame_rx(p, skb);
- hlist_for_each_entry_rcu(tmp, &p->br->frame_type_list, list)
- if (unlikely(tmp->type == skb->protocol))
- return tmp->frame_handler(p, skb);
+ if (skb->protocol == htons(ETH_P_MRP) &&
+ br_opt_get(br, BROPT_MRP_ENABLED))
+ return br_mrp_process(p, skb);
return 0;
}
@@ -389,7 +397,8 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
}
}
- if (unlikely(br_process_frame_type(p, skb)))
+ if (unlikely((READ_ONCE(p->br->options) & BR_CFM_MRP_OPTS) &&
+ br_process_frame_type(p, skb)))
return RX_HANDLER_PASS;
forward:
@@ -430,19 +439,3 @@ rx_handler_func_t *br_get_rx_handler(const struct net_device *dev)
return br_handle_frame;
}
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
- hlist_add_head_rcu(&ft->list, &br->frame_type_list);
-}
-
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
- struct br_frame_type *tmp;
-
- hlist_for_each_entry(tmp, &br->frame_type_list, list)
- if (ft == tmp) {
- hlist_del_rcu(&ft->list);
- return;
- }
-}
diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c
index a837ff7d6f36d..79d6bc62179e2 100644
--- a/net/bridge/br_mrp.c
+++ b/net/bridge/br_mrp.c
@@ -6,13 +6,6 @@
static const u8 mrp_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x1 };
static const u8 mrp_in_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x3 };
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
-
-static struct br_frame_type mrp_frame_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_MRP),
- .frame_handler = br_mrp_process,
-};
-
static bool br_mrp_is_ring_port(struct net_bridge_port *p_port,
struct net_bridge_port *s_port,
struct net_bridge_port *port)
@@ -486,7 +479,7 @@ static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp)
kfree_rcu(mrp, rcu);
if (hlist_empty(&br->mrp_list))
- br_del_frame(br, &mrp_frame_type);
+ br_opt_toggle(br, BROPT_MRP_ENABLED, false);
}
/* Adds a new MRP instance.
@@ -536,7 +529,7 @@ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance)
rcu_assign_pointer(mrp->s_port, p);
if (hlist_empty(&br->mrp_list))
- br_add_frame(br, &mrp_frame_type);
+ br_opt_toggle(br, BROPT_MRP_ENABLED, true);
INIT_DELAYED_WORK(&mrp->test_work, br_mrp_test_work_expired);
INIT_DELAYED_WORK(&mrp->in_test_work, br_mrp_in_test_work_expired);
@@ -1241,7 +1234,7 @@ static int br_mrp_rcv(struct net_bridge_port *p,
* normal forwarding.
* note: already called with rcu_read_lock
*/
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
{
/* If there is no MRP instance do normal forwarding */
if (likely(!(p->flags & BR_MRP_AWARE)))
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 617e636a8a4c2..8c0912283df79 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -459,12 +459,13 @@ enum net_bridge_opts {
BROPT_VLAN_BRIDGE_BINDING,
BROPT_MCAST_VLAN_SNOOPING_ENABLED,
BROPT_MST_ENABLED,
+ BROPT_CFM_ENABLED,
+ BROPT_MRP_ENABLED,
};
struct net_bridge {
spinlock_t lock;
spinlock_t hash_lock;
- struct hlist_head frame_type_list;
struct net_device *dev;
unsigned long options;
/* These fields are accessed on each packet */
@@ -861,16 +862,6 @@ int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
rx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
-struct br_frame_type {
- __be16 type;
- int (*frame_handler)(struct net_bridge_port *port,
- struct sk_buff *skb);
- struct hlist_node list;
-};
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
-
static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
{
return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
@@ -1931,6 +1922,7 @@ int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
bool br_mrp_enabled(struct net_bridge *br);
void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
#else
static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd,
@@ -1954,6 +1946,11 @@ static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
return 0;
}
+static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+{
+ return 0;
+}
+
#endif
/* br_cfm.c */
@@ -1962,6 +1959,7 @@ int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
bool br_cfm_created(struct net_bridge *br);
void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb);
int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
int br_cfm_status_fill_info(struct sk_buff *skb,
struct net_bridge *br,
@@ -1986,6 +1984,12 @@ static inline void br_cfm_port_del(struct net_bridge *br,
{
}
+static inline int br_cfm_frame_rx(struct net_bridge_port *port,
+ struct sk_buff *skb)
+{
+ return 0;
+}
+
static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
{
return -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0048/1887] landlock: Fix use-after-free of the sources parent directory
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0047/1887] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0049/1887] smb: client: fix heap overflow in DACL owner/group rewrite Greg Kroah-Hartman
` (950 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Günther Noack,
Mickaël Salaün, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
[ Upstream commit 2c6dc792538260a8087ac5b22c31b3b8e47c85d6 ]
current_check_refer_path() reads old_dentry->d_parent without holding a
reference nor a lock on it, and then dereferences it in
collect_domain_accesses() and in the audit record.
A reference on a child does not pin its parent: __d_move() reassigns
dentry->d_parent and drops the reference the child held on its former
parent. hook_path_rename() is not affected because the rename path
calls lock_rename() before the hook, so the source cannot be reparented
under it. hook_path_link() has no such protection: filename_linkat()
holds a reference on the source dentry but neither locks nor references
its parent, so a concurrent rename(2) can reparent the source while
security_path_link() runs, and the former parent can then be removed and
freed while the hook walks it.
A process can trigger this after entering a Landlock domain that handles
at least one filesystem access right. The process can then race a
linkat(2) loop against rename(2) and rmdir(2):
BUG: KASAN: slab-use-after-free in collect_domain_accesses+0x278/0x290
Read of size 4 at addr ffff888160bd53f4 by task llrepro2/549
collect_domain_accesses+0x278/0x290
current_check_refer_path+0x952/0x1120
security_path_link+0x1be/0x320
filename_linkat+0x342/0x6d0
__x64_sys_linkat+0xfa/0x150
Freed by task 562:
kmem_cache_free+0x139/0x4c0
i_callback+0x4b/0x80
rcu_core+0x7dc/0x10a0
Take a reference on the dentry selected as the source parent, using
dget() for the common-mount-root case and dget_parent() otherwise.
Release it after the hierarchy walk and synchronous audit logging.
Cc: stable@vger.kernel.org
Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Tested-by: Günther Noack <gnoack3000@gmail.com>
Link: https://patch.msgid.link/E9CDD9E6-E960-4DE2-B1AC-5667D52ABB3E@doyensec.com
[mic: Clarify the caller, reachability, and reference handling]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[ consolidated dput(old_parent) into one release after the hierarchy walks because the older branch lacks audit logging. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/landlock/fs.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 8f20a146648cf..4e03da721e633 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -911,17 +911,19 @@ static int current_check_refer_path(struct dentry *const old_dentry,
/*
* old_dentry may be the root of the common mount point and
* !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
- * OPEN_TREE_CLONE). We do not need to call dget(old_parent) because
- * we keep a reference to old_dentry.
+ * OPEN_TREE_CLONE). Pin the dentry used as old_parent in either case.
+ * Otherwise, dget_parent() safely fetches and pins the current parent
+ * against a concurrent rename(2).
*/
- old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
- old_dentry->d_parent;
+ old_parent = (old_dentry == mnt_dir.dentry) ? dget(old_dentry) :
+ dget_parent(old_dentry);
/* new_dir->dentry is equal to new_dentry->d_parent */
allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry, old_parent,
&layer_masks_parent1);
allow_parent2 = collect_domain_accesses(
dom, mnt_dir.dentry, new_dir->dentry, &layer_masks_parent2);
+ dput(old_parent);
if (allow_parent1 && allow_parent2)
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0049/1887] smb: client: fix heap overflow in DACL owner/group rewrite
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0048/1887] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0050/1887] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling Greg Kroah-Hartman
` (949 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bjoern Doebel, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <doebel@amazon.de>
[ Upstream commit 0ee150794c75bcd0be0e24ff3394f433cbae18cc ]
When id_mode_to_cifs_acl rewrites an existing DACL, it allocates a
buffer sized according to the on-disk DACL length reported by
dacl_ptr->size. However, replace_sids_and_copy_aces may rewrite each
ACE with a new owner/group SID obtained from the cifs.idmap upcall.
Those SIDs can have up to SID_MAX_SUB_AUTHORITIES (15) sub-authorities,
making each ACE up to 76 bytes (sizeof(struct smb_ace)).
If the original DACL contains short SIDs (e.g., 1 sub-authority) while
the replacement SIDs are long, the rewritten ACEs overflow the
allocation.
Fix this by always budgeting for worst-case SID expansion: allocate
sizeof(struct smb_acl) plus num_aces * sizeof(struct smb_ace), which
covers the smb_acl header and room for every ACE at maximum SID size.
This replaces the previous split logic that used dacl_ptr->size for
cifsacl mounts but num_aces * sizeof(struct smb_ace) for mode_from_sid
mounts: both paths can trigger the same rewrite and need the same
headroom.
KASAN reports this as:
BUG: KASAN: slab-out-of-bounds in build_sec_desc+0x1e8a/0x2680 [cifs]
Write of size 4 at addr ffff8881a5e25374 by task chown/5298
...
The buggy address is located 0 bytes to the right of
allocated 884-byte region [ffff8881a5e25000, ffff8881a5e25374)
Cc: stable@vger.kernel.org
Fixes: bc3e9dd9d104 ("cifs: Change SIDs in ACEs while transferring file ownership.")
Assisted-by: Kiro:claude-opus-4.6
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Fixes: 5c3564852c58 ("cifs: Minimize the number of cifs_acl memory allocations")
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ changed smb_acl/smb_ace to cifs_acl/cifs_ace and le16_to_cpu() to le32_to_cpu() for the branch’s 32-bit num_aces field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsacl.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
index 93e3f0bcecace..39179e639b943 100644
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1751,11 +1751,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
cifs_put_tlink(tlink);
return rc;
}
- if (mode_from_sid)
- nsecdesclen +=
- le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
- else /* cifsacl */
- nsecdesclen += le16_to_cpu(dacl_ptr->size);
+ /*
+ * Worst case: every ACE is rewritten with a new SID of
+ * SID_MAX_SUB_AUTHORITIES sub-auths -> sizeof(cifs_ace) each,
+ * plus the cifs_acl header replace_sids_and_copy_aces() emits.
+ */
+ nsecdesclen += sizeof(struct cifs_acl) +
+ le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0050/1887] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0049/1887] smb: client: fix heap overflow in DACL owner/group rewrite Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0051/1887] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity Greg Kroah-Hartman
` (948 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 36adb51ac0b19edb32ffeea3fe66b174bad25ead ]
We did manual copies over loop for the packet data update of the
implicit feedback, but this can be optimized with a simple memcpy().
Along with it, change the data type of snd_usb_packet_info struct to
align with other (from uint32_t to int).
No functional changes but only code optimizations.
Link: https://patch.msgid.link/20260216141209.1849200-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 76a986c980bb ("ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/card.h | 2 +-
sound/usb/endpoint.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 6ec95b2edf863..ac5505ce046de 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -89,7 +89,7 @@ struct snd_usb_endpoint {
struct snd_urb_ctx urb[MAX_URBS];
struct snd_usb_packet_info {
- uint32_t packet_size[MAX_PACKS_HS];
+ int packet_size[MAX_PACKS_HS];
int packets;
} next_packet[MAX_URBS];
unsigned int next_packet_head; /* ring buffer offset to read */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 778466624f030..6cde8455da37b 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -478,7 +478,7 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
unsigned long flags;
struct snd_usb_packet_info *packet;
struct snd_urb_ctx *ctx = NULL;
- int err, i;
+ int err;
spin_lock_irqsave(&ep->lock, flags);
if ((!implicit_fb || ep->next_packet_queued > 0) &&
@@ -498,8 +498,8 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
/* copy over the length information */
if (implicit_fb) {
ctx->packets = packet->packets;
- for (i = 0; i < packet->packets; i++)
- ctx->packet_size[i] = packet->packet_size[i];
+ memcpy(ctx->packet_size, packet->packet_size,
+ packet->packets * sizeof(packet->packet_size[0]));
}
/* call the data handler to fill in playback data */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0051/1887] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0050/1887] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0052/1887] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
` (947 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+8eacd4fa193b1b28, Xiang Mei,
Takashi Iwai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <xmei5@asu.edu>
[ Upstream commit 76a986c980bb502c7688d605ac7a67fd257a9a1b ]
data_ep_set_params() allocates each data URB for exactly u->packets
isochronous frames, so urb->iso_frame_desc[] has u->packets slots and
ctx->packets is the driver's only record of that limit. For an implicit
feedback sink, snd_usb_queue_pending_output_urbs() overwrites it with the
sync source's packet count, which is calculated independently from the
capture endpoint's parameters. When that count is larger,
prepare_playback_urb() and prepare_silent_urb() can write
iso_frame_desc[] past the allocation; their existing bounds limit payload
bytes, not the descriptor index.
The reproducer uses a high-speed UAC2 device declaring bInterval 1 for
implicit feedback capture (8 packets) and bInterval 4 for playback
(1 packet). On the first capture completion after the stream starts, it
accesses seven descriptors spanning 112 bytes beyond the one-packet URB:
BUG: KASAN: slab-out-of-bounds in prepare_playback_urb (sound/usb/pcm.c:1560)
Write of size 4 at addr ffff88801e696ad0 by task vhci_rx/178
prepare_playback_urb (sound/usb/pcm.c:1560)
prepare_outbound_urb (sound/usb/endpoint.c:340)
snd_usb_queue_pending_output_urbs (sound/usb/endpoint.c:501)
snd_complete_urb (sound/usb/endpoint.c:1834)
__usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1741)
vhci_rx_loop (drivers/usb/usbip/vhci_rx.c:107)
kthread (kernel/kthread.c:436)
The buggy address belongs to the object at ffff88801e696a00
which belongs to the cache kmalloc-256 of size 256
The buggy address is located 0 bytes to the right of
allocated 208-byte region [ffff88801e696a00, ffff88801e696ad0)
Record the allocated packet count per endpoint and clamp both the adopted
count and the packet-size copy to it. Fold the Format Type II delimiter
into urb_packs before the allocation loop so the recorded limit matches
every URB.
Fixes: cf044e441902 ("ALSA: usb-audio: Update the number of packets properly at receiving")
Reported-by: co+8eacd4fa193b1b28@bugs.sh
Closes: https://lore.kernel.org/all/22xPn8drvIUtYgVeQnBiNqXuevOTpBAjepLz%40bugs.sh/
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260912200530.1955491-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/card.h | 1 +
sound/usb/endpoint.c | 12 +++++++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ac5505ce046de..0d860c57d9d9d 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -115,6 +115,7 @@ struct snd_usb_endpoint {
unsigned int phase; /* phase accumulator */
unsigned int maxpacksize; /* max packet size in bytes */
unsigned int maxframesize; /* max packet size in frames */
+ unsigned int max_urb_packs; /* packets allocated per data URB */
unsigned int max_urb_frames; /* max URB size in frames */
unsigned int curpacksize; /* current packet size in bytes (for capture) */
unsigned int curframesize; /* current packet size in frames (for capture) */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 6cde8455da37b..dd81c94cbb520 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -497,9 +497,10 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
/* copy over the length information */
if (implicit_fb) {
- ctx->packets = packet->packets;
+ ctx->packets = min_t(int, packet->packets,
+ ep->max_urb_packs);
memcpy(ctx->packet_size, packet->packet_size,
- packet->packets * sizeof(packet->packet_size[0]));
+ ctx->packets * sizeof(packet->packet_size[0]));
}
/* call the data handler to fill in playback data */
@@ -1252,15 +1253,16 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep)
ep->nurbs = min(max_urbs, urbs_per_period * ep->cur_buffer_periods);
}
+ if (fmt->fmt_type == UAC_FORMAT_TYPE_II)
+ urb_packs++; /* for transfer delimiter */
+ ep->max_urb_packs = urb_packs;
+
/* allocate and initialize data urbs */
for (i = 0; i < ep->nurbs; i++) {
struct snd_urb_ctx *u = &ep->urb[i];
u->index = i;
u->ep = ep;
u->packets = urb_packs;
-
- if (fmt->fmt_type == UAC_FORMAT_TYPE_II)
- u->packets++; /* for transfer delimiter */
u->buffer_size = maxsize * u->packets;
u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
if (!u->urb)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0052/1887] exec: Cleanup POSIX timers right after de_thread()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0051/1887] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0053/1887] wifi: libipw: reject TKIP frames without a full MIC Greg Kroah-Hartman
` (946 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Thomas Gleixner,
Kijo Park, Oleg Nesterov, Frederic Weisbecker, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <imv4bel@gmail.com>
[ Upstream commit acb03d3881818581052924a9bbbe92b8741ed448 ]
A per-thread CPU timer holds a reference to the PID of the thread it is
attached to and, while it is armed, its node is queued in that thread's
posix_cputimers. The task is looked up by that PID.
When a non-leader thread exec()s, de_thread() changes which task owns
that PID. pid_task(timer->it.cpu.pid, PIDTYPE_PID) then returns NULL,
but the node is still queued on tsk, which is alive. timer_lock_sighand()
takes a failed lookup to mean that the node is already dequeued, so it
has nothing to undo.
begin_new_exec() calls posix_cpu_timers_exit(me) right after
exec_task_namespaces() and that removes the leftover node, so the state
normally stays invisible. But bprm->point_of_no_return is set before
de_thread(), so if unshare_files(), set_mm_exe_file(), exec_mmap() or
exec_task_namespaces() fails, the task dies before it gets there.
exit_itimers() then frees the k_itimer while its node is still queued,
and reaping tsk later erases that freed node from the rbtree.
In short:
the non-leader thread B the parent
timer_create(CLOCK_THREAD_CPUTIME_ID)
timer_settime()
arm_timer() // the node is queued on B
execve()
de_thread(B)
exchange_tids(B, leader) // B's PID now belongs to the leader
release_task(leader)
__exit_signal(leader)
posix_cpu_timers_exit(leader) // cleans leader's queue, not B's
__unhash_process(leader) // that PID has no task anymore
exec_mmap()
mmap_read_lock_killable(old_mm)
kill(B, SIGKILL)
// -EINTR
get_signal()
do_exit()
exit_itimers()
posix_timer_delete()
posix_cpu_timer_del()
posix_timer_unhash_and_free() // freed while still queued
wait4()
release_task(B)
posix_cpu_timers_exit(B)
cleanup_timerqueue()
timerqueue_del() // use-after-free
Move the POSIX timer cleanup right after de_thread() before any of the
later failure conditions brings the task into do_exit().
[ tglx: Move the cleanup right after de_thread() ]
Fixes: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Kijo Park <red993688@gmail.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/ao7Q8miiuLAPVnWv@v4bel
Link: https://patch.msgid.link/20260911090541.627712075@kernel.org
[ kept timer cleanup inline instead of introducing upstream’s posixtimer_exec() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/exec.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index 6ff6367793b9e..7391ec00a1cc1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1268,6 +1268,21 @@ int begin_new_exec(struct linux_binprm * bprm)
if (retval)
goto out;
+ /*
+ * This must be done here to ensure that POSIX CPU timers which were
+ * armed on the current task are dequeued from me::posix_cputimers.
+ * Otherwise in case of a TID switch the deletion of the related POSIX
+ * timer would not remove an enqueued timer because the TID lookup
+ * of the old TID fails.
+ */
+#ifdef CONFIG_POSIX_TIMERS
+ spin_lock_irq(&me->sighand->siglock);
+ posix_cpu_timers_exit(me);
+ spin_unlock_irq(&me->sighand->siglock);
+ exit_itimers(me);
+ flush_itimer_signals();
+#endif
+
/*
* Cancel any io_uring activity across execve
*/
@@ -1316,14 +1331,6 @@ int begin_new_exec(struct linux_binprm * bprm)
bprm->mm = NULL;
-#ifdef CONFIG_POSIX_TIMERS
- spin_lock_irq(&me->sighand->siglock);
- posix_cpu_timers_exit(me);
- spin_unlock_irq(&me->sighand->siglock);
- exit_itimers(me);
- flush_itimer_signals();
-#endif
-
/*
* Make the signal table private.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0053/1887] wifi: libipw: reject TKIP frames without a full MIC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0052/1887] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0054/1887] smb: client: fix use-after-free of iface in cifs_try_adding_channels() Greg Kroah-Hartman
` (945 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit 06f42accaf3c6aecab1dcc57f68dde6c06c8b380 ]
libipw_michael_mic_verify() assumes that an skb contains an eight-byte
Michael MIC. A short TKIP frame makes the unsigned payload length wrap,
causing michael_mic() to read past the skb.
Check that the MIC is present before verifying it, and use the existing
MICHAEL_MIC_LEN constant for all MIC lengths in the verifier.
Fixes: b453872c35cf ("[NET] ieee80211 subsystem")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20260909061124.3802517-1-4ncienth@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ adapted libipw changes to the older lib80211 implementation and Michael MIC helper interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/lib80211_crypt_tkip.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index 1b4d6c87a5c5d..823274728711a 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -38,6 +38,7 @@ MODULE_DESCRIPTION("lib80211 crypt: TKIP");
MODULE_LICENSE("GPL");
#define TKIP_HDR_LEN 8
+#define MICHAEL_MIC_LEN 8
struct lib80211_tkip_data {
#define TKIP_KEY_LEN 32
@@ -585,16 +586,18 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
int hdr_len, void *priv)
{
struct lib80211_tkip_data *tkey = priv;
- u8 mic[8];
+ u8 mic[MICHAEL_MIC_LEN];
- if (!tkey->key_set)
+ if (!tkey->key_set || skb->len < hdr_len + MICHAEL_MIC_LEN)
return -1;
michael_mic_hdr(skb, tkey->rx_hdr);
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+ skb->data + hdr_len,
+ skb->len - MICHAEL_MIC_LEN - hdr_len, mic))
return -1;
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
+ if (memcmp(mic, skb->data + skb->len - MICHAEL_MIC_LEN,
+ MICHAEL_MIC_LEN) != 0) {
struct ieee80211_hdr *hdr;
hdr = (struct ieee80211_hdr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
@@ -612,7 +615,7 @@ static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
tkey->rx_iv32 = tkey->rx_iv32_new;
tkey->rx_iv16 = tkey->rx_iv16_new;
- skb_trim(skb, skb->len - 8);
+ skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0054/1887] smb: client: fix use-after-free of iface in cifs_try_adding_channels()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0053/1887] wifi: libipw: reject TKIP frames without a full MIC Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0055/1887] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs() Greg Kroah-Hartman
` (944 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Shyam Prasad N,
Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit d034e836eefd7ce75e588f7031cffbeec594f5ac ]
cifs_try_adding_channels() iterates ses->iface_list with
list_for_each_entry_safe_from(), which captures the next entry
(niface) under iface_lock. The loop body then drops iface_lock for
the whole duration of cifs_ses_add_channel().
A concurrent interface refresh (SMB3_request_interfaces() ->
parse_server_interfaces()) marks all ifaces inactive and removes and
frees any that are not re-advertised via list_del() + kref_put(),
where release_iface() is a bare kfree(). Since niface typically has
no channel holding a reference, the list reference is its last and it
can be freed inside the unlocked window. On continue, the iterator
advance step then dereferences niface->iface_head.next, and the loop
body reads iface->rdma_capable/is_active, both on freed memory.
Fix this by never keeping an unreferenced list pointer across the
unlocked window. Each channel attempt now re-scans the list from the
head under iface_lock, takes a kref on the selected candidate, and
passes only that referenced candidate to cifs_ses_add_channel().
weight_fulfilled still tracks selection progress, so restarting the
scan preserves the original weighted distribution and the
weight_fulfilled-before-kref_put ordering on the failure path.
Add a per-pass attempts cap so a flapping interface refresh cannot
keep the inner loop spinning within a single tries increment.
Fixes: aa45dadd34e4 ("cifs: change iface_list from array to sorted linked list")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Acked-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ adapted calls to retain the cifs_sb argument and use cifs_dbg(VFS, ...) instead of cifs_info(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/sess.c | 106 ++++++++++++++++++++++++++-----------------
1 file changed, 64 insertions(+), 42 deletions(-)
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index ffeb3e7d34d5c..1f1043e47c5cf 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -163,9 +163,9 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
int old_chan_count, new_chan_count;
int left;
int rc = 0;
- int tries = 0;
+ int tries = 0, attempts;
size_t iface_weight = 0, iface_min_speed = 0;
- struct cifs_server_iface *iface = NULL, *niface = NULL;
+ struct cifs_server_iface *iface = NULL, *candidate = NULL;
struct cifs_server_iface *last_iface = NULL;
spin_lock(&ses->chan_lock);
@@ -211,67 +211,89 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
break;
}
- if (!iface)
- iface = list_first_entry(&ses->iface_list, struct cifs_server_iface,
- iface_head);
last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
iface_head);
iface_min_speed = last_iface->speed;
+ spin_unlock(&ses->iface_lock);
- list_for_each_entry_safe_from(iface, niface, &ses->iface_list,
- iface_head) {
- /* do not mix rdma and non-rdma interfaces */
- if (iface->rdma_capable != ses->server->rdma)
- continue;
-
- /* skip ifaces that are unusable */
- if (!iface->is_active ||
- (is_ses_using_iface(ses, iface) &&
- !iface->rss_capable))
- continue;
+ attempts = 0;
+ while (left > 0) {
+ spin_lock(&ses->iface_lock);
- /* check if we already allocated enough channels */
- iface_weight = iface->speed / iface_min_speed;
+ /*
+ * iface_lock must be dropped while opening a channel,
+ * and a concurrent interface refresh may remove and
+ * free entries during that window, so no list entry
+ * may be kept across it without a reference. Scan
+ * the list from the beginning each time and only pass
+ * a referenced candidate to cifs_ses_add_channel();
+ * weight_fulfilled tracks the progress so that no
+ * iface is selected beyond its weight.
+ */
+ candidate = NULL;
+ list_for_each_entry(iface, &ses->iface_list, iface_head) {
+ /* do not mix rdma and non-rdma interfaces */
+ if (iface->rdma_capable != ses->server->rdma)
+ continue;
+
+ /* skip ifaces that are unusable */
+ if (!iface->is_active ||
+ (is_ses_using_iface(ses, iface) &&
+ !iface->rss_capable))
+ continue;
+
+ /* check if we already allocated enough channels */
+ iface_weight = iface->speed / iface_min_speed;
+
+ if (iface->weight_fulfilled >= iface_weight)
+ continue;
+
+ /* take ref before unlock */
+ kref_get(&iface->refcount);
+ candidate = iface;
+ break;
+ }
- if (iface->weight_fulfilled >= iface_weight)
- continue;
+ if (!candidate) {
+ /* no usable iface. reset weight_fulfilled and start over */
+ list_for_each_entry(iface, &ses->iface_list, iface_head)
+ iface->weight_fulfilled = 0;
+ spin_unlock(&ses->iface_lock);
+ break;
+ }
- /* take ref before unlock */
- kref_get(&iface->refcount);
+ attempts++;
+ if (attempts > 3 * ses->chan_max) {
+ kref_put(&candidate->refcount, release_iface);
+ spin_unlock(&ses->iface_lock);
+ break;
+ }
spin_unlock(&ses->iface_lock);
- rc = cifs_ses_add_channel(cifs_sb, ses, iface);
+ rc = cifs_ses_add_channel(cifs_sb, ses, candidate);
spin_lock(&ses->iface_lock);
if (rc) {
cifs_dbg(VFS, "failed to open extra channel on iface:%pIS rc=%d\n",
- &iface->sockaddr,
+ &candidate->sockaddr,
rc);
/* failure to add chan should increase weight */
- iface->weight_fulfilled++;
- kref_put(&iface->refcount, release_iface);
+ candidate->weight_fulfilled++;
+ kref_put(&candidate->refcount, release_iface);
+ spin_unlock(&ses->iface_lock);
continue;
}
- iface->num_channels++;
- iface->weight_fulfilled++;
+ candidate->num_channels++;
+ candidate->weight_fulfilled++;
cifs_dbg(VFS, "successfully opened new channel on iface:%pIS\n",
- &iface->sockaddr);
- break;
- }
-
- /* reached end of list. reset weight_fulfilled and start over */
- if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
- list_for_each_entry(iface, &ses->iface_list, iface_head)
- iface->weight_fulfilled = 0;
+ &candidate->sockaddr);
spin_unlock(&ses->iface_lock);
- iface = NULL;
- continue;
- }
- spin_unlock(&ses->iface_lock);
- left--;
- new_chan_count++;
+ left--;
+ new_chan_count++;
+ break;
+ }
}
return new_chan_count - old_chan_count;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0055/1887] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0054/1887] smb: client: fix use-after-free of iface in cifs_try_adding_channels() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0056/1887] vlan: require the MAC header to be present in __vlan_insert_inner_tag() Greg Kroah-Hartman
` (943 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
[ Upstream commit eeb5ef6083e1cefa2ef75041b5597ff228b8d7bb ]
In move_smb2_ea_to_cifs(), the while (src_size > 0) loop condition is
insufficient. It allows iteration to continue even if the remaining
src_size is too small to contain a complete smb2_ea_info structure.
Consequently, reads of ea_name_length and ea_value_length can occur
out-of-bounds.
Fix this by ensuring src_size >= sizeof(*src) before attempting to read
any structure fields. Additionally, reject any next_entry_offset that is
smaller than sizeof(*src) or that would advance the pointer beyond the
available buffer.
Note that for calls where the server returns a malformed EA list, the
error returned to userspace changes from -ENODATA (getxattr) or
-ERANGE (listxattr) to -EIO. This correctly signals a server protocol
error rather than misleadingly indicating "attribute not present" or
"output buffer too small".
Fixes: 95907fea4fd8 ("cifs: Add support for reading attributes on SMB2+")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Replaced unavailable smb_EIO2() tracing calls with -EIO. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 3de0f2f385b58..07e003163d66b 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -1005,8 +1005,9 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
char *name, *value;
size_t buf_size = dst_size;
size_t name_len, value_len, user_name_len;
+ u32 next_off;
- while (src_size > 0) {
+ while (src_size >= sizeof(*src)) {
name_len = (size_t)src->ea_name_length;
value_len = (size_t)le16_to_cpu(src->ea_value_length);
@@ -1061,14 +1062,21 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
if (!src->next_entry_offset)
break;
- if (src_size < le32_to_cpu(src->next_entry_offset)) {
- /* stop before overrun buffer */
- rc = -ERANGE;
- break;
+ next_off = le32_to_cpu(src->next_entry_offset);
+ if (next_off < sizeof(*src) || src_size < next_off) {
+ cifs_dbg(FYI, "EA next_entry_offset %u out of range [%zu, %zu]\n",
+ next_off, sizeof(*src), src_size);
+ rc = -EIO;
+ goto out;
+ }
+ src_size -= next_off;
+ src = (void *)((char *)src + next_off);
+ if (src_size > 0 && src_size < sizeof(*src)) {
+ cifs_dbg(FYI, "EA next_entry_offset %u left truncated entry (%zu bytes)\n",
+ next_off, src_size);
+ rc = -EIO;
+ goto out;
}
- src_size -= le32_to_cpu(src->next_entry_offset);
- src = (void *)((char *)src +
- le32_to_cpu(src->next_entry_offset));
}
/* didn't find the named attribute */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0056/1887] vlan: require the MAC header to be present in __vlan_insert_inner_tag()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0055/1887] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0057/1887] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
` (942 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+0ea1ac045375cf05, Xiang Mei,
Simon Horman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <xmei5@asu.edu>
[ Upstream commit ab888242fce4f16f6c4d4c6ec53939ad36aa3b3a ]
__vlan_insert_inner_tag() only guarantees head room via skb_cow_head(),
never that mac_len bytes of MAC header are present. Its ETH_HLEN
wrappers - __vlan_insert_tag() under skb_vlan_push(), and
vlan_insert_tag() under validate_xmit_vlan() on the generic transmit
path - therefore rewrite the first 16 bytes at skb->data: a 12-byte
memmove plus two 2-byte stores at +12 and +14. No caller supplies the
bound, while the pop helpers use skb_ensure_writable()/pskb_may_pull().
An IFF_TUN device has hard_header_len == 0, so packet_snd() accepts a
one-byte AF_PACKET/SOCK_RAW frame. The first vlan push only sets a
hwaccel tag; the next - clsact "action vlan push" or
bpf_skb_vlan_push() - enters the helper with skb->len still 1. The
head comes from skbuff_small_head without __GFP_ZERO, so each push
drags bytes from beyond skb->tail into the frame. After three the
one-byte send leaves as 13 bytes carrying 11 bytes of uninitialised
slab:
0000: 5a b3 62 12 80 88 ff ff 00 b3 62 12 81
`------------------------------'
only 0x5a was sent; the rest is slab, here the top 56 bits of a
linear-map address
Require the MAC header the helper rewrites to be present, so such a
frame is dropped rather than transmitted.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: co+0ea1ac045375cf05@bugs.sh
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915083152.705309-1-xmei5@asu.edu
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adjusted context around skb_cow_head(skb, VLAN_HLEN) because the branch lacks upstream meta_len handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/if_vlan.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index f4eb8dd7308a2..e63081a9d7db8 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -351,6 +351,9 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
{
struct vlan_ethhdr *veth;
+ if (unlikely(!pskb_may_pull(skb, mac_len)))
+ return -EINVAL;
+
if (skb_cow_head(skb, VLAN_HLEN) < 0)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0057/1887] pinctrl: sunxi: keep a shadow copy of the data register output latches
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0056/1887] vlan: require the MAC header to be present in __vlan_insert_inner_tag() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0058/1887] perf tools: Fix a asan issue in parse_events_multi_pmu_add() Greg Kroah-Hartman
` (941 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ilya Titov, Linus Walleij,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Titov <ilya.titov@wirenboard.com>
[ Upstream commit a13f7f5d14af9baf34eb12c25962f8d3542b281d ]
On Allwinner SoCs, reading a bank's data register returns the pin level,
not the output latch, for pins that are muxed as inputs. Writing a GPIO
therefore corrupts the output latches of all input-muxed pins in the
same bank: the read-modify-write in sunxi_pinctrl_gpio_set() reads back
their pin levels and writes those into their latches.
This breaks emulated open-drain lines (e.g. a bit-banged I2C bus from
i2c-gpio). Such a line is released high by muxing it as input and
letting the pull-up raise it, so any concurrent GPIO write in the same
bank stores 1 into its latch. Driving the line low afterwards is a
non-atomic data-then-mux sequence in sunxi_pinctrl_gpio_direction_output();
if the poisoning write lands between the two steps, the pin actively
drives high (push-pull) instead of low.
Observed in practice as sporadic glitches on a T507 board bit-banging
I2C on port E while other PE GPIOs are toggled. On a scope the failure
is unmistakable: on a clock pulse where SCL should fall to GND, the line
instead steps *above* its idle high level for the whole low phase — the
pad drives a strong push-pull 3.3 V high, higher than the level the
pull-up sustains on the loaded bus — before the next transition recovers
it. The same can hit SDA, corrupting data instead of clocks.
Steps to reproduce on any sunxi board with a bit-banged (i2c-gpio) bus:
# background: toggle any other GPIO of the same bank, e.g. line 21
gpioset -c <chip> --toggle 100us 21=0 &
# foreground: keep the bit-banged bus busy
while :; do i2cdetect -y <bus> 0x50 0x57; done
# watch SCL/SDA with a scope or logic analyzer: sporadic clock-low
# phases driven high (above the pull-up level) instead of low
The bank spinlock cannot help: the racing write is a perfectly valid
whole-register RMW that faithfully writes back what the hardware
returned. There are no set/clear registers on this IP to write a single
bit atomically.
Fix it the same way gpio-mmio handles hardware whose data register read
does not return the output latch: keep a shadow copy of each bank's
latches, base the read-modify-write on the shadow, and only write the
register. The shadow is seeded from the hardware at probe time so pins
left in output mode by the bootloader keep their state. Pins that reach
output mode through the gpiolib paths write their value (and thereby
their shadow bit) before the mux switch in
sunxi_pinctrl_gpio_direction_output(); pins muxed to gpio_out directly
through a pinmux node bypass that path, so sunxi_pmx_set() refreshes
their shadow bit from the latch (readable once the pin is in output
mode) to keep them driving their pre-existing level.
Seeding the shadow reads the PIO registers at probe time, which requires
the bus clock to be enabled. The clock was only requested at the very
end of probe, after devm_pinctrl_register() had already claimed the pin
hogs described in the device tree - which mux pins, and thus access
registers, with the clock still gated. Move the request ahead of both.
Boards whose bootloader leaves the PIO clock running are unaffected,
which is why the pre-existing hog problem has gone unnoticed since
commit 950707c0eb5c ("pinctrl: sunxi: add clock support").
Fixes: df7b34f4c3d2 ("pinctrl: sunxi: Fix gpio_set behaviour")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Titov <ilya.titov@wirenboard.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 88 +++++++++++++++++++--------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 7 +++
2 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 508aa911c8d99..c7001f0eb6765 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -793,6 +793,21 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
writel((readl(pctl->membase + reg) & ~mask) | config << shift,
pctl->membase + reg);
+ /*
+ * A pin muxed to gpio_out directly through a pinmux node bypasses
+ * sunxi_pinctrl_gpio_set() and drives whatever its output latch
+ * holds. Now that the pin is in output mode the data register
+ * reads back the latch, so refresh the shadow to keep such pins
+ * driving their pre-existing level.
+ */
+ if (config == SUN4I_FUNC_OUTPUT) {
+ u32 *shadow = &pctl->dat_shadow[pin / PINS_PER_BANK];
+
+ sunxi_data_reg(pctl, pin, ®, &shift, &mask);
+ *shadow = (*shadow & ~mask) |
+ (readl(pctl->membase + reg) & mask);
+ }
+
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
@@ -946,21 +961,29 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
unsigned offset, int value)
{
struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
- u32 reg, shift, mask, val;
+ u32 *shadow = &pctl->dat_shadow[offset / PINS_PER_BANK];
+ u32 reg, shift, mask;
unsigned long flags;
sunxi_data_reg(pctl, offset, ®, &shift, &mask);
raw_spin_lock_irqsave(&pctl->lock, flags);
- val = readl(pctl->membase + reg);
-
+ /*
+ * Reading the data register returns the pin level, not the output
+ * latch, for pins muxed as inputs. A read-modify-write based on
+ * the register would therefore corrupt the latches of input-muxed
+ * pins in the same bank (e.g. an emulated open-drain I2C line
+ * released high), making them drive the wrong level once switched
+ * to output. Base the read-modify-write on a shadow copy of the
+ * latches instead.
+ */
if (value)
- val |= mask;
+ *shadow |= mask;
else
- val &= ~mask;
+ *shadow &= ~mask;
- writel(val, pctl->membase + reg);
+ writel(*shadow, pctl->membase + reg);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
@@ -1484,7 +1507,7 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
struct pinctrl_pin_desc *pins;
struct sunxi_pinctrl *pctl;
struct pinmux_ops *pmxops;
- int i, ret, last_pin, pin_idx;
+ int i, ret, last_pin, pin_idx, nbanks;
struct clk *clk;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
@@ -1518,6 +1541,37 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
if (!pctl->irq_array)
return -ENOMEM;
+ /*
+ * The bus clock has to be enabled before the pinctrl device
+ * registers, as the pin hogs claimed from there access registers.
+ */
+ ret = of_clk_get_parent_count(node);
+ clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ /*
+ * Seed the output latch shadow from the hardware so pins the
+ * bootloader left in output mode keep their state; see
+ * sunxi_pinctrl_gpio_set() for why a shadow is needed. This must
+ * happen before the pinctrl device registers, as pin hogs can mux
+ * pins to gpio_out and thereby update the shadow.
+ */
+ last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+ nbanks = DIV_ROUND_UP(last_pin + 1 - pctl->desc->pin_base,
+ PINS_PER_BANK);
+ pctl->dat_shadow = devm_kcalloc(&pdev->dev, nbanks,
+ sizeof(*pctl->dat_shadow), GFP_KERNEL);
+ if (!pctl->dat_shadow)
+ return -ENOMEM;
+
+ for (i = 0; i < nbanks; i++) {
+ u32 reg, shift, mask;
+
+ sunxi_data_reg(pctl, i * PINS_PER_BANK, ®, &shift, &mask);
+ pctl->dat_shadow[i] = readl(pctl->membase + reg);
+ }
+
ret = sunxi_pinctrl_build_state(pdev);
if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -1572,7 +1626,6 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
if (!pctl->chip)
return -ENOMEM;
- last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
pctl->chip->owner = THIS_MODULE;
pctl->chip->request = gpiochip_generic_request;
pctl->chip->free = gpiochip_generic_free;
@@ -1605,31 +1658,20 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
goto gpiochip_error;
}
- ret = of_clk_get_parent_count(node);
- clk = devm_clk_get(&pdev->dev, ret == 1 ? NULL : "apb");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- goto gpiochip_error;
- }
-
- ret = clk_prepare_enable(clk);
- if (ret)
- goto gpiochip_error;
-
pctl->irq = devm_kcalloc(&pdev->dev,
pctl->desc->irq_banks,
sizeof(*pctl->irq),
GFP_KERNEL);
if (!pctl->irq) {
ret = -ENOMEM;
- goto clk_error;
+ goto gpiochip_error;
}
for (i = 0; i < pctl->desc->irq_banks; i++) {
pctl->irq[i] = platform_get_irq(pdev, i);
if (pctl->irq[i] < 0) {
ret = pctl->irq[i];
- goto clk_error;
+ goto gpiochip_error;
}
}
@@ -1640,7 +1682,7 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM;
- goto clk_error;
+ goto gpiochip_error;
}
for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
@@ -1672,8 +1714,6 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
return 0;
-clk_error:
- clk_disable_unprepare(clk);
gpiochip_error:
gpiochip_remove(pctl->chip);
return ret;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index a87a2f944d609..244b0039480a0 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -80,6 +80,7 @@
#define IO_BIAS_MASK GENMASK(3, 0)
#define SUN4I_FUNC_INPUT 0
+#define SUN4I_FUNC_OUTPUT 1
#define SUN4I_FUNC_IRQ 6
#define PINCTRL_SUN5I_A10S BIT(1)
@@ -173,6 +174,12 @@ struct sunxi_pinctrl {
int *irq;
unsigned *irq_array;
raw_spinlock_t lock;
+ /*
+ * Output latch shadow, one word per bank. Seeded lockless at
+ * probe before the pinctrl device registers, protected by @lock
+ * afterwards.
+ */
+ u32 *dat_shadow;
struct pinctrl_dev *pctl_dev;
unsigned long variant;
u32 bank_mem_size;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0058/1887] perf tools: Fix a asan issue in parse_events_multi_pmu_add()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0057/1887] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0059/1887] perf test bpf: Address error about non-null argument for epoll_pwait 2nd arg Greg Kroah-Hartman
` (940 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namhyung Kim, Ian Rogers,
Adrian Hunter, Ingo Molnar, Jiri Olsa, Kan Liang, Leo Yan,
Peter Zijlstra, Arnaldo Carvalho de Melo, Florian Fainelli,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <namhyung@kernel.org>
commit 66c9598bd8916c6c1319d0100ac916cac89d4b0e upstream
In the parse_events_multi_pmu_add() it passes the 'config' variable
twice to parse_events_term__num() - one for config and another for
loc_term. I'm not sure about the second one as it's converted to
YYLTYPE variable. Asan reports it like below:
In function ‘parse_events_term__num’,
inlined from ‘parse_events_multi_pmu_add’ at util/parse-events.c:1602:6:
util/parse-events.c:2653:64: error: array subscript ‘YYLTYPE[0]’ is partly outside
array bounds of ‘char[8]’ [-Werror=array-bounds]
2653 | .err_term = loc_term ? loc_term->first_column : 0,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
util/parse-events.c: In function ‘parse_events_multi_pmu_add’:
util/parse-events.c:1587:15: note: object ‘config’ of size 8
1587 | char *config;
| ^~~~~~
cc1: all warnings being treated as errors
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230331202949.810326-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/util/parse-events.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5973f46c23755..b77686a7bd26c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1585,7 +1585,7 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
if (parse_events_term__num(&term,
PARSE_EVENTS__TERM_TYPE_USER,
- config, 1, false, &config,
+ config, 1, false, NULL,
NULL) < 0) {
free(config);
goto out_err;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0059/1887] perf test bpf: Address error about non-null argument for epoll_pwait 2nd arg
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0058/1887] perf tools: Fix a asan issue in parse_events_multi_pmu_add() Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0060/1887] usb: xhci: bail out of setup if the controller is inaccessible Greg Kroah-Hartman
` (939 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adrian Hunter, Ian Rogers, Jiri Olsa,
Namhyung Kim, Arnaldo Carvalho de Melo, Florian Fainelli,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <acme@redhat.com>
commit ed847e30f001b207013b6136c264454d7560557f upstream
First noticed on Fedora Rawhide:
tests/bpf.c: In function ‘epoll_pwait_loop’:
tests/bpf.c:36:17: error: argument 2 null where non-null expected [-Werror=nonnull]
36 | epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
| ^~~~~~~~~~~
In file included from tests/bpf.c:5:
/usr/include/sys/epoll.h:134:12: note: in a call to function ‘epoll_pwait’ declared ‘nonnull’
134 | extern int epoll_pwait (int __epfd, struct epoll_event *__events,
| ^~~~~~~~~~~
[perfbuilder@27cfe44d67ed perf-6.5.0-rc2]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-13.2.1-20230728/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none --without-cuda-driver --enable-offload-defaulted --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.1 20230728 (Red Hat 13.2.1-1) (GCC)
[perfbuilder@27cfe44d67ed perf-6.5.0-rc2]$
Just add that argument to address this compiler warning.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/lkml/ZMj8+bvN86D0ZKiB@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/tests/bpf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 6a4235a9cf57e..d5bf0e47a48a0 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -29,11 +29,12 @@
static int epoll_pwait_loop(void)
{
+ struct epoll_event events;
int i;
/* Should fail NR_ITERS times */
for (i = 0; i < NR_ITERS; i++)
- epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
+ epoll_pwait(-(i + 1), &events, 0, 0, NULL);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0060/1887] usb: xhci: bail out of setup if the controller is inaccessible
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0059/1887] perf test bpf: Address error about non-null argument for epoll_pwait 2nd arg Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0061/1887] gtp: serialize PDP context updates Greg Kroah-Hartman
` (938 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Mathias Nyman,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit 78203d5b54a40f0e36196ebf31c9c7a380fc8811 ]
xhci_gen_setup() locates the operational registers using the capability
length read from the very first register:
xhci->op_regs = hcd->regs +
HC_LENGTH(readl(&xhci->cap_regs->hc_capbase));
If the controller is dead or has dropped off the bus, that read returns
~0, HC_LENGTH() truncates it to 0xff, and op_regs ends up 0xff bytes
past the page-aligned MMIO base, i.e. unaligned. The first access
through it, xhci_halt() -> xhci_handshake() reading op_regs->status, is
then an unaligned readl() on device memory. arm64 faults on unaligned
device accesses, so instead of xhci_handshake() catching the all-ones
value and returning -ENODEV, setup oopses:
xhci-pci-renesas 0005:08:00.0: Unable to change power state from D3cold to D0, device inaccessible
xhci-pci-renesas 0005:08:00.0: xHCI Host Controller
xhci-pci-renesas 0005:08:00.0: new USB bus registered, assigned bus number 1
Unable to handle kernel paging request at virtual address ffff80030a770103
ESR = 0x0000000096000021
FSC = 0x21: alignment fault
Internal error: Oops: 0000000096000021 [#1] SMP
pc : xhci_halt [xhci_hcd]
Call trace:
xhci_halt
xhci_gen_setup
xhci_pci_setup
usb_add_hcd
usb_hcd_pci_probe
xhci_pci_common_probe
xhci_pci_renesas_probe
This was hit with a Renesas uPD720201 that failed to power up ("Unable
to change power state from D3cold to D0, device inaccessible") yet still
reached the HCD probe path.
Read the capability register once, and if it reads back the all-ones
value (as xhci_handshake() and xhci_reset() already test for), abort
setup with -ENODEV before op_regs is derived from it. Reading it once
also avoids re-reading a register that may change under a concurrent
hot-removal.
Fixes: 66d4eadd8d06 ("USB: xhci: BIOS handoff and HW initialization.")
Cc: stable@vger.kernel.org
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260806142113.2436238-11-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ dropped the phantom hcs_params1 local declaration since this tree lacks the later refactor that introduced it ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 104ee26b27aa4..6cfc8205d10db 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5365,6 +5365,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
*/
struct device *dev = hcd->self.sysdev;
int retval;
+ u32 hc_capbase;
/* Accept arbitrarily long scatter-gather lists */
hcd->self.sg_tablesize = ~0;
@@ -5385,15 +5386,19 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
mutex_init(&xhci->mutex);
xhci->main_hcd = hcd;
xhci->cap_regs = hcd->regs;
- xhci->op_regs = hcd->regs +
- HC_LENGTH(readl(&xhci->cap_regs->hc_capbase));
+ hc_capbase = readl(&xhci->cap_regs->hc_capbase);
+ if (hc_capbase == U32_MAX) {
+ xhci_warn(xhci, "Host controller not accessible, removed?\n");
+ return -ENODEV;
+ }
+ xhci->op_regs = hcd->regs + HC_LENGTH(hc_capbase);
xhci->run_regs = hcd->regs +
(readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
/* Cache read-only capability registers */
xhci->hcs_params1 = readl(&xhci->cap_regs->hcs_params1);
xhci->hcs_params2 = readl(&xhci->cap_regs->hcs_params2);
xhci->hcs_params3 = readl(&xhci->cap_regs->hcs_params3);
- xhci->hci_version = HC_VERSION(readl(&xhci->cap_regs->hc_capbase));
+ xhci->hci_version = HC_VERSION(hc_capbase);
xhci->hcc_params = readl(&xhci->cap_regs->hcc_params);
if (xhci->hci_version > 0x100)
xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0061/1887] gtp: serialize PDP context updates
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0060/1887] usb: xhci: bail out of setup if the controller is inaccessible Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0062/1887] KEYS: trusted: Fix TPM teardown ordering Greg Kroah-Hartman
` (937 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qing Ming, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qing Ming <a0yami@mailbox.org>
[ Upstream commit 498386b6d402737db1e2eeed4c385acbf0ef9e34 ]
PDP contexts can be deleted through GTP_CMD_DELPDP or while the GTP
network device is being unregistered. The latter is serialized by RTNL,
but the generic-netlink delete path only holds RCU.
Running both paths concurrently can therefore make both paths delete the
same PDP context. The issue was found through static analysis and
reproduced on a KASAN-enabled kernel by a simple two-thread program
racing GTP_CMD_DELPDP against RTM_DELLINK:
Oops: general protection fault, probably for non-canonical address
KASAN: maybe wild-memory-access in range
[0xdead000000000120-0xdead000000000127]
RIP: gtp_genl_del_pdp+0x1c1/0x420 [gtp]
RBP: dead000000000122
The second deletion dereferenced the poisoned hlist pprev pointer.
Serialize gtp_pdp_add(), gtp_genl_del_pdp(), and gtp_dellink() with a
shared mutex. Keep the mutex held until the final use of a PDP context in
the NEWPDP path, and keep the RCU read-side section around the complete
PDP context use in the DELPDP path.
Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)")
Cc: stable@vger.kernel.org
Signed-off-by: Qing Ming <a0yami@mailbox.org>
Link: https://patch.msgid.link/20260818150000.7670-1-a0yami@mailbox.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted the locking changes to the older IPv4-only PDP context API and omitted the absent IPv6 lookup hunk. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/gtp.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 0817ff58b8dab..501dbfa917408 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/rculist.h>
@@ -92,6 +93,7 @@ struct gtp_net {
};
static u32 gtp_h_initval;
+static DEFINE_MUTEX(gtp_pdp_lock);
static struct genl_family gtp_genl_family;
@@ -129,7 +131,8 @@ static struct pdp_ctx *gtp0_pdp_find(struct gtp_dev *gtp, u64 tid)
head = >p->tid_hash[gtp0_hashfn(tid) % gtp->hash_size];
- hlist_for_each_entry_rcu(pdp, head, hlist_tid) {
+ hlist_for_each_entry_rcu(pdp, head, hlist_tid,
+ lockdep_is_held(>p_pdp_lock)) {
if (pdp->gtp_version == GTP_V0 &&
pdp->u.v0.tid == tid)
return pdp;
@@ -145,7 +148,8 @@ static struct pdp_ctx *gtp1_pdp_find(struct gtp_dev *gtp, u32 tid)
head = >p->tid_hash[gtp1u_hashfn(tid) % gtp->hash_size];
- hlist_for_each_entry_rcu(pdp, head, hlist_tid) {
+ hlist_for_each_entry_rcu(pdp, head, hlist_tid,
+ lockdep_is_held(>p_pdp_lock)) {
if (pdp->gtp_version == GTP_V1 &&
pdp->u.v1.i_tei == tid)
return pdp;
@@ -161,7 +165,8 @@ static struct pdp_ctx *ipv4_pdp_find(struct gtp_dev *gtp, __be32 ms_addr)
head = >p->addr_hash[ipv4_hashfn(ms_addr) % gtp->hash_size];
- hlist_for_each_entry_rcu(pdp, head, hlist_addr) {
+ hlist_for_each_entry_rcu(pdp, head, hlist_addr,
+ lockdep_is_held(>p_pdp_lock)) {
if (pdp->af == AF_INET &&
pdp->ms_addr_ip4.s_addr == ms_addr)
return pdp;
@@ -1120,9 +1125,11 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
struct pdp_ctx *pctx;
int i;
+ mutex_lock(>p_pdp_lock);
for (i = 0; i < gtp->hash_size; i++)
hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid)
pdp_context_delete(pctx);
+ mutex_unlock(>p_pdp_lock);
list_del(>p->list);
unregister_netdevice_queue(dev, head);
@@ -1507,6 +1514,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
goto out_unlock;
}
+ mutex_lock(>p_pdp_lock);
pctx = gtp_pdp_add(gtp, sk, info);
if (IS_ERR(pctx)) {
err = PTR_ERR(pctx);
@@ -1514,6 +1522,7 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
gtp_tunnel_notify(pctx, GTP_CMD_NEWPDP, GFP_KERNEL);
err = 0;
}
+ mutex_unlock(>p_pdp_lock);
out_unlock:
rtnl_unlock();
@@ -1568,6 +1577,8 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[GTPA_VERSION])
return -EINVAL;
+ mutex_lock(>p_pdp_lock);
+
rcu_read_lock();
pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs);
@@ -1588,6 +1599,7 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
out_unlock:
rcu_read_unlock();
+ mutex_unlock(>p_pdp_lock);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0062/1887] KEYS: trusted: Fix TPM teardown ordering
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0061/1887] gtp: serialize PDP context updates Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:35 ` [PATCH 6.1 0063/1887] zram: fixup read_block_state() Greg Kroah-Hartman
` (936 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Jarkko Sakkinen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
[ Upstream commit 5e2d672280d97d83de43031d93761b12dadd7b8a ]
trusted_tpm_exit() drops the TPM chip reference and frees the digest
array before unregistering the trusted key type. key_type_lookup()
holds key_types_sem for reading until the key operation finishes, while
unregister_key_type() takes it for writing. It therefore provides the
synchronization point that must precede backend teardown.
The current order permits this interleaving:
CPU 0 CPU 1
trusted_tpm_exit() key_type_lookup("trusted")
put_device(&chip->dev) trusted_tpm_seal()
kfree(digests) pcrlock()
unregister_key_type() tpm_pcr_extend(..., digests)
CPU 1 can consequently dereference the freed digest array. The chip can
also be released before callbacks stop using it.
KASAN reported:
BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200
Read of size 2 at addr ffff88810872d000 by task poc/89
Call Trace:
tpm_pcr_extend+0x1f0/0x200
pcrlock+0x42/0x70 [trusted]
trusted_tpm_seal+0x1b6/0x570 [trusted]
trusted_instantiate+0x293/0x340 [trusted]
__key_instantiate_and_link+0xb2/0x2b0
__key_create_or_update+0x61e/0xb50
__do_sys_add_key+0x1b8/0x310
Allocated by task 88:
__kmalloc_noprof+0x1a7/0x490
do_one_initcall+0xa1/0x390
do_init_module+0x2df/0x840
Freed by task 90:
kfree+0x131/0x3c0
trusted_tpm_exit+0x59/0xa0 [trusted]
__do_sys_delete_module+0x346/0x510
Move unregister_key_type() before releasing either resource. This stops
new lookups and waits for in-flight key operations to finish before the
backend state is destroyed.
Fixes: 0b6cf6b97b7e ("tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://lore.kernel.org/r/20260731140925.2973492-1-nicoyip.dev@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
[ preserved the additional trusted_shash_release() cleanup after unregister_key_type() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/keys/trusted-keys/trusted_tpm1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 4863ee08b7b11..c482c54be918c 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -1058,10 +1058,10 @@ static int __init trusted_tpm_init(void)
static void trusted_tpm_exit(void)
{
if (chip) {
+ unregister_key_type(&key_type_trusted);
put_device(&chip->dev);
kfree(digests);
trusted_shash_release();
- unregister_key_type(&key_type_trusted);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0063/1887] zram: fixup read_block_state()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0062/1887] KEYS: trusted: Fix TPM teardown ordering Greg Kroah-Hartman
@ 2026-10-28 16:35 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0064/1887] zram: fix out-of-bounds access in read_block_state() Greg Kroah-Hartman
` (935 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sergey Senozhatsky, Chris Mason,
Brian Geffon, David Stevens, Minchan Kim, Richard Chang,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <senozhatsky@chromium.org>
[ Upstream commit 8b05d2d8af817c6a1e23032df51e7ad83030d543 ]
ac_time is now in seconds, do not use ktime_to_timespec64()
[akpm@linux-foundation.org: remove now-unused local `ts']
[akpm@linux-foundation.org: fix build]
Link: https://lkml.kernel.org/r/20260115033031.3818977-1-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reported-by: Chris Mason <clm@meta.com>
Closes: https://lkml.kernel.org/r/20260114124522.1326519-1-clm@meta.com
Cc: Brian Geffon <bgeffon@google.com>
Cc: David Stevens <stevensd@google.com>
Cc: Minchan Kim <minchan@google.com>
Cc: Richard Chang <richardycc@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Stable tree note: The ac_time conversion described above is not present
here, so retain the ktime_t conversion and microsecond output. Move the
timespec64 temporary into the scan loop instead, allowing the follow-up
bounds fix to move nr_pages initialization under init_lock cleanly. ]
Stable-dep-of: 391f057f44a5 ("zram: fix out-of-bounds access in read_block_state()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/zram/zram_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index bef5388e4e28e..de5533fadc675 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -904,7 +904,6 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
ssize_t index, written = 0;
struct zram *zram = file->private_data;
unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
- struct timespec64 ts;
kbuf = kvmalloc(count, GFP_KERNEL);
if (!kbuf)
@@ -919,6 +918,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
for (index = *ppos; index < nr_pages; index++) {
int copied;
+ struct timespec64 ts;
zram_slot_lock(zram, index);
if (!zram_allocated(zram, index))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0064/1887] zram: fix out-of-bounds access in read_block_state()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-10-28 16:35 ` [PATCH 6.1 0063/1887] zram: fixup read_block_state() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0065/1887] nfsd: release path refs on follow_down() error Greg Kroah-Hartman
` (934 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Longlong Xia, Sergey Senozhatsky,
Jens Axboe, Minchan Kim, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Longlong Xia <xialonglong@kylinos.cn>
[ Upstream commit 391f057f44a51cc9418da5cba78b014324174264 ]
read_block_state() calculates nr_pages before taking dev_lock. If the
device is reset and reinitialized with a smaller disksize before lock
acquisition, nr_pages still describes the old table. The subsequent loop
can then call slot_lock() past the end of the newly allocated table.
Read disksize after acquiring dev_lock and checking that the device is
initialized. The read lock then keeps the table and its bound stable for
the duration of the scan.
Link: https://lore.kernel.org/20260804065919.3970386-3-xialonglong2025@163.com
Fixes: c0265342bff4 ("zram: introduce zram memory tracking")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/zram/zram_drv.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index de5533fadc675..740ca88bb6733 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -903,7 +903,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
char *kbuf;
ssize_t index, written = 0;
struct zram *zram = file->private_data;
- unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
+ unsigned long nr_pages;
kbuf = kvmalloc(count, GFP_KERNEL);
if (!kbuf)
@@ -916,6 +916,8 @@ static ssize_t read_block_state(struct file *file, char __user *buf,
return -EINVAL;
}
+ nr_pages = zram->disksize >> PAGE_SHIFT;
+
for (index = *ppos; index < nr_pages; index++) {
int copied;
struct timespec64 ts;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0065/1887] nfsd: release path refs on follow_down() error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0064/1887] zram: fix out-of-bounds access in read_block_state() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0066/1887] nfsd: size fh_verify server sockaddr slot by xpt_locallen Greg Kroah-Hartman
` (933 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Mason, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <clm@meta.com>
[ Upstream commit 6cba08dc1922140d260cfeb30bbda4ee1bf869d8 ]
nfsd_cross_mnt() initializes a local struct path with mntget() and
dget() before calling follow_down(). On a negative return the error
arm jumps to out without releasing those references:
err = follow_down(&path, follow_flags);
if (err < 0)
goto out;
follow_down() never drops the caller's entry-time refs on any error
sub-case; for example a pre-cross d_manage() failure leaves path
untouched, so the mntget()/dget() taken on entry survive the call.
Every other early-exit arm in nfsd_cross_mnt() (other-namespace
return, IS_ERR(exp2), and the success tail after the swap) already
calls path_put(&path); the err < 0 arm is the lone omission. The
leak inflates mnt_count and d_count on each failed cross-mount,
blocking umount and pinning dentries against the shrinker, and is
reachable by any authenticated NFS client through nfsd_lookup_dentry
or the NFSv4 READDIR encode path.
Fix by calling path_put(&path) before the goto out in the err < 0
arm so the entry-time refs are released on all follow_down() error
returns.
Fixes: cc53ce53c869 ("Add a dentry op to allow processes to be held during pathwalk transit")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-2-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[ retained the older single-argument follow_down(&path) API ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/vfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index a69287613479b..ec28429c29462 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -130,8 +130,10 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
int err = 0;
err = follow_down(&path);
- if (err < 0)
+ if (err < 0) {
+ path_put(&path);
goto out;
+ }
if (path.mnt == exp->ex_path.mnt && path.dentry == dentry &&
nfsd_mountpoint(dentry, exp) == 2) {
/* This is only a mountpoint in some other namespace */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0066/1887] nfsd: size fh_verify server sockaddr slot by xpt_locallen
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0065/1887] nfsd: release path refs on follow_down() error Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0067/1887] nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create() Greg Kroah-Hartman
` (932 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Mason, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <clm@meta.com>
[ Upstream commit 71d068490098b1d23c63b2345e40675d3a1ca763 ]
The nfsd_fh_verify and nfsd_fh_verify_err tracepoints declare the
server sockaddr slot sized by xpt_remotelen but fill it from
xpt_local using xpt_locallen:
TP_STRUCT__entry(
...
__sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
...
)
TP_fast_assign(
...
__assign_sockaddr(server, &rqstp->rq_xprt->xpt_local,
rqstp->rq_xprt->xpt_locallen);
...
)
When xpt_locallen exceeds xpt_remotelen, __assign_sockaddr's memcpy
writes past the reserved ring-buffer slot. In the reverse direction
(xpt_locallen < xpt_remotelen) the slot is oversized and the
unwritten tail leaks prior ring-buffer contents to trace consumers.
The write-past-end case is reachable on NFS/UDP. svc_xprt_set_remote()
is only called from svc_tcp_accept() (net/sunrpc/svcsock.c) and from
the RDMA connect path; svc_create_socket() for UDP calls only
svc_xprt_set_local(), so xpt_remotelen stays 0 for the xprt's
lifetime. Every fh_verify trace for an NFSv2/v3-over-UDP request
then copies 16 or 28 bytes from xpt_local into a zero-byte slot.
The other NFSD tracepoints that record the server address
(NFSD_TRACE_PROC_CALL_FIELDS, NFSD_TRACE_PROC_RES_FIELDS,
SVC_RQST_ENDPOINT_FIELDS) already size the server slot by
xpt_locallen; nfsd_fh_verify and nfsd_fh_verify_err were the only
exceptions.
Fix by sizing the server slot with xpt_locallen so the declared slot
matches the copy length. The client slot and its assignment already
agree on xpt_remotelen and are left untouched.
Fixes: 051382885552 ("NFSD: Instrument fh_verify()")
Fixes: 948755efc951 ("NFSD: Replace dprintk() call site in fh_verify()")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-1-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/trace.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 447b3483f94ba..513245b3697cf 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -201,7 +201,7 @@ TRACE_EVENT(nfsd_fh_verify,
TP_ARGS(rqstp, fhp, type, access),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
- __sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
+ __sockaddr(server, rqstp->rq_xprt->xpt_locallen)
__sockaddr(client, rqstp->rq_xprt->xpt_remotelen)
__field(u32, xid)
__field(u32, fh_hash)
@@ -240,7 +240,7 @@ TRACE_EVENT_CONDITION(nfsd_fh_verify_err,
TP_CONDITION(error),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
- __sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
+ __sockaddr(server, rqstp->rq_xprt->xpt_locallen)
__sockaddr(client, rqstp->rq_xprt->xpt_remotelen)
__field(u32, xid)
__field(u32, fh_hash)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0067/1887] nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0066/1887] nfsd: size fh_verify server sockaddr slot by xpt_locallen Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0068/1887] nfsd: fix clock domain mismatch in clients_still_reclaiming() Greg Kroah-Hartman
` (931 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 2c7912732184773dbd371a411da87af1cc080b86 ]
nfsd4_create() stores the return value of nfsd4_acl_to_attr() in
status, but the switch(create->cr_type) block unconditionally
overwrites it in every branch. ACL translation errors are silently
discarded, and the CREATE proceeds without the requested ACL.
Add an early exit check after nfsd4_acl_to_attr(), matching the
pattern already used in nfsd4_setattr().
Fixes: c0cbe70742f4 ("NFSD: add posix ACLs to struct nfsd_attrs")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: prefer NFS4ERR_BADTYPE over NFS4ERR_ATTRNOTSUPP ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-5-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
[ retained unconditional ACL conversion because the older helper already handles null ACLs ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4proc.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 7486c470fe6f1..97d48dea5ac3a 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -761,7 +761,23 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;
+ /* Sanitize cr_type to avoid returning ATTRNOTSUPP. */
+ switch (create->cr_type) {
+ case NF4LNK:
+ case NF4BLK:
+ case NF4CHR:
+ case NF4SOCK:
+ case NF4FIFO:
+ case NF4DIR:
+ break;
+ default:
+ status = nfserr_badtype;
+ goto out_aftermask;
+ }
+
status = nfsd4_acl_to_attr(create->cr_type, create->cr_acl, &attrs);
+ if (status != nfs_ok)
+ goto out_aftermask;
current->fs->umask = create->cr_umask;
switch (create->cr_type) {
case NF4LNK:
@@ -828,6 +844,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
fh_put(&resfh);
out_umask:
current->fs->umask = 0;
+out_aftermask:
nfsd_attrs_free(&attrs);
return status;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0068/1887] nfsd: fix clock domain mismatch in clients_still_reclaiming()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0067/1887] nfsd: check nfsd4_acl_to_attr() return value in nfsd4_create() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0069/1887] nfsd: gate nfs2 setacl by argp->mask Greg Kroah-Hartman
` (930 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 09ea3eb9a518565f5bca386e81b993ed8825f5e8 ]
clients_still_reclaiming() computes a deadline from nn->boot_time
(CLOCK_REALTIME, ~1.7 billion) but compares it against
ktime_get_boottime_seconds() (CLOCK_BOOTTIME, seconds since boot).
The comparison is always false — it would take ~54 years of uptime
for BOOTTIME to exceed the REALTIME-derived deadline.
This means any client can hold the server in grace indefinitely by
sending CLAIM_PREVIOUS OPEN requests, blocking all non-reclaim
operations for all other clients.
Add boot_time_bt (CLOCK_BOOTTIME) alongside the existing boot_time
and use it for the deadline computation. boot_time (CLOCK_REALTIME)
is preserved for its cl_boot clientid-nonce role.
Fixes: 20b7d86f29d3 ("nfsd: use boottime for lease expiry calculation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-12-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
[ preserved the branch’s boolean fields instead of the upstream flags bitmap ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/netns.h | 1 +
fs/nfsd/nfs4state.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index be0c8f1ce4e3e..b95ad49800533 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -67,6 +67,7 @@ struct nfsd_net {
bool grace_end_forced;
bool client_tracking_active;
time64_t boot_time;
+ time64_t boot_time_bt; /* same instant in CLOCK_BOOTTIME */
struct dentry *nfsd_client_dir;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 07c739f5f08d3..a342f6398e55e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6029,7 +6029,7 @@ bool nfsd4_force_end_grace(struct nfsd_net *nn)
*/
static bool clients_still_reclaiming(struct nfsd_net *nn)
{
- time64_t double_grace_period_end = nn->boot_time +
+ time64_t double_grace_period_end = nn->boot_time_bt +
2 * nn->nfsd4_lease;
if (READ_ONCE(nn->grace_end_forced))
@@ -8277,6 +8277,7 @@ static int nfs4_state_create_net(struct net *net)
nn->conf_name_tree = RB_ROOT;
nn->unconf_name_tree = RB_ROOT;
nn->boot_time = ktime_get_real_seconds();
+ nn->boot_time_bt = ktime_get_boottime_seconds();
nn->grace_ended = false;
nn->grace_end_forced = false;
nn->client_tracking_active = false;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0069/1887] nfsd: gate nfs2 setacl by argp->mask
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0068/1887] nfsd: fix clock domain mismatch in clients_still_reclaiming() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0070/1887] coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior Greg Kroah-Hartman
` (929 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chuck Lever, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <chuck.lever@oracle.com>
[ Upstream commit a3a7e20ed66d3f04d37883c398da8a113b430769 ]
The NFSACL v2 SETACL path shares the decoder convention used by its
v3 sibling: nfsaclsvc_decode_setaclargs() fills in argp->acl_access
only when NFS_ACL is set in the request mask and argp->acl_default
only when NFS_DFACL is set, leaving the other pointer NULL because
the argument buffer is zeroed up to pc_argzero before decode.
nfsacld_proc_setacl() then hands both pointers to set_posix_acl()
unconditionally. set_posix_acl(idmap, dentry, type, NULL) is the VFS
"remove this ACL type" operation, so an omitted arm is
indistinguishable from an explicit request to delete that ACL. A
SETACL carrying only NFS_ACL silently strips the directory's default
ACL; mask=0 strips both.
This is the same defect just fixed in nfsd3_proc_setacl(); apply the
same remedy. Gate each set_posix_acl() call on its mask bit and
initialize error to 0 so that a request with neither bit set leaves
the on-disk ACLs untouched and returns success. The out_drop_lock
path and the unconditional posix_acl_release() in
nfsaclsvc_release_setacl() already tolerate the skipped arms.
Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.")
Cc: stable@vger.kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[ retained the older user-namespace and inode set_posix_acl() API in place of the newer mount-idmap and dentry API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs2acl.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index f8b91aacd8174..cd6de7aca989f 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -115,14 +115,19 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
inode_lock(inode);
- error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
- argp->acl_access);
- if (error)
- goto out_drop_lock;
- error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT,
- argp->acl_default);
- if (error)
- goto out_drop_lock;
+ error = 0;
+ if (argp->mask & NFS_ACL) {
+ error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
+ argp->acl_access);
+ if (error)
+ goto out_drop_lock;
+ }
+ if (argp->mask & NFS_DFACL) {
+ error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT,
+ argp->acl_default);
+ if (error)
+ goto out_drop_lock;
+ }
inode_unlock(inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0070/1887] coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0069/1887] nfsd: gate nfs2 setacl by argp->mask Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0071/1887] kasan: fix lockdep report invalid wait context Greg Kroah-Hartman
` (928 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuan-Wei Chiu, James Clark,
Suzuki K Poulose, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Wei Chiu <visitorckw@gmail.com>
[ Upstream commit 41fb4e925528aefa4b7a5f76c7f81db99c0d0f38 ]
The cntr_val_show() function was intended to print the values of all
counters using a loop. However, due to a buffer overwrite issue with
sprintf(), it effectively only displayed the value of the last counter.
The companion function, cntr_val_store(), allows users to modify a
specific counter selected by 'cntr_idx'. To maintain consistency
between read and write operations and to align with the ETM4x driver
behavior, modify cntr_val_show() to report only the value of the
currently selected counter.
This change removes the loop and the "counter %d:" prefix, printing
only the hexadecimal value. It also adopts sysfs_emit() for standard
sysfs output formatting.
Fixes: a939fc5a71ad ("coresight-etm: add CoreSight ETM/PTM driver")
Cc: stable@vger.kernel.org
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20251202082613.3265761-1-visitorckw@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../hwtracing/coresight/coresight-etm3x-sysfs.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index fd81eca3ec182..a49b3c237c079 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -716,26 +716,19 @@ static DEVICE_ATTR_RW(cntr_rld_event);
static ssize_t cntr_val_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int i, ret = 0;
u32 val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etm_config *config = &drvdata->config;
if (!local_read(&drvdata->mode)) {
spin_lock(&drvdata->spinlock);
- for (i = 0; i < drvdata->nr_cntr; i++)
- ret += sprintf(buf, "counter %d: %x\n",
- i, config->cntr_val[i]);
+ val = config->cntr_val[config->cntr_idx];
spin_unlock(&drvdata->spinlock);
- return ret;
- }
-
- for (i = 0; i < drvdata->nr_cntr; i++) {
- val = etm_readl(drvdata, ETMCNTVRn(i));
- ret += sprintf(buf, "counter %d: %x\n", i, val);
+ } else {
+ val = etm_readl(drvdata, ETMCNTVRn(config->cntr_idx));
}
- return ret;
+ return sysfs_emit(buf, "%#x\n", val);
}
static ssize_t cntr_val_store(struct device *dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0071/1887] kasan: fix lockdep report invalid wait context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0070/1887] coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0072/1887] kasan: fix cache shrink race with CPU hotplug Greg Kroah-Hartman
` (927 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zqiang, Marco Elver,
Alexander Potapenko, Andrey Konovalov, Andrey Ryabinin,
Dmitry Vyukov, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zqiang <qiang1.zhang@intel.com>
[ Upstream commit be41d814c6c7bbf3ffa66faeefa01f6cea8e3c98 ]
For kernels built with the following options and booting
CONFIG_SLUB=y
CONFIG_DEBUG_LOCKDEP=y
CONFIG_PROVE_LOCKING=y
CONFIG_PROVE_RAW_LOCK_NESTING=y
[ 0.523115] [ BUG: Invalid wait context ]
[ 0.523315] 6.3.0-rc1-yocto-standard+ #739 Not tainted
[ 0.523649] -----------------------------
[ 0.523663] swapper/0/0 is trying to lock:
[ 0.523663] ffff888035611360 (&c->lock){....}-{3:3}, at: put_cpu_partial+0x2e/0x1e0
[ 0.523663] other info that might help us debug this:
[ 0.523663] context-{2:2}
[ 0.523663] no locks held by swapper/0/0.
[ 0.523663] stack backtrace:
[ 0.523663] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.3.0-rc1-yocto-standard+ #739
[ 0.523663] Call Trace:
[ 0.523663] <IRQ>
[ 0.523663] dump_stack_lvl+0x64/0xb0
[ 0.523663] dump_stack+0x10/0x20
[ 0.523663] __lock_acquire+0x6c4/0x3c10
[ 0.523663] lock_acquire+0x188/0x460
[ 0.523663] put_cpu_partial+0x5a/0x1e0
[ 0.523663] __slab_free+0x39a/0x520
[ 0.523663] ___cache_free+0xa9/0xc0
[ 0.523663] qlist_free_all+0x7a/0x160
[ 0.523663] per_cpu_remove_cache+0x5c/0x70
[ 0.523663] __flush_smp_call_function_queue+0xfc/0x330
[ 0.523663] generic_smp_call_function_single_interrupt+0x13/0x20
[ 0.523663] __sysvec_call_function+0x86/0x2e0
[ 0.523663] sysvec_call_function+0x73/0x90
[ 0.523663] </IRQ>
[ 0.523663] <TASK>
[ 0.523663] asm_sysvec_call_function+0x1b/0x20
[ 0.523663] RIP: 0010:default_idle+0x13/0x20
[ 0.523663] RSP: 0000:ffffffff83e07dc0 EFLAGS: 00000246
[ 0.523663] RAX: 0000000000000000 RBX: ffffffff83e1e200 RCX: ffffffff82a83293
[ 0.523663] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8119a6b1
[ 0.523663] RBP: ffffffff83e07dc8 R08: 0000000000000001 R09: ffffed1006ac0d66
[ 0.523663] R10: ffff888035606b2b R11: ffffed1006ac0d65 R12: 0000000000000000
[ 0.523663] R13: ffffffff83e1e200 R14: ffffffff84a7d980 R15: 0000000000000000
[ 0.523663] default_idle_call+0x6c/0xa0
[ 0.523663] do_idle+0x2e1/0x330
[ 0.523663] cpu_startup_entry+0x20/0x30
[ 0.523663] rest_init+0x152/0x240
[ 0.523663] arch_call_rest_init+0x13/0x40
[ 0.523663] start_kernel+0x331/0x470
[ 0.523663] x86_64_start_reservations+0x18/0x40
[ 0.523663] x86_64_start_kernel+0xbb/0x120
[ 0.523663] secondary_startup_64_no_verify+0xe0/0xeb
[ 0.523663] </TASK>
The local_lock_irqsave() is invoked in put_cpu_partial() and happens in
IPI context, due to the CONFIG_PROVE_RAW_LOCK_NESTING=y (the
LD_WAIT_CONFIG not equal to LD_WAIT_SPIN), so acquire local_lock in IPI
context will trigger above calltrace.
This commit therefore moves qlist_free_all() from hard-irq context to task
context.
Link: https://lkml.kernel.org/r/20230327120019.1027640-1-qiang1.zhang@intel.com
Signed-off-by: Zqiang <qiang1.zhang@intel.com>
Acked-by: Marco Elver <elver@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 8790303cbaac ("kasan: fix cache shrink race with CPU hotplug")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kasan/quarantine.c | 34 ++++++++--------------------------
1 file changed, 8 insertions(+), 26 deletions(-)
diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c
index 75585077eb6dd..152dca73f3984 100644
--- a/mm/kasan/quarantine.c
+++ b/mm/kasan/quarantine.c
@@ -99,7 +99,6 @@ static unsigned long quarantine_size;
static DEFINE_RAW_SPINLOCK(quarantine_lock);
DEFINE_STATIC_SRCU(remove_cache_srcu);
-#ifdef CONFIG_PREEMPT_RT
struct cpu_shrink_qlist {
raw_spinlock_t lock;
struct qlist_head qlist;
@@ -108,7 +107,6 @@ struct cpu_shrink_qlist {
static DEFINE_PER_CPU(struct cpu_shrink_qlist, shrink_qlist) = {
.lock = __RAW_SPIN_LOCK_UNLOCKED(shrink_qlist.lock),
};
-#endif
/* Maximum size of the global queue. */
static unsigned long quarantine_max_size;
@@ -319,16 +317,6 @@ static void qlist_move_cache(struct qlist_head *from,
}
}
-#ifndef CONFIG_PREEMPT_RT
-static void __per_cpu_remove_cache(struct qlist_head *q, void *arg)
-{
- struct kmem_cache *cache = arg;
- struct qlist_head to_free = QLIST_INIT;
-
- qlist_move_cache(q, &to_free, cache);
- qlist_free_all(&to_free, cache);
-}
-#else
static void __per_cpu_remove_cache(struct qlist_head *q, void *arg)
{
struct kmem_cache *cache = arg;
@@ -340,7 +328,6 @@ static void __per_cpu_remove_cache(struct qlist_head *q, void *arg)
qlist_move_cache(q, &sq->qlist, cache);
raw_spin_unlock_irqrestore(&sq->lock, flags);
}
-#endif
static void per_cpu_remove_cache(void *arg)
{
@@ -362,6 +349,8 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache)
{
unsigned long flags, i;
struct qlist_head to_free = QLIST_INIT;
+ int cpu;
+ struct cpu_shrink_qlist *sq;
/*
* Must be careful to not miss any objects that are being moved from
@@ -372,20 +361,13 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache)
*/
on_each_cpu(per_cpu_remove_cache, cache, 1);
-#ifdef CONFIG_PREEMPT_RT
- {
- int cpu;
- struct cpu_shrink_qlist *sq;
-
- for_each_online_cpu(cpu) {
- sq = per_cpu_ptr(&shrink_qlist, cpu);
- raw_spin_lock_irqsave(&sq->lock, flags);
- qlist_move_cache(&sq->qlist, &to_free, cache);
- raw_spin_unlock_irqrestore(&sq->lock, flags);
- }
- qlist_free_all(&to_free, cache);
+ for_each_online_cpu(cpu) {
+ sq = per_cpu_ptr(&shrink_qlist, cpu);
+ raw_spin_lock_irqsave(&sq->lock, flags);
+ qlist_move_cache(&sq->qlist, &to_free, cache);
+ raw_spin_unlock_irqrestore(&sq->lock, flags);
}
-#endif
+ qlist_free_all(&to_free, cache);
raw_spin_lock_irqsave(&quarantine_lock, flags);
for (i = 0; i < QUARANTINE_BATCHES; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0072/1887] kasan: fix cache shrink race with CPU hotplug
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0071/1887] kasan: fix lockdep report invalid wait context Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0073/1887] ACPI: TAD: Rearrange RT data validation checking Greg Kroah-Hartman
` (926 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Su, Andrey Ryabinin,
Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Zhang, Qiang1, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit 8790303cbaac52a11dfed4aab261f8ea60682525 ]
kasan_quarantine_remove_cache() first invokes per_cpu_remove_cache() on
all online CPUs. Each callback moves objects belonging to the cache from
cpu_quarantine to the CPU's shrink_qlist, where they can later be freed
from task context.
kmem_cache_destroy() invokes the quarantine removal path while holding
cpus_read_lock(), but kmem_cache_shrink() does not. The latter can
therefore race with CPU offlining as follows:
kmem_cache_shrink() CPU hotplug
------------------- -----------
on_each_cpu()
CPU1 moves objects to
CPU1's shrink_qlist
on_each_cpu() returns
CPU1 goes offline
kasan_cpu_offline()
drains cpu_quarantine
leaves shrink_qlist untouched
for_each_online_cpu()
skips CPU1
The objects left on CPU1's shrink_qlist are not returned to the slab
allocator. This may prevent kmem_cache_shrink() from releasing slabs that
would otherwise become empty. If CPU1 remains offline, a later
kmem_cache_destroy() also skips the list and can report that the cache
still contains objects.
An intermittent occurrence was observed with a virtio-9p filesystem. The
mount and umount commands both returned 0, but the kernel logged the
following during the userspace-triggered teardown:
[ 2994.380134][ T111] BUG 9p-fcall-cache-1 (Tainted: G B ): Objects remaining on __kmem_cache_shutdown()
[ 2994.381140][ T111] Object 0xff11000004361118 @offset=4376
[ 2994.381607][ T111] Allocated in p9_fcall_init+0x201/0x400 age=19564 cpu=1 pid=104
[ 2994.382591][ T111] p9_fcall_init+0x201/0x400
[ 2994.382810][ T111] p9_tag_alloc+0x12f/0x700
[ 2994.382982][ T111] p9_client_prepare_req+0x102/0x3e0
[ 2994.383165][ T111] p9_client_rpc+0x1ab/0xa50
[ 2994.383334][ T111] p9_client_getattr_dotl+0xb0/0x1a0
[ 2994.383515][ T111] v9fs_vfs_getattr_dotl+0x115/0x360
[ 2994.383719][ T111] vfs_getattr_nosec+0x22c/0x3a0
[ 2994.383910][ T111] vfs_statx+0xd7/0x170
[ 2994.384062][ T111] vfs_fstatat+0x45/0x80
[ 2994.384215][ T111] __do_sys_newfstatat+0x84/0xe0
[ 2994.384386][ T111] do_syscall_64+0x115/0x6a0
[ 2994.384566][ T111] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2994.399720][ T111] WARNING: mm/slub.c:1244 at __kmem_cache_shutdown+0x363/0x500, CPU#0: busybox/111
[ 2994.405655][ T111] Call Trace:
[ 2994.406325][ T111] kmem_cache_destroy+0x73/0x1b0
[ 2994.406630][ T111] p9_client_destroy+0x271/0x3c0
[ 2994.407210][ T111] v9fs_session_close+0x3c/0x260
[ 2994.407409][ T111] v9fs_kill_super+0x48/0x90
[ 2994.407584][ T111] deactivate_locked_super+0xa3/0x160
[ 2994.407778][ T111] cleanup_mnt+0x1dd/0x3e0
Thus, a successful umount left objects in the 9p fcall cache and prevented
the cache from being destroyed cleanly.
Per-CPU shrink_qlist storage exists for every possible CPU, and each list
is protected by its own raw spinlock. Iterate over possible CPUs so that
a list populated before its CPU went offline is drained as well.
for_each_possible_cpu() can do more work than for_each_online_cpu(), but
this change only affects CONFIG_KASAN_GENERIC kernels. The extra work is
limited to cache shrink and cache destruction paths and does not affect
the normal allocation/free fast path. It adds one raw-spinlock-protected
scan of each possible CPU's shrink list. These lists are normally empty;
a non-empty list is traversed to remove objects belonging to the cache
being shrunk or destroyed.
Link: https://lore.kernel.org/20260808031459.3032812-1-sh_def@163.com
Fixes: 07d067e4f2ce ("kasan: fix sleeping function called from invalid context on RT kernel")
Signed-off-by: Hui Su <sh_def@163.com>
Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: "Zhang, Qiang1" <qiang1.zhang@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kasan/quarantine.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c
index 152dca73f3984..11bd18e851a02 100644
--- a/mm/kasan/quarantine.c
+++ b/mm/kasan/quarantine.c
@@ -361,7 +361,12 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache)
*/
on_each_cpu(per_cpu_remove_cache, cache, 1);
- for_each_online_cpu(cpu) {
+ /*
+ * A CPU can go offline after on_each_cpu() returns, leaving cache
+ * objects on that CPU's shrink list. Scan all possible CPUs to
+ * drain those lists.
+ */
+ for_each_possible_cpu(cpu) {
sq = per_cpu_ptr(&shrink_qlist, cpu);
raw_spin_lock_irqsave(&sq->lock, flags);
qlist_move_cache(&sq->qlist, &to_free, cache);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0073/1887] ACPI: TAD: Rearrange RT data validation checking
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0072/1887] kasan: fix cache shrink race with CPU hotplug Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0074/1887] ACPI: TAD: Split three functions to untangle runtime PM handling Greg Kroah-Hartman
` (925 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rafael J. Wysocki, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ Upstream commit 3329a1416c3350449081ca5daaa94802a65b2992 ]
Move RT data validation checks from acpi_tad_set_real_time() to
a separate function called acpi_tad_rt_is_invalid() and use it
also in acpi_tad_get_real_time() to validate data coming from
the platform firmware.
Also make acpi_tad_set_real_time() return -EINVAL when the RT data
passed to it is invalid (instead of -ERANGE which is somewhat
confusing) and introduce ACPI_TAD_TZ_UNSPEC to represent the
"unspecified timezone" value.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/3409319.aeNJFYEL58@rafael.j.wysocki
Stable-dep-of: a3df8bbe0a70 ("ACPI: TAD: Add locking around AML evaluations")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/acpi_tad.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c
index 8383d6329c645..664281d7f4259 100644
--- a/drivers/acpi/acpi_tad.c
+++ b/drivers/acpi/acpi_tad.c
@@ -48,6 +48,9 @@ MODULE_AUTHOR("Rafael J. Wysocki");
/* Special value for disabled timer or expired timer wake policy. */
#define ACPI_TAD_WAKE_DISABLED (~(u32)0)
+/* ACPI TAD RTC */
+#define ACPI_TAD_TZ_UNSPEC 2047
+
struct acpi_tad_driver_data {
u32 capabilities;
};
@@ -66,6 +69,16 @@ struct acpi_tad_rt {
u8 padding[3]; /* must be 0 */
} __packed;
+static bool acpi_tad_rt_is_invalid(struct acpi_tad_rt *rt)
+{
+ return rt->year < 1900 || rt->year > 9999 ||
+ rt->month < 1 || rt->month > 12 ||
+ rt->hour > 23 || rt->minute > 59 || rt->second > 59 ||
+ rt->tz < -1440 ||
+ (rt->tz > 1440 && rt->tz != ACPI_TAD_TZ_UNSPEC) ||
+ rt->daylight > 3;
+}
+
static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
{
acpi_handle handle = ACPI_HANDLE(dev);
@@ -79,12 +92,8 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
unsigned long long retval;
acpi_status status;
- if (rt->year < 1900 || rt->year > 9999 ||
- rt->month < 1 || rt->month > 12 ||
- rt->hour > 23 || rt->minute > 59 || rt->second > 59 ||
- rt->tz < -1440 || (rt->tz > 1440 && rt->tz != 2047) ||
- rt->daylight > 3)
- return -ERANGE;
+ if (acpi_tad_rt_is_invalid(rt))
+ return -EINVAL;
args[0].buffer.pointer = (u8 *)rt;
args[0].buffer.length = sizeof(*rt);
@@ -131,6 +140,11 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
goto out_free;
memcpy(rt, data, sizeof(*rt));
+ if (acpi_tad_rt_is_invalid(rt)) {
+ ret = -ENODATA;
+ goto out_free;
+ }
+
ret = 0;
out_free:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0074/1887] ACPI: TAD: Split three functions to untangle runtime PM handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0073/1887] ACPI: TAD: Rearrange RT data validation checking Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0075/1887] ACPI: TAD: Add locking around AML evaluations Greg Kroah-Hartman
` (924 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rafael J. Wysocki, Alexandre Belloni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ Upstream commit b14b77bbea0a82cb66f1538824783e63d4128510 ]
Move the core functionality of acpi_tad_get_real_time(),
acpi_tad_wake_set(), and acpi_tad_wake_read() into separate functions
called __acpi_tad_get_real_time(), __acpi_tad_wake_set(), and
__acpi_tad_wake_read(), respectively, which can be called from
code blocks following a single runtime resume of the device.
This will facilitate adding alarm support to the RTC class device
interface of the driver going forward.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://patch.msgid.link/23076728.EfDdHjke4D@rafael.j.wysocki
Stable-dep-of: a3df8bbe0a70 ("ACPI: TAD: Add locking around AML evaluations")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/acpi_tad.c | 128 ++++++++++++++++++++++++++--------------
1 file changed, 84 insertions(+), 44 deletions(-)
diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c
index 664281d7f4259..5f8fc254fc4f3 100644
--- a/drivers/acpi/acpi_tad.c
+++ b/drivers/acpi/acpi_tad.c
@@ -110,7 +110,7 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
return 0;
}
-static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
+static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt)
{
acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
@@ -119,12 +119,7 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
acpi_status status;
int ret = -EIO;
- pm_runtime_get_sync(dev);
-
status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
-
- pm_runtime_put_sync(dev);
-
if (ACPI_FAILURE(status))
goto out_free;
@@ -140,11 +135,6 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
goto out_free;
memcpy(rt, data, sizeof(*rt));
- if (acpi_tad_rt_is_invalid(rt)) {
- ret = -ENODATA;
- goto out_free;
- }
-
ret = 0;
out_free:
@@ -152,6 +142,82 @@ static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
return ret;
}
+static int __acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
+{
+ int ret;
+
+ ret = acpi_tad_evaluate_grt(dev, rt);
+ if (ret)
+ return ret;
+
+ if (acpi_tad_rt_is_invalid(rt))
+ return -ENODATA;
+
+ return 0;
+}
+
+static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
+{
+ int ret;
+
+ pm_runtime_get_sync(dev);
+
+ ret = __acpi_tad_get_real_time(dev, rt);
+
+ pm_runtime_put_sync(dev);
+
+ return ret;
+}
+
+static int __acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
+ u32 value)
+{
+ acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object args[] = {
+ { .type = ACPI_TYPE_INTEGER, },
+ { .type = ACPI_TYPE_INTEGER, },
+ };
+ struct acpi_object_list arg_list = {
+ .pointer = args,
+ .count = ARRAY_SIZE(args),
+ };
+ unsigned long long retval;
+ acpi_status status;
+
+ args[0].integer.value = timer_id;
+ args[1].integer.value = value;
+
+ status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
+ if (ACPI_FAILURE(status) || retval)
+ return -EIO;
+
+ return 0;
+}
+
+static int __acpi_tad_wake_read(struct device *dev, char *method, u32 timer_id,
+ unsigned long long *retval)
+{
+ acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object args[] = {
+ { .type = ACPI_TYPE_INTEGER, },
+ };
+ struct acpi_object_list arg_list = {
+ .pointer = args,
+ .count = ARRAY_SIZE(args),
+ };
+ acpi_status status;
+
+ args[0].integer.value = timer_id;
+
+ status = acpi_evaluate_integer(handle, method, &arg_list, retval);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
+/* sysfs interface */
+
static char *acpi_tad_rt_next_field(char *s, int *val)
{
char *p;
@@ -264,31 +330,15 @@ static const struct attribute_group acpi_tad_time_attr_group = {
static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
u32 value)
{
- acpi_handle handle = ACPI_HANDLE(dev);
- union acpi_object args[] = {
- { .type = ACPI_TYPE_INTEGER, },
- { .type = ACPI_TYPE_INTEGER, },
- };
- struct acpi_object_list arg_list = {
- .pointer = args,
- .count = ARRAY_SIZE(args),
- };
- unsigned long long retval;
- acpi_status status;
-
- args[0].integer.value = timer_id;
- args[1].integer.value = value;
+ int ret;
pm_runtime_get_sync(dev);
- status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
+ ret = __acpi_tad_wake_set(dev, method, timer_id, value);
pm_runtime_put_sync(dev);
- if (ACPI_FAILURE(status) || retval)
- return -EIO;
-
- return 0;
+ return ret;
}
static int acpi_tad_wake_write(struct device *dev, const char *buf, char *method,
@@ -314,27 +364,17 @@ static int acpi_tad_wake_write(struct device *dev, const char *buf, char *method
static ssize_t acpi_tad_wake_read(struct device *dev, char *buf, char *method,
u32 timer_id, const char *specval)
{
- acpi_handle handle = ACPI_HANDLE(dev);
- union acpi_object args[] = {
- { .type = ACPI_TYPE_INTEGER, },
- };
- struct acpi_object_list arg_list = {
- .pointer = args,
- .count = ARRAY_SIZE(args),
- };
unsigned long long retval;
- acpi_status status;
-
- args[0].integer.value = timer_id;
+ int ret;
pm_runtime_get_sync(dev);
- status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
+ ret = __acpi_tad_wake_read(dev, method, timer_id, &retval);
pm_runtime_put_sync(dev);
- if (ACPI_FAILURE(status))
- return -EIO;
+ if (ret)
+ return ret;
if ((u32)retval == ACPI_TAD_WAKE_DISABLED)
return sprintf(buf, "%s\n", specval);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0075/1887] ACPI: TAD: Add locking around AML evaluations
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0074/1887] ACPI: TAD: Split three functions to untangle runtime PM handling Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0076/1887] kernel/params.c: Use kstrtobool() instead of strtobool() Greg Kroah-Hartman
` (923 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rafael J. Wysocki, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ Upstream commit a3df8bbe0a704fa5c1609b9666b594f350558fe0 ]
In the ACPI TAD driver, there are hidden assumptions that the ACPI
control methods used by it will not be evaluated concurrently due
to ACPICA namespace and interpreter locking.
However, that may not be the case since ACPICA may drop and re-acquire
the namespace and interpreter locks during the evaluation of a given
object in a few cases, including the one in which the AML in question
sleeps causing acpi_ex_system_do_sleep() to be called. In that case,
the evaluation of one control method may be started while the
evaluation of another one is still in progress.
For this reason, add a global lock to the ACPI TAD driver and
acquire it every time before evaluating an ACPI control method,
except for the initial evaluation of _GCP in acpi_tad_probe().
Fixes: 95c513ec84f7 ("ACPI: Add Time and Alarm Device (TAD) driver")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/12951141.O9o76ZdvQC@rafael.j.wysocki
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/acpi_tad.c | 50 ++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c
index 5f8fc254fc4f3..3ee041d5df59e 100644
--- a/drivers/acpi/acpi_tad.c
+++ b/drivers/acpi/acpi_tad.c
@@ -23,6 +23,7 @@
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
@@ -79,6 +80,8 @@ static bool acpi_tad_rt_is_invalid(struct acpi_tad_rt *rt)
rt->daylight > 3;
}
+static DEFINE_MUTEX(acpi_tad_aml_lock);
+
static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
{
acpi_handle handle = ACPI_HANDLE(dev);
@@ -100,6 +103,8 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
pm_runtime_get_sync(dev);
+ guard(mutex)(&acpi_tad_aml_lock);
+
status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);
pm_runtime_put_sync(dev);
@@ -114,30 +119,27 @@ static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt)
{
acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
- union acpi_object *out_obj;
- struct acpi_tad_rt *data;
acpi_status status;
int ret = -EIO;
- status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
- if (ACPI_FAILURE(status))
- goto out_free;
-
- out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER)
- goto out_free;
+ guard(mutex)(&acpi_tad_aml_lock);
- if (out_obj->buffer.length != sizeof(*rt))
- goto out_free;
-
- data = (struct acpi_tad_rt *)(out_obj->buffer.pointer);
- if (!data->valid)
- goto out_free;
-
- memcpy(rt, data, sizeof(*rt));
- ret = 0;
-
-out_free:
+ status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
+ if (ACPI_SUCCESS(status)) {
+ union acpi_object *out_obj;
+
+ out_obj = output.pointer;
+ if (out_obj->type == ACPI_TYPE_BUFFER &&
+ out_obj->buffer.length == sizeof(*rt)) {
+ struct acpi_tad_rt *data;
+
+ data = (struct acpi_tad_rt *)(out_obj->buffer.pointer);
+ if (data->valid) {
+ memcpy(rt, data, sizeof(*rt));
+ ret = 0;
+ }
+ }
+ }
ACPI_FREE(output.pointer);
return ret;
}
@@ -187,6 +189,8 @@ static int __acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
args[0].integer.value = timer_id;
args[1].integer.value = value;
+ guard(mutex)(&acpi_tad_aml_lock);
+
status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
if (ACPI_FAILURE(status) || retval)
return -EIO;
@@ -209,6 +213,8 @@ static int __acpi_tad_wake_read(struct device *dev, char *method, u32 timer_id,
args[0].integer.value = timer_id;
+ guard(mutex)(&acpi_tad_aml_lock);
+
status = acpi_evaluate_integer(handle, method, &arg_list, retval);
if (ACPI_FAILURE(status))
return -EIO;
@@ -425,6 +431,8 @@ static int acpi_tad_clear_status(struct device *dev, u32 timer_id)
pm_runtime_get_sync(dev);
+ guard(mutex)(&acpi_tad_aml_lock);
+
status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval);
pm_runtime_put_sync(dev);
@@ -466,6 +474,8 @@ static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id)
pm_runtime_get_sync(dev);
+ guard(mutex)(&acpi_tad_aml_lock);
+
status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval);
pm_runtime_put_sync(dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0076/1887] kernel/params.c: Use kstrtobool() instead of strtobool()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0075/1887] ACPI: TAD: Add locking around AML evaluations Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0077/1887] params: Do not go over the limit when getting the string length Greg Kroah-Hartman
` (922 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christophe JAILLET, Miroslav Benes,
Luis Chamberlain, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
[ Upstream commit def7b92efd868a6c78da86770704c1a03506016e ]
strtobool() is the same as kstrtobool().
However, the latter is more used within the kernel.
In order to remove strtobool() and slightly simplify kstrtox.h, switch to
the other function name.
While at it, include the corresponding header file (<linux/kstrtox.h>)
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
Stable-dep-of: 3dfaae04243c ("params: fix charp corruption on allocation failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/params.c b/kernel/params.c
index 82109c0cf9918..e6df4c2ef097c 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -4,6 +4,7 @@
*/
#include <linux/kernel.h>
+#include <linux/kstrtox.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -310,7 +311,7 @@ int param_set_bool(const char *val, const struct kernel_param *kp)
if (!val) val = "1";
/* One of =[yYnN01] */
- return strtobool(val, kp->arg);
+ return kstrtobool(val, kp->arg);
}
EXPORT_SYMBOL(param_set_bool);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0077/1887] params: Do not go over the limit when getting the string length
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0076/1887] kernel/params.c: Use kstrtobool() instead of strtobool() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0078/1887] params: Use size_add() for kmalloc() Greg Kroah-Hartman
` (921 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luis Chamberlain, Kees Cook,
Andy Shevchenko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit fd0cd057a1b7351604daa6ffc91dfe28adf7225d ]
We can use strnlen() even on early stages and it prevents from
going over the string boundaries in case it's already too long.
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20231120151419.1661807-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Kees Cook <keescook@chromium.org>
Stable-dep-of: 3dfaae04243c ("params: fix charp corruption on allocation failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/kernel/params.c b/kernel/params.c
index e6df4c2ef097c..89c139e861faf 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -264,7 +264,10 @@ EXPORT_SYMBOL_GPL(param_set_uint_minmax);
int param_set_charp(const char *val, const struct kernel_param *kp)
{
- if (strlen(val) > 1024) {
+ size_t len, maxlen = 1024;
+
+ len = strnlen(val, maxlen + 1);
+ if (len == maxlen + 1) {
pr_err("%s: string parameter too long\n", kp->name);
return -ENOSPC;
}
@@ -274,7 +277,7 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
/* This is a hack. We can't kmalloc in early boot, and we
* don't need to; this mangled commandline is preserved. */
if (slab_is_available()) {
- *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
+ *(char **)kp->arg = kmalloc_parameter(len + 1);
if (!*(char **)kp->arg)
return -ENOMEM;
strcpy(*(char **)kp->arg, val);
@@ -512,7 +515,7 @@ int param_set_copystring(const char *val, const struct kernel_param *kp)
{
const struct kparam_string *kps = kp->str;
- if (strlen(val)+1 > kps->maxlen) {
+ if (strnlen(val, kps->maxlen) == kps->maxlen) {
pr_err("%s: string doesn't fit in %u chars.\n",
kp->name, kps->maxlen-1);
return -ENOSPC;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0078/1887] params: Use size_add() for kmalloc()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0077/1887] params: Do not go over the limit when getting the string length Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0079/1887] params: Sort headers Greg Kroah-Hartman
` (920 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luis Chamberlain, Kees Cook,
Andy Shevchenko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 0fc79cbc937f2a754a302a710a94b68c61d0a89a ]
Prevent allocations from integer overflow by using size_add().
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20231120151419.1661807-4-andriy.shevchenko@linux.intel.com
Signed-off-by: Kees Cook <keescook@chromium.org>
Stable-dep-of: 3dfaae04243c ("params: fix charp corruption on allocation failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/params.c b/kernel/params.c
index 89c139e861faf..4d021ba9c677a 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -11,6 +11,7 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/security.h>
@@ -48,7 +49,7 @@ static void *kmalloc_parameter(unsigned int size)
{
struct kmalloced_param *p;
- p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
+ p = kmalloc(size_add(sizeof(*p), size), GFP_KERNEL);
if (!p)
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0079/1887] params: Sort headers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0078/1887] params: Use size_add() for kmalloc() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0080/1887] params: Fix multi-line comment style Greg Kroah-Hartman
` (919 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luis Chamberlain, Kees Cook,
Andy Shevchenko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit a05f096c2c0ca52e8fd34740c7d4b53ab3e7123e ]
Sort the headers in alphabetic order in order to ease
the maintenance for this part.
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20231120151419.1661807-5-andriy.shevchenko@linux.intel.com
Signed-off-by: Kees Cook <keescook@chromium.org>
Stable-dep-of: 3dfaae04243c ("params: fix charp corruption on allocation failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/kernel/params.c b/kernel/params.c
index 4d021ba9c677a..8c51ce17862ca 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -3,18 +3,18 @@
Copyright (C) 2001 Rusty Russell.
*/
+#include <linux/ctype.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kstrtox.h>
-#include <linux/string.h>
-#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/err.h>
#include <linux/overflow.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
#include <linux/security.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#ifdef CONFIG_SYSFS
/* Protects all built-in parameters, modules use their own param_lock */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0080/1887] params: Fix multi-line comment style
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0079/1887] params: Sort headers Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0081/1887] params: fix charp corruption on allocation failure Greg Kroah-Hartman
` (918 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luis Chamberlain, Kees Cook,
Andy Shevchenko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit b5e3f86a47d34f7b8af899f8cc70520f6daf8b53 ]
The multi-line comment style in the file is rather arbitrary.
Make it follow the standard one.
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20231120151419.1661807-6-andriy.shevchenko@linux.intel.com
Signed-off-by: Kees Cook <keescook@chromium.org>
Stable-dep-of: 3dfaae04243c ("params: fix charp corruption on allocation failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/kernel/params.c b/kernel/params.c
index 8c51ce17862ca..03443c99496c6 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-/* Helpers for initial module or kernel cmdline parsing
- Copyright (C) 2001 Rusty Russell.
-
-*/
+/*
+ * Helpers for initial module or kernel cmdline parsing
+ * Copyright (C) 2001 Rusty Russell.
+ */
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -275,8 +275,10 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
maybe_kfree_parameter(*(char **)kp->arg);
- /* This is a hack. We can't kmalloc in early boot, and we
- * don't need to; this mangled commandline is preserved. */
+ /*
+ * This is a hack. We can't kmalloc() in early boot, and we
+ * don't need to; this mangled commandline is preserved.
+ */
if (slab_is_available()) {
*(char **)kp->arg = kmalloc_parameter(len + 1);
if (!*(char **)kp->arg)
@@ -741,8 +743,10 @@ void module_param_sysfs_remove(struct module *mod)
{
if (mod->mkobj.mp) {
sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
- /* We are positive that no one is using any param
- * attrs at this point. Deallocate immediately. */
+ /*
+ * We are positive that no one is using any param
+ * attrs at this point. Deallocate immediately.
+ */
free_module_param_attrs(&mod->mkobj);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0081/1887] params: fix charp corruption on allocation failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0080/1887] params: Fix multi-line comment style Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0082/1887] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
` (917 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jiacheng Yu, Petr Pavlu, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiacheng Yu <yujiacheng3@huawei.com>
[ Upstream commit 3dfaae04243cde460d82dfc2a7dd0bb6664d20ae ]
param_set_charp() stores charp parameters in allocated memory after slab is
available, and releases the previous value when the parameter is updated.
The previous value is released before the replacement allocation succeeds.
If kmalloc_parameter() fails, the setter returns -ENOMEM with the parameter
left as NULL.
Failing zswap's compressor update before zswap is initialized can later
trigger:
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:strcmp+0x10/0x30
Call Trace:
zswap_setup+0x3b1/0x490
zswap_enabled_param_set+0x5b/0xa0
param_attr_store+0x93/0xe0
module_attr_store+0x1c/0x30
kernfs_fop_write_iter+0x116/0x1f0
Allocate and copy the replacement first, then replace the parameter value
only after allocation succeeds.
Fixes: e180a6b7759a ("param: fix charp parameters set via sysfs")
Cc: stable@vger.kernel.org
Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/params.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/kernel/params.c b/kernel/params.c
index 03443c99496c6..1b699c7632598 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -265,6 +265,7 @@ EXPORT_SYMBOL_GPL(param_set_uint_minmax);
int param_set_charp(const char *val, const struct kernel_param *kp)
{
+ char *tmp;
size_t len, maxlen = 1024;
len = strnlen(val, maxlen + 1);
@@ -273,19 +274,20 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
return -ENOSPC;
}
- maybe_kfree_parameter(*(char **)kp->arg);
-
/*
* This is a hack. We can't kmalloc() in early boot, and we
* don't need to; this mangled commandline is preserved.
*/
if (slab_is_available()) {
- *(char **)kp->arg = kmalloc_parameter(len + 1);
- if (!*(char **)kp->arg)
+ tmp = kmalloc_parameter(len + 1);
+ if (!tmp)
return -ENOMEM;
- strcpy(*(char **)kp->arg, val);
+ memcpy(tmp, val, len + 1);
} else
- *(const char **)kp->arg = val;
+ tmp = (char *)val;
+
+ maybe_kfree_parameter(*(char **)kp->arg);
+ *(char **)kp->arg = tmp;
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0082/1887] dmaengine: Add devm_dma_request_chan()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0081/1887] params: fix charp corruption on allocation failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0083/1887] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
` (916 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bence Csókás, Vinod Koul,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bence Csókás <csokas.bence@prolan.hu>
[ Upstream commit 08bf1663c21a3e815eda28fa242d84c945ca3b94 ]
Expand the arsenal of devm functions for DMA devices, this time for
requesting channels.
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
Link: https://lore.kernel.org/r/20250610082256.400492-2-csokas.bence@prolan.hu
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Stable-dep-of: 777979e62711 ("i2c: mxs: fix DMA channel leak on probe error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dmaengine.c | 30 ++++++++++++++++++++++++++++++
include/linux/dmaengine.h | 7 +++++++
2 files changed, 37 insertions(+)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 53e755c03f414..96c3f455b7bd7 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -933,6 +933,36 @@ void dma_release_channel(struct dma_chan *chan)
}
EXPORT_SYMBOL_GPL(dma_release_channel);
+static void dmaenginem_release_channel(void *chan)
+{
+ dma_release_channel(chan);
+}
+
+/**
+ * devm_dma_request_chan - try to allocate an exclusive slave channel
+ * @dev: pointer to client device structure
+ * @name: slave channel name
+ *
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
+ *
+ * The operation is managed and will be undone on driver detach.
+ */
+
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+ struct dma_chan *chan = dma_request_chan(dev, name);
+ int ret = 0;
+
+ if (!IS_ERR(chan))
+ ret = devm_add_action_or_reset(dev, dmaenginem_release_channel, chan);
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(devm_dma_request_chan);
+
/**
* dmaengine_get - register interest in dma_channels
*/
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 3576c6e89fea4..368a03920c928 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1489,6 +1489,7 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
void dma_release_channel(struct dma_chan *chan);
int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
@@ -1525,6 +1526,12 @@ static inline struct dma_chan *dma_request_chan_by_mask(
{
return ERR_PTR(-ENODEV);
}
+
+static inline struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline void dma_release_channel(struct dma_chan *chan)
{
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0083/1887] i2c: mxs: fix DMA channel leak on probe error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0082/1887] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0084/1887] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
` (915 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ruoyu Wang, Frank Li, Andi Shyti,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <ruoyuw560@gmail.com>
[ Upstream commit 777979e627115734052b323d2721cdb500e81dcf ]
mxs_i2c_probe() requests an exclusive DMA channel before resetting the
controller and registering the I2C adapter. If either later operation
fails, probe returns without releasing the channel because the remove
callback is not invoked after a failed probe.
Use devm_dma_request_chan() so the device core releases the channel on
probe failure and driver detach. Remove the manual release from the
remove callback because the channel is now device-managed.
This issue was found by a static analysis checker and confirmed by
manual source review.
Fixes: 62885f59a261 ("MXS: Implement DMA support into mxs-i2c")
Assisted-by: unnamed:claude-opus-4.8 typestate
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Cc: <stable@vger.kernel.org> # v3.7+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260815151720.3757460-1-ruoyuw560@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/busses/i2c-mxs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index e0f3b3545cfe4..d792bcc11a895 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -832,7 +832,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
}
/* Setup the DMA */
- i2c->dmach = dma_request_chan(dev, "rx-tx");
+ i2c->dmach = devm_dma_request_chan(dev, "rx-tx");
if (IS_ERR(i2c->dmach)) {
return dev_err_probe(dev, PTR_ERR(i2c->dmach),
"Failed to request dma\n");
@@ -870,9 +870,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&i2c->adapter);
- if (i2c->dmach)
- dma_release_channel(i2c->dmach);
-
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0084/1887] lockd: fix swapped arguments in nlmsvc_match_ip()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0083/1887] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0085/1887] power: supply: rt9455: Convert to i2cs .probe_new() Greg Kroah-Hartman
` (914 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Oscar Ou, Chuck Lever, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oscar Ou <oscarou@synology.com>
[ Upstream commit b9060689f49dc663e9a3d069c4a65ff63a836e66 ]
When releasing locks by server IP address via /proc/fs/nfsd/unlock_ip,
nlmsvc_unlock_all_by_ip() calls nlm_traverse_files() with the server
sockaddr as the opaque @data argument:
nlm_traverse_files(server_addr, nlmsvc_match_ip, NULL);
The match callback is later invoked from nlm_traverse_locks() as:
match(lockhost, host);
where the first argument is the nlm_host that owns the lock, and the
second argument is the @data that was originally passed down (here the
server sockaddr). This is the convention every other match callback
relies on (nlmsvc_mark_host(), nlmsvc_same_host(), nlmsvc_is_client()):
arg1 is the real nlm_host, arg2 is the caller-supplied reference value.
nlmsvc_match_ip() has had these two arguments reversed ever since the
unlock-by-IP feature was introduced in commit 4373ea84c84d ("lockd:
unlock lockd locks associated with a given server ip"):
return rpc_cmp_addr(nlm_srcaddr(host), datap);
Here @host is actually the server sockaddr, so nlm_srcaddr(host)
dereferences a struct sockaddr as a struct nlm_host and reads garbage
at the offset of h_srcaddr; meanwhile @datap is actually the lock
owner's nlm_host but is compared as a sockaddr. As a result the
comparison practically never matches and locks are not released for the
requested IP.
Swap the arguments so the lock owner's source address is compared
against the requested server address:
return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);
Fixes: 4373ea84c84d ("lockd: unlock lockd locks associated with a given server ip")
Cc: stable@vger.kernel.org
Signed-off-by: Oscar Ou <oscarou@synology.com>
[ cel: fix the misleading typedef parameter names too ]
Link: https://patch.msgid.link/20260617075738.1151797-1-oscarou@synology.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/lockd/svcsubs.c | 2 +-
include/linux/lockd/lockd.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index 9e2a67bfd0702..bba701e1a6089 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -493,7 +493,7 @@ EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_sb);
static int
nlmsvc_match_ip(void *datap, struct nlm_host *host)
{
- return rpc_cmp_addr(nlm_srcaddr(host), datap);
+ return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);
}
/**
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 70ce419e27093..d6034b8bbb7dc 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -265,7 +265,7 @@ void nsm_release(struct nsm_handle *nsm);
* This is used in garbage collection and resource reclaim
* A return value != 0 means destroy the lock/block/share
*/
-typedef int (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
+typedef int (*nlm_host_match_fn_t)(void *owner, struct nlm_host *ref);
/*
* Server-side lock handling
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0085/1887] power: supply: rt9455: Convert to i2cs .probe_new()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0084/1887] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0086/1887] power: supply: rt9455: quiesce delayed work before teardown Greg Kroah-Hartman
` (913 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König,
Sebastian Reichel, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit 2adfc4370ebb745380a44c3e5418486a32a9ba67 ]
The probe function doesn't make use of the i2c_device_id * parameter so it
can be trivially converted.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 3e7a1ebc32fa ("power: supply: rt9455: quiesce delayed work before teardown")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/rt9455_charger.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c
index 566243a423c8f..dd4ff038814f4 100644
--- a/drivers/power/supply/rt9455_charger.c
+++ b/drivers/power/supply/rt9455_charger.c
@@ -1583,8 +1583,7 @@ static const struct regmap_config rt9455_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int rt9455_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rt9455_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
@@ -1741,7 +1740,7 @@ MODULE_DEVICE_TABLE(acpi, rt9455_i2c_acpi_match);
#endif
static struct i2c_driver rt9455_driver = {
- .probe = rt9455_probe,
+ .probe_new = rt9455_probe,
.remove = rt9455_remove,
.id_table = rt9455_i2c_id_table,
.driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0086/1887] power: supply: rt9455: quiesce delayed work before teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0085/1887] power: supply: rt9455: Convert to i2cs .probe_new() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0087/1887] i2c: core: Introduce i2c_client_get_device_id helper function Greg Kroah-Hartman
` (912 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Sebastian Reichel,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 3e7a1ebc32fad5a558254a478efd401c17a24381 ]
The threaded IRQ handler can queue pwr_rdy_work,
max_charging_time_work and batt_presence_work. pwr_rdy_work and
batt_presence_work can also queue max_charging_time_work, while
batt_presence_work can requeue itself.
rt9455_remove() cancels max_charging_time_work before
batt_presence_work. The latter can therefore queue
max_charging_time_work after it has already been cancelled:
rt9455_remove() workqueue
cancel pwr_rdy_work
cancel max_charging_time_work
batt_presence_work queues
max_charging_time_work
cancel batt_presence_work
return
devres frees rt9455_info
max_charging_time_work dereferences
rt9455_info
The IRQ also remains registered until devres cleanup and can queue more
work after any of the cancellation calls. If rt9455_hw_init() fails
after the IRQ has been requested, probe returns without cancelling work
that may already have been queued. A pending callback can then access
rt9455_info after it has been freed.
Register rt9455_cancel_all_delayed_works() through
devm_add_action_or_reset() right after devm_power_supply_register().
devres invokes the action in reverse registration order, after the
managed IRQ has been freed and before rt9455_info is released, so the
delayed works are drained in both rt9455_remove() and the probe error
path. Cancel pwr_rdy_work and batt_presence_work before
max_charging_time_work because both can queue the latter.
This issue was found by an in-house static analysis tool.
Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260723225310.12663-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/rt9455_charger.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c
index dd4ff038814f4..62ffc3acc2aec 100644
--- a/drivers/power/supply/rt9455_charger.c
+++ b/drivers/power/supply/rt9455_charger.c
@@ -1583,6 +1583,19 @@ static const struct regmap_config rt9455_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
+static void rt9455_cancel_all_delayed_works(void *data)
+{
+ struct rt9455_info *info = data;
+
+ /*
+ * Both pwr_rdy_work and batt_presence_work can queue
+ * max_charging_time_work, so cancel them first.
+ */
+ cancel_delayed_work_sync(&info->pwr_rdy_work);
+ cancel_delayed_work_sync(&info->batt_presence_work);
+ cancel_delayed_work_sync(&info->max_charging_time_work);
+}
+
static int rt9455_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
@@ -1673,6 +1686,10 @@ static int rt9455_probe(struct i2c_client *client)
goto put_usb_notifier;
}
+ ret = devm_add_action_or_reset(dev, rt9455_cancel_all_delayed_works, info);
+ if (ret)
+ goto put_usb_notifier;
+
ret = devm_request_threaded_irq(dev, client->irq, NULL,
rt9455_irq_handler_thread,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
@@ -1713,10 +1730,6 @@ static void rt9455_remove(struct i2c_client *client)
if (info->nb.notifier_call)
usb_unregister_notifier(info->usb_phy, &info->nb);
#endif
-
- cancel_delayed_work_sync(&info->pwr_rdy_work);
- cancel_delayed_work_sync(&info->max_charging_time_work);
- cancel_delayed_work_sync(&info->batt_presence_work);
}
static const struct i2c_device_id rt9455_i2c_id_table[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0087/1887] i2c: core: Introduce i2c_client_get_device_id helper function
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0086/1887] power: supply: rt9455: quiesce delayed work before teardown Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0088/1887] power: supply: max17040: Convert to i2cs .probe_new() Greg Kroah-Hartman
` (911 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nuno Sá, Andy Shevchenko,
Jonathan Cameron, Angel Iglesias, Jonathan Cameron, Wolfram Sang,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Angel Iglesias <ang.iglesiasg@gmail.com>
[ Upstream commit 662233731d66cf41e7494e532e702849c8ce18f3 ]
Introduces new helper function to aid in .probe_new() refactors. In order
to use existing i2c_get_device_id() on the probe callback, the device
match table needs to be accessible in that function, which would require
bigger refactors in some drivers using the deprecated .probe callback.
This issue was discussed in more detail in the IIO mailing list.
Link: https://lore.kernel.org/all/20221023132302.911644-11-u.kleine-koenig@pengutronix.de/
Suggested-by: Nuno Sá <noname.nuno@gmail.com>
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Angel Iglesias <ang.iglesiasg@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Stable-dep-of: 4e4b9f5ce9df ("power: supply: max17040: drop incorrect I2C functionality check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 14 ++++++++++++++
include/linux/i2c.h | 1 +
2 files changed, 15 insertions(+)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index e8fb84c7cfd85..cfb1454c48b9f 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -2432,6 +2432,20 @@ int i2c_get_device_id(const struct i2c_client *client,
}
EXPORT_SYMBOL_GPL(i2c_get_device_id);
+/**
+ * i2c_client_get_device_id - get the driver match table entry of a device
+ * @client: the device to query. The device must be bound to a driver
+ *
+ * Returns a pointer to the matching entry if found, NULL otherwise.
+ */
+const struct i2c_device_id *i2c_client_get_device_id(const struct i2c_client *client)
+{
+ const struct i2c_driver *drv = to_i2c_driver(client->dev.driver);
+
+ return i2c_match_id(drv->id_table, client);
+}
+EXPORT_SYMBOL_GPL(i2c_client_get_device_id);
+
/* ----------------------------------------------------
* the i2c address scanning function
* Will not work for 10-bit addresses!
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 87b403a6d7e41..60c5bc674dcce 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -189,6 +189,7 @@ s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
u8 *values);
int i2c_get_device_id(const struct i2c_client *client,
struct i2c_device_identity *id);
+const struct i2c_device_id *i2c_client_get_device_id(const struct i2c_client *client);
#endif /* I2C */
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0088/1887] power: supply: max17040: Convert to i2cs .probe_new()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0087/1887] i2c: core: Introduce i2c_client_get_device_id helper function Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0089/1887] power: supply: max17040: drop incorrect I2C functionality check Greg Kroah-Hartman
` (910 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König,
Sebastian Reichel, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit a07fca69378c26ea034826feb0011256e25ad237 ]
.probe_new() doesn't get the i2c_device_id * parameter, so determine
that explicitly in the probe function.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 4e4b9f5ce9df ("power: supply: max17040: drop incorrect I2C functionality check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/max17040_battery.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
index 04b61692da300..8e913f92af9cd 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -430,9 +430,9 @@ static const struct power_supply_desc max17040_battery_desc = {
.num_properties = ARRAY_SIZE(max17040_battery_props),
};
-static int max17040_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int max17040_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct i2c_adapter *adapter = client->adapter;
struct power_supply_config psy_cfg = {};
struct max17040_chip *chip;
@@ -599,7 +599,7 @@ static struct i2c_driver max17040_i2c_driver = {
.of_match_table = max17040_of_match,
.pm = MAX17040_PM_OPS,
},
- .probe = max17040_probe,
+ .probe_new = max17040_probe,
.id_table = max17040_id,
};
module_i2c_driver(max17040_i2c_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0089/1887] power: supply: max17040: drop incorrect I2C functionality check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0088/1887] power: supply: max17040: Convert to i2cs .probe_new() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0090/1887] mmc: via-sdmmc: cancel card-detect work on remove Greg Kroah-Hartman
` (909 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jianing Li, Sebastian Reichel,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianing Li <m13940358460@163.com>
[ Upstream commit 4e4b9f5ce9dfb8ed4b8d1262a504b8043ac09d87 ]
max17040_probe() rejects adapters that do not advertise
I2C_FUNC_SMBUS_BYTE. The driver does not issue SMBus byte transactions,
however. Its regmap has 8-bit registers and 16-bit big-endian values, for
which regmap-i2c supports either raw I2C transfers or SMBus word-data
transactions.
Consequently, an adapter providing raw I2C transfers or SMBus word data
but not SMBus byte transactions is rejected even though regmap can access
the device. Conversely, the current check can pass an adapter that regmap
cannot use.
Drop the stale check and let devm_regmap_init_i2c() validate and select
the supported transfer method.
Fixes: 6455a8a84bdfd ("power: supply: max17040: Use regmap i2c")
Cc: stable@vger.kernel.org
Signed-off-by: Jianing Li <m13940358460@163.com>
Link: https://patch.msgid.link/20260731084259.916-1-m13940358460@163.com
[Fixed Fixes tag, so that it points to the regmap introduction instead of the initial driver addition]
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/max17040_battery.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
index 8e913f92af9cd..2017acf67a32c 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -433,16 +433,12 @@ static const struct power_supply_desc max17040_battery_desc = {
static int max17040_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
- struct i2c_adapter *adapter = client->adapter;
struct power_supply_config psy_cfg = {};
struct max17040_chip *chip;
enum chip_id chip_id;
bool enable_irq = false;
int ret;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
- return -EIO;
-
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0090/1887] mmc: via-sdmmc: cancel card-detect work on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0089/1887] power: supply: max17040: drop incorrect I2C functionality check Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0091/1887] hwrng: stm32 - Fix runtime PM cleanup on registration failure Greg Kroah-Hartman
` (908 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 57e5d877f898d5e5c9d672a77bb6bdd24f0d9bf5 ]
Disabling the device interrupt and freeing the IRQ prevents new card-detect
work from being queued, but carddet_work already queued by the handler can
still run after via_sd_remove() returns. via_sdc_card_detect() recovers the
host through container_of() and dereferences its MMIO base; once remove()
returns the host can be freed, so that work would touch freed memory.
Cancel carddet_work after freeing the IRQ and before cancelling
finish_bh_work, which the card-detect handler can also queue. carddet_work
can re-enable the interrupt through via_reset_pcictrl(); mask it again
afterwards.
This issue was found by an in-house static analysis tool and confirmed by
manual code review.
Fixes: f0bf7f61b840 ("mmc: Add new via-sdmmc host controller driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
[ adjusted context to retain del_timer_sync() instead of timer_delete_sync(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mmc/host/via-sdmmc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 5bf508b6db0e3..3ae8f005f8fe0 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1208,6 +1208,10 @@ static void via_sd_remove(struct pci_dev *pcidev)
free_irq(pcidev->irq, sdhost);
+ cancel_work_sync(&sdhost->carddet_work);
+ /* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
+ writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
+
del_timer_sync(&sdhost->timer);
tasklet_kill(&sdhost->finish_tasklet);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0091/1887] hwrng: stm32 - Fix runtime PM cleanup on registration failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0090/1887] mmc: via-sdmmc: cancel card-detect work on remove Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0092/1887] i3c: master: Do not treat master device as a duplicate target Greg Kroah-Hartman
` (907 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Can Peng, Linus Walleij, Herbert Xu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Can Peng <pengcan@kylinos.cn>
[ Upstream commit 1163a476a568f6c0f852d469c8e4c5a5f805adac ]
stm32_rng_probe() enables autosuspend and runtime PM before registering the
hwrng. If devm_hwrng_register() fails, probe returns with runtime PM left
enabled and autosuspend still selected.
The remove callback also only disables runtime PM and does not undo
pm_runtime_use_autosuspend().
Use devm_pm_runtime_enable() so runtime PM is unwound automatically on
probe failure and driver detach. Since the managed cleanup also disables
runtime PM,drop the remove callback.
Fixes: c6a97c42e399 ("hwrng: stm32 - add support for STM32 HW RNG")
Cc: stable@vger.kernel.org
Signed-off-by: Can Peng <pengcan@kylinos.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[ adapted to the older driver’s relocated int-returning remove callback and existing err variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/char/hw_random/stm32-rng.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
index bc22178f83e83..440c001c746b1 100644
--- a/drivers/char/hw_random/stm32-rng.c
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -156,18 +156,13 @@ static int stm32_rng_probe(struct platform_device *ofdev)
pm_runtime_set_autosuspend_delay(dev, 100);
pm_runtime_use_autosuspend(dev);
- pm_runtime_enable(dev);
+ err = devm_pm_runtime_enable(dev);
+ if (err)
+ return err;
return devm_hwrng_register(dev, &priv->rng);
}
-static int stm32_rng_remove(struct platform_device *ofdev)
-{
- pm_runtime_disable(&ofdev->dev);
-
- return 0;
-}
-
#ifdef CONFIG_PM
static int stm32_rng_runtime_suspend(struct device *dev)
{
@@ -209,7 +204,6 @@ static struct platform_driver stm32_rng_driver = {
.of_match_table = stm32_rng_match,
},
.probe = stm32_rng_probe,
- .remove = stm32_rng_remove,
};
module_platform_driver(stm32_rng_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0092/1887] i3c: master: Do not treat master device as a duplicate target
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0091/1887] hwrng: stm32 - Fix runtime PM cleanup on registration failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0093/1887] i3c: master: Fix use-after-free of master->this Greg Kroah-Hartman
` (906 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adrian Hunter, Frank Li,
Mukesh Savaliya, Alexandre Belloni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <adrian.hunter@intel.com>
[ Upstream commit 4dc1b3eeba7991905a5b5b8129ebea51be7d87b7 ]
i3c_master_search_i3c_dev_duplicate() searches the bus for another I3C
device with the same PID as the reference device. The search can match
master->this, causing the controller itself to be returned as a
duplicate.
Since the controller is not a target device, it cannot be a duplicate of
one. Exclude master->this from matching so that the function only
returns real duplicate target devices.
Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Acked-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>
Link: https://patch.msgid.link/20260807145638.168865-4-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ adjusted the duplicate-device comparison to match the older branch’s PID handling without nonzero-PID checks. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i3c/master.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 059ddd50e8590..d0f5ae21ea1f3 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1978,7 +1978,8 @@ i3c_master_search_i3c_dev_duplicate(struct i3c_dev_desc *refdev)
struct i3c_dev_desc *i3cdev;
i3c_bus_for_each_i3cdev(&master->bus, i3cdev) {
- if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid)
+ if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid &&
+ i3cdev != master->this)
return i3cdev;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0093/1887] i3c: master: Fix use-after-free of master->this
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0092/1887] i3c: master: Do not treat master device as a duplicate target Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0094/1887] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers() Greg Kroah-Hartman
` (905 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adrian Hunter, Frank Li,
Alexandre Belloni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <adrian.hunter@intel.com>
[ Upstream commit feb0ed76601f3c2f91f08688c5a7d8b9d382f720 ]
sysfs attribute callbacks for the master controller device dereference
master->this. However, master->this is freed in
i3c_master_detach_free_devs() before the master device itself is
released.
As a result, sysfs accesses can dereference a freed master->this
pointer, leading to a use-after-free.
Keep master->this alive until i3c_masterdev_release(), which is called
after the master device and its sysfs state are being torn down. Do not
free master->this as part of the normal device detach path.
On the error path in i3c_master_set_info(), reset master->this and
bus.cur_master to NULL before freeing the allocated device.
Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260807145638.168865-5-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ retained of_node_put(dev->of_node) instead of upstream’s fwnode_handle_put(dev->fwnode). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i3c/master.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index d0f5ae21ea1f3..cbc3f2d24b618 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -667,6 +667,11 @@ static struct attribute *i3c_masterdev_attrs[] = {
};
ATTRIBUTE_GROUPS(i3c_masterdev);
+static void i3c_master_free_i3c_dev(struct i3c_dev_desc *dev)
+{
+ kfree(dev);
+}
+
static void i3c_masterdev_release(struct device *dev)
{
struct i3c_master_controller *master = dev_to_i3cmaster(dev);
@@ -679,6 +684,8 @@ static void i3c_masterdev_release(struct device *dev)
i3c_bus_cleanup(bus);
of_node_put(dev->of_node);
+
+ i3c_master_free_i3c_dev(master->this);
}
static const struct device_type i3c_masterdev_type = {
@@ -866,11 +873,6 @@ static void i3c_device_release(struct device *dev)
kfree(i3cdev);
}
-static void i3c_master_free_i3c_dev(struct i3c_dev_desc *dev)
-{
- kfree(dev);
-}
-
static struct i3c_dev_desc *
i3c_master_alloc_i3c_dev(struct i3c_master_controller *master,
const struct i3c_device_info *info)
@@ -1738,6 +1740,8 @@ int i3c_master_set_info(struct i3c_master_controller *master,
return 0;
err_free_dev:
+ master->bus.cur_master = NULL;
+ master->this = NULL;
i3c_master_free_i3c_dev(i3cdev);
return ret;
@@ -1758,7 +1762,8 @@ static void i3c_master_detach_free_devs(struct i3c_master_controller *master)
i3cdev->boardinfo->init_dyn_addr,
I3C_ADDR_SLOT_FREE);
- i3c_master_free_i3c_dev(i3cdev);
+ if (i3cdev != master->this)
+ i3c_master_free_i3c_dev(i3cdev);
}
list_for_each_entry_safe(i2cdev, i2ctmp, &master->bus.devs.i2c,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0094/1887] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0093/1887] i3c: master: Fix use-after-free of master->this Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0095/1887] spi: bcm63xx: switch to use modern name Greg Kroah-Hartman
` (904 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+791be35f1fbcc85d06d7, stable,
Jeffin Philip, Alan Stern, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeffin Philip <jeffinphilip14@gmail.com>
[ Upstream commit 2c0f5ca48674a5b5f9fa4a9c3325aa48053af0bc ]
Previously fsg_num_buffers_validate() was removed as it was not
necessary due to Kconfig setting the limits for n from 2 to 256 with
default as 2. However, setting the page content in such a way that
kstrtou8() reflects n value as either 0 or 1 bypasses these
restrictions leading to a null pointer dereference if n is 0. Fix
this by adding a check for n < 2 and returning -EINVAL if n is
either 0 or 1 consistent with Kconfig logic.
Reported-by: syzbot+791be35f1fbcc85d06d7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=791be35f1fbcc85d06d7
Fixes: fe5a6c48fd95 ("usb: gadget: storage: get rid of fsg_num_buffers_validate()")
Cc: stable <stable@kernel.org>
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260818035904.10324-1-jeffinphilip14@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ adjusted context to retain the branch’s existing kcalloc() call instead of kzalloc_objs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_mass_storage.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index a40be63aca291..5618ca904f5d0 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2747,6 +2747,9 @@ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
struct fsg_buffhd *bh, *buffhds;
int i;
+ if (n < 2)
+ return -EINVAL;
+
buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL);
if (!buffhds)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0095/1887] spi: bcm63xx: switch to use modern name
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0094/1887] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0096/1887] spi: bcm63xx: disable clock on resume failure Greg Kroah-Hartman
` (903 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yang Yingliang, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <yangyingliang@huawei.com>
[ Upstream commit 1a9e76190f72e4e3aaf7eb89da22876846ff9b3d ]
Change legacy name master to modern name host or controller.
No functional changed.
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Link: https://lore.kernel.org/r/20230728093221.3312026-9-yangyingliang@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 2b62c2c134fa ("spi: bcm63xx: disable clock on resume failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-bcm63xx.c | 68 +++++++++++++++++++--------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index e57e1f75cd9f9..80a88d38ec00d 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -196,7 +196,7 @@ static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u8 clk_cfg, reg;
int i;
@@ -227,7 +227,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
unsigned int num_transfers)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u16 msg_ctl;
u16 cmd;
unsigned int i, timeout = 0, prepend_len = 0, len = 0;
@@ -336,10 +336,10 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
return 0;
}
-static int bcm63xx_spi_transfer_one(struct spi_master *master,
+static int bcm63xx_spi_transfer_one(struct spi_controller *host,
struct spi_message *m)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
struct spi_transfer *t, *first = NULL;
struct spi_device *spi = m->spi;
int status = 0;
@@ -409,18 +409,18 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
}
exit:
m->status = status;
- spi_finalize_current_message(master);
+ spi_finalize_current_message(host);
return 0;
}
-/* This driver supports single master mode only. Hence
+/* This driver supports single host mode only. Hence
* CMD_DONE is the only interrupt we care about
*/
static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
{
- struct spi_master *master = (struct spi_master *)dev_id;
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *host = (struct spi_controller *)dev_id;
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
u8 intr;
/* Read interupts and clear them immediately */
@@ -437,7 +437,7 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
static size_t bcm63xx_spi_max_length(struct spi_device *spi)
{
- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
return bs->fifo_size;
}
@@ -505,7 +505,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
const unsigned long *bcm63xx_spireg;
struct device *dev = &pdev->dev;
int irq, bus_num;
- struct spi_master *master;
+ struct spi_controller *host;
struct clk *clk;
struct bcm63xx_spi *bs;
int ret;
@@ -551,16 +551,16 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
if (IS_ERR(reset))
return PTR_ERR(reset);
- master = spi_alloc_master(dev, sizeof(*bs));
- if (!master) {
+ host = spi_alloc_host(dev, sizeof(*bs));
+ if (!host) {
dev_err(dev, "out of memory\n");
return -ENOMEM;
}
- bs = spi_master_get_devdata(master);
+ bs = spi_controller_get_devdata(host);
init_completion(&bs->done);
- platform_set_drvdata(pdev, master);
+ platform_set_drvdata(pdev, host);
bs->pdev = pdev;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -576,21 +576,21 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];
ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
- pdev->name, master);
+ pdev->name, host);
if (ret) {
dev_err(dev, "unable to request irq\n");
goto out_err;
}
- master->dev.of_node = dev->of_node;
- master->bus_num = bus_num;
- master->num_chipselect = num_cs;
- master->transfer_one_message = bcm63xx_spi_transfer_one;
- master->mode_bits = MODEBITS;
- master->bits_per_word_mask = SPI_BPW_MASK(8);
- master->max_transfer_size = bcm63xx_spi_max_length;
- master->max_message_size = bcm63xx_spi_max_length;
- master->auto_runtime_pm = true;
+ host->dev.of_node = dev->of_node;
+ host->bus_num = bus_num;
+ host->num_chipselect = num_cs;
+ host->transfer_one_message = bcm63xx_spi_transfer_one;
+ host->mode_bits = MODEBITS;
+ host->bits_per_word_mask = SPI_BPW_MASK(8);
+ host->max_transfer_size = bcm63xx_spi_max_length;
+ host->max_message_size = bcm63xx_spi_max_length;
+ host->auto_runtime_pm = true;
bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT];
bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH];
bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]);
@@ -614,7 +614,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
goto out_clk_disable;
/* register and we are done */
- ret = devm_spi_register_master(dev, master);
+ ret = devm_spi_register_controller(dev, host);
if (ret) {
dev_err(dev, "spi register failed\n");
goto out_clk_disable;
@@ -628,14 +628,14 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
out_clk_disable:
clk_disable_unprepare(clk);
out_err:
- spi_master_put(master);
+ spi_controller_put(host);
return ret;
}
static int bcm63xx_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *host = platform_get_drvdata(pdev);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
@@ -649,10 +649,10 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int bcm63xx_spi_suspend(struct device *dev)
{
- struct spi_master *master = dev_get_drvdata(dev);
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *host = dev_get_drvdata(dev);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
- spi_master_suspend(master);
+ spi_controller_suspend(host);
clk_disable_unprepare(bs->clk);
@@ -661,15 +661,15 @@ static int bcm63xx_spi_suspend(struct device *dev)
static int bcm63xx_spi_resume(struct device *dev)
{
- struct spi_master *master = dev_get_drvdata(dev);
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *host = dev_get_drvdata(dev);
+ struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
int ret;
ret = clk_prepare_enable(bs->clk);
if (ret)
return ret;
- spi_master_resume(master);
+ spi_controller_resume(host);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0096/1887] spi: bcm63xx: disable clock on resume failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0095/1887] spi: bcm63xx: switch to use modern name Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0097/1887] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit() Greg Kroah-Hartman
` (902 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Can Peng, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Can Peng <pengcan@kylinos.cn>
[ Upstream commit 2b62c2c134fa32d9d3a9e7323c8ac74518eeb4ac ]
bcm63xx_spi_resume() enables the controller clock before restarting the
SPI controller queue.
If spi_controller_resume() fails, the function currently reports success
and leaves the clock enabled. Propagate the error and disable the clock
before returning.
Fixes: b42dfed83d95 ("spi: add Broadcom BCM63xx SPI controller driver")
Cc: stable@vger.kernel.org
Signed-off-by: Can Peng <pengcan@kylinos.cn>
Link: https://patch.msgid.link/20260804071831.860784-1-pengcan@kylinos.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-bcm63xx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index 80a88d38ec00d..cf0456f41a379 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -669,7 +669,11 @@ static int bcm63xx_spi_resume(struct device *dev)
if (ret)
return ret;
- spi_controller_resume(host);
+ ret = spi_controller_resume(host);
+ if (ret) {
+ clk_disable_unprepare(bs->clk);
+ return ret;
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0097/1887] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0096/1887] spi: bcm63xx: disable clock on resume failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0098/1887] ftrace: Synchronize the initialization of ftrace_ops Greg Kroah-Hartman
` (901 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Muhammad Bilal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <meatuni001@gmail.com>
[ Upstream commit cc7cd2a9228175c975f62ad56ed7c767701cb4fa ]
sm750_hw_imageblit() advances its monochrome source pointer by
src_delta per scanline, and computes the correct rounded-up stride
internally as:
bytes_per_scan = (width + start_bit + 7) / 8;
Its only caller, lynxfb_ops_imageblit(), instead passed src_delta as
image->width >> 3. For widths not a multiple of 8 this under-counted
the stride, so the source pointer fell further behind the real
per-scanline layout on every line, corrupting the rendered image.
Rather than just fixing the caller's calculation, remove src_delta
as a parameter entirely and have sm750_hw_imageblit() advance by the
bytes_per_scan it already computes for itself. There has only ever
been one caller, and that caller was passing an out-of-sync
derivative of the same width/start_bit values sm750_hw_imageblit()
already has, so keeping stride as a separate parameter served no
purpose beyond letting the two calculations drift apart, which is
exactly what happened here.
Rounding up, rather than down, is the direction consistent with the
rest of the fbdev core: struct fb_image mono bitmap data (the same
image->data this driver receives) is walked elsewhere with byte
strides derived from a ceiling division of width by 8. The generic
mono bit iterator in drivers/video/fbdev/core/fb_imageblit.h advances
scanlines with "iter->data += BITS_TO_BYTES(iter->width)", and
BITS_TO_BYTES() (include/linux/bitops.h) is a ceiling division.
sm750_hw_imageblit()'s own "(width + start_bit + 7) / 8" is that same
ceiling division with an added start_bit offset, so the caller's
">> 3" (floor) was the one calculation out of step with how this data
layout is handled everywhere else.
Found by code review of sm750_hw_imageblit()'s internal stride
calculation against what its only caller was passing in, and
confirmed with a clean -Werror build. I do not have this hardware,
so this has not been exercised at runtime on real sm750 silicon.
Fixes: 81dee67e215b2 ("staging: sm750fb: add sm750 to staging")
Cc: stable@vger.kernel.org
Reviewed-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260901113031.161610-1-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/sm750fb/sm750.c | 2 +-
drivers/staging/sm750fb/sm750.h | 2 +-
drivers/staging/sm750fb/sm750_accel.c | 6 ++----
drivers/staging/sm750fb/sm750_accel.h | 4 +---
4 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 758759b706d47..ad41ba284a3af 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -276,7 +276,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
spin_lock(&sm750_dev->slock);
sm750_dev->accel.de_imageblit(&sm750_dev->accel,
- image->data, image->width >> 3, 0,
+ image->data, 0,
base, pitch, Bpp,
image->dx, image->dy,
image->width, image->height,
diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h
index aff69661c8e62..a693d9f1d0d5e 100644
--- a/drivers/staging/sm750fb/sm750.h
+++ b/drivers/staging/sm750fb/sm750.h
@@ -73,7 +73,7 @@ struct lynx_accel {
u32 rop2);
int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf,
- u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch,
+ u32 start_bit, u32 d_base, u32 d_pitch,
u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
u32 height, u32 f_color, u32 b_color, u32 rop2);
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 24b9077a634a6..eb47c18a585d0 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -301,8 +301,6 @@ static unsigned int deGetTransparency(struct lynx_accel *accel)
* sm750_hw_imageblit
* @accel: Acceleration device data
* @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
- * and -ive mean button up
* @startBit: Mono data can start at any bit in a byte, this value should be
* 0 to 7
* @dBase: Address of destination: offset in frame buffer
@@ -317,7 +315,7 @@ static unsigned int deGetTransparency(struct lynx_accel *accel)
* @rop2: ROP value
*/
int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
- u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
+ u32 startBit, u32 dBase, u32 dPitch,
u32 bytePerPixel, u32 dx, u32 dy, u32 width,
u32 height, u32 fColor, u32 bColor, u32 rop2)
{
@@ -406,7 +404,7 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
write_dpPort(accel, *(unsigned int *)ajRemain);
}
- pSrcbuf += srcDelta;
+ pSrcbuf += ulBytesPerScan;
}
return 0;
diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h
index 2c79cb730a0a6..df48ed57a054e 100644
--- a/drivers/staging/sm750fb/sm750_accel.h
+++ b/drivers/staging/sm750fb/sm750_accel.h
@@ -220,8 +220,6 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
/**
* sm750_hw_imageblit
* @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
- *>----- and -ive mean button up
* @startBit: Mono data can start at any bit in a byte, this value should be
*>----- 0 to 7
* @dBase: Address of destination: offset in frame buffer
@@ -236,7 +234,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
* @rop2: ROP value
*/
int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
- u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
+ u32 startBit, u32 dBase, u32 dPitch,
u32 bytePerPixel, u32 dx, u32 dy, u32 width,
u32 height, u32 fColor, u32 bColor, u32 rop2);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0098/1887] ftrace: Synchronize the initialization of ftrace_ops
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0097/1887] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0099/1887] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm Greg Kroah-Hartman
` (900 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Steven Rostedt,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 4617721c502b2ddaa4e324e86da4997edf738fa5 ]
There's some internal state that ftrace_ops needs to have set, but since
it can be declared outside of the ftrace.c code, it calls
ftrace_ops_init() on the ops in every global function. The issue is that
if two tasks call it on the same ops at the same time it is possible to
have the initialization of one corrupt the initialization of the other
call.
Create a ops_mutex to use to synchronize every initialization of the
ftrace_ops. The mutex is taken within checking the ftrace_ops flag that
states it was initializied but the flag is checked again after the mutex
has been taken. Checking first outside the mutex allows it to shortcut
having to take the mutex. But then the check needs to be done again after
the mute is taken in case of races.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home
Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock")
Reported-by: sashiko-bot@kernel.org
Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ adjusted INIT_OPS_HASH macro context for the missing subop_list member. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/ftrace.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eee7bb2843940..359cea3478b65 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -71,6 +71,8 @@
#define INIT_OPS_HASH(opsname) \
.func_hash = &opsname.local_hash, \
.local_hash.regex_lock = __MUTEX_INITIALIZER(opsname.local_hash.regex_lock),
+/* Used only to synchronize the initialization of ftrace_ops */
+static DEFINE_MUTEX(ops_mutex);
#else
#define INIT_OPS_HASH(opsname)
#endif
@@ -128,10 +130,17 @@ void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
static inline void ftrace_ops_init(struct ftrace_ops *ops)
{
#ifdef CONFIG_DYNAMIC_FTRACE
- if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED)) {
+ unsigned long flags = smp_load_acquire(&ops->flags);
+
+ if (!(flags & FTRACE_OPS_FL_INITIALIZED)) {
+ guard(mutex)(&ops_mutex);
+ /* Could have been initialized before lock taken */
+ if (unlikely(ops->flags & FTRACE_OPS_FL_INITIALIZED))
+ return;
mutex_init(&ops->local_hash.regex_lock);
ops->func_hash = &ops->local_hash;
- ops->flags |= FTRACE_OPS_FL_INITIALIZED;
+ flags = ops->flags | FTRACE_OPS_FL_INITIALIZED;
+ smp_store_release(&ops->flags, flags);
}
#endif
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0099/1887] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0098/1887] ftrace: Synchronize the initialization of ftrace_ops Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0100/1887] arm64: allow pte_offset_map() to fail Greg Kroah-Hartman
` (899 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lad Prabhakar, Wolfram Sang,
Alexandre Belloni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
[ Upstream commit 457b5dbce31209e65e1184716ed3af59cb1c0372 ]
RZN1_RTC_ALW is a weekday bitmask where bit N represents weekday N.
When no alarm has been configured, the register has its power-on-reset
value of zero.
rzn1_rtc_read_alarm() uses fls() to convert the weekday bitmask into a
weekday number. When RZN1_RTC_ALW is zero, fls(0) returns zero and
fls(wday) - 1 evaluates to -1. This invalid weekday is then used to
calculate the alarm date and can either leave tm_wday set to -1 or
produce a fabricated alarm date.
Treat a zero RZN1_RTC_ALW value as an unset alarm weekday and return
without calculating the alarm date. Move reading RZN1_RTC_CTL1 before
this check so that alrm->enabled is updated for both configured and
unconfigured alarms.
Fixes: b5ad1bf00d2c4 ("rtc: rzn1: Add alarm support")
Cc: stable@vger.kernel.org
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://patch.msgid.link/20260821211032.13554-5-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ retained the ALME-only enable check because RZN1_RTC_CTL1_1SE is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/rtc/rtc-rzn1.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 36381385d2628..cf9154a62d463 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -193,13 +193,24 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret)
return ret;
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME);
+
min = readl(rtc->base + RZN1_RTC_ALM);
hour = readl(rtc->base + RZN1_RTC_ALH);
- wday = readl(rtc->base + RZN1_RTC_ALW);
tm->tm_sec = 0;
tm->tm_min = bcd2bin(min);
tm->tm_hour = bcd2bin(hour);
+
+ /*
+ * If wday is zero, no bit is set in RZN1_RTC_ALW. This is the
+ * register's power-on reset value.
+ */
+ wday = readl(rtc->base + RZN1_RTC_ALW);
+ if (!wday)
+ return 0;
+
delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7;
tm->tm_wday = fls(wday) - 1;
@@ -208,9 +219,6 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
rtc_time64_to_tm(alarm, tm);
}
- ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
- alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME);
-
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0100/1887] arm64: allow pte_offset_map() to fail
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0099/1887] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0101/1887] arm64: mm: Fix the lockless page-table walk in show_pte() Greg Kroah-Hartman
` (898 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hugh Dickins, Catalin Marinas,
Alexander Gordeev, Alexandre Ghiti, Aneesh Kumar K.V,
Christian Borntraeger, Chris Zankel, Claudio Imbrenda,
David Hildenbrand, David S. Miller, Geert Uytterhoeven,
Greg Ungerer, Heiko Carstens, Helge Deller, H. Peter Anvin,
Ingo Molnar, John David Anglin, John Paul Adrian Glaubitz,
Kirill A. Shutemov, Matthew Wilcox (Oracle), Max Filippov,
Michael Ellerman, Michal Simek, Mike Kravetz, Mike Rapoport (IBM),
Palmer Dabbelt, Peter Zijlstra, Qi Zheng, Russell King,
Suren Baghdasaryan, Thomas Bogendoerfer, Thomas Gleixner,
Will Deacon, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugh Dickins <hughd@google.com>
[ Upstream commit 52924726f4c06b3f77de75fb665e6efd8e777d07 ]
In rare transient cases, not yet made possible, pte_offset_map() and
pte_offset_map_lock() may not find a page table: handle appropriately.
Link: https://lkml.kernel.org/r/35e46485-8499-4337-c51f-b8fa495a1a93@google.com
Signed-off-by: Hugh Dickins <hughd@google.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greg Ungerer <gerg@linux-m68k.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Helge Deller <deller@gmx.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: John David Anglin <dave.anglin@bell.net>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: a77644d009de ("arm64: mm: Fix the lockless page-table walk in show_pte()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/mm/fault.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 0776c98ad27f1..c4120bd80a9b4 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -177,6 +177,9 @@ static void show_pte(unsigned long addr)
break;
ptep = pte_offset_map(pmdp, addr);
+ if (!ptep)
+ break;
+
pte = READ_ONCE(*ptep);
pr_cont(", pte=%016llx", pte_val(pte));
pte_unmap(ptep);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0101/1887] arm64: mm: Fix the lockless page-table walk in show_pte()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0100/1887] arm64: allow pte_offset_map() to fail Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0102/1887] nvme-fabrics: fix DHCHAP secret leak on parse failure Greg Kroah-Hartman
` (897 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Will Deacon,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit a77644d009dece1104b6fcc6e322b0e4503db0d6 ]
show_pte() walks page tables locklessly and can run with interrupts
enabled. A concurrent teardown can free a table page while it is being
walked. It can also clear a parent entry after show_pte() checked it; the
regular pXd_offset() helpers then reread the cleared entry and can derive a
bogus lower-level pointer and fault again.
Use the lockless offset helpers with the saved parent entries, as
gup_fast() does, and pass the saved PMD to pte_offset_map().
For task page tables, arm64 selects MMU_GATHER_RCU_TABLE_FREE. Disable
local interrupts around the walk to hold off RCU-deferred table frees and
block the tlb_remove_table_sync_one() IPI until the walk is finished.
Place the IRQ guard after the header print. This does not make the output a
consistent snapshot, but prevents the task page-table walk from
dereferencing a released table page or deriving a pointer from a different
parent value.
Fixes: 1d18c47c735e ("arm64: MMU fault handling and page table management")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/mm/fault.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index c4120bd80a9b4..5bd5e10c49f18 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/init.h>
+#include <linux/irqflags.h>
#include <linux/kasan.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
@@ -145,6 +146,9 @@ static void show_pte(unsigned long addr)
pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
vabits_actual, mm_to_pgd_phys(mm));
+
+ guard(irqsave)();
+
pgdp = pgd_offset(mm, addr);
pgd = READ_ONCE(*pgdp);
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
@@ -158,25 +162,25 @@ static void show_pte(unsigned long addr)
if (pgd_none(pgd) || pgd_bad(pgd))
break;
- p4dp = p4d_offset(pgdp, addr);
+ p4dp = p4d_offset_lockless(pgdp, pgd, addr);
p4d = READ_ONCE(*p4dp);
pr_cont(", p4d=%016llx", p4d_val(p4d));
if (p4d_none(p4d) || p4d_bad(p4d))
break;
- pudp = pud_offset(p4dp, addr);
+ pudp = pud_offset_lockless(p4dp, p4d, addr);
pud = READ_ONCE(*pudp);
pr_cont(", pud=%016llx", pud_val(pud));
if (pud_none(pud) || pud_bad(pud))
break;
- pmdp = pmd_offset(pudp, addr);
+ pmdp = pmd_offset_lockless(pudp, pud, addr);
pmd = READ_ONCE(*pmdp);
pr_cont(", pmd=%016llx", pmd_val(pmd));
if (pmd_none(pmd) || pmd_bad(pmd))
break;
- ptep = pte_offset_map(pmdp, addr);
+ ptep = pte_offset_map(&pmd, addr);
if (!ptep)
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0102/1887] nvme-fabrics: fix DHCHAP secret leak on parse failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0101/1887] arm64: mm: Fix the lockless page-table walk in show_pte() Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0103/1887] s390/vfio-ap: Fix NULL deref in status_show() during queue probe Greg Kroah-Hartman
` (896 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Xu Rao,
Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
[ Upstream commit afdee49a1b88ed9bb44e2b30e855297c169bcc53 ]
nvmf_parse_options() duplicates dhchap_secret and dhchap_ctrl_secret
with match_strdup() before validating the DHHC-1: representation.
If validation fails, the parser returns -EINVAL before the temporary
string in p is assigned to opts->dhchap_secret or
opts->dhchap_ctrl_secret. nvmf_create_ctrl() subsequently frees opts,
but nvmf_free_options() cannot release the unassigned temporary string.
Each rejected option therefore leaks one allocation.
This is easy to miss because valid secrets transfer ownership to opts
and are freed normally, while the malformed-secret path still returns
the expected -EINVAL to userspace.
With CONFIG_NVME_HOST_AUTH enabled, the leak is reachable before the
required-option checks and transport lookup. No NVMe-oF target or
working transport connection is required; for example, repeatedly
writing
dhchap_secret=BAD
or
dhchap_ctrl_secret=BAD
to /dev/nvme-fabrics deterministically takes the leaking parse path.
Free the temporary string before leaving both validation error paths.
Use kfree_sensitive() because the copied option may contain secret
material even when its representation is rejected, matching the
sensitive cleanup used for stored DHCHAP secrets.
Fixes: f50fff73d620 ("nvme: implement In-Band authentication")
Cc: stable@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/fabrics.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index ffe433c470894..eed78e6f2cdf6 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -898,6 +898,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
}
if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
pr_err("Invalid DH-CHAP secret %s\n", p);
+ kfree_sensitive(p);
ret = -EINVAL;
goto out;
}
@@ -912,6 +913,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
}
if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
pr_err("Invalid DH-CHAP secret %s\n", p);
+ kfree_sensitive(p);
ret = -EINVAL;
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0103/1887] s390/vfio-ap: Fix NULL deref in status_show() during queue probe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0102/1887] nvme-fabrics: fix DHCHAP secret leak on parse failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0104/1887] iio: pressure: dps310: fix NULL pointer dereference on ACPI probe Greg Kroah-Hartman
` (895 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anthony Krowiak, Matthew Rosato,
Christian Borntraeger, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anthony Krowiak <akrowiak@linux.ibm.com>
[ Upstream commit dd6f4ef6f8a37412909ad787c837332fb070159c ]
When vfio_ap_mdev_probe_queue() creates the sysfs attribute group,
the queue's driver data has not yet been set. A concurrent read of
the 'status' attribute can therefore call dev_get_drvdata() and
get NULL, which is then passed directly to
vfio_ap_mdev_for_queue() where q->apqn is unconditionally
dereferenced, causing a NULL pointer dereference.
Fix this by acquiring the update locks before calling
sysfs_create_group(). The status_show() function acquires
guests_lock before reading the driver data, so any concurrent
read will block until after dev_set_drvdata() has been called
and the update locks are released.
As a bonus, the APQN no longer needs to be read from the queue
struct after allocation — it can be read directly from apdev
before allocation and stored in a local variable, which is then
assigned to q->apqn once the allocation succeeds.
Fixes: 260f3ea141382 ("s390/vfio-ap: move probe and remove callbacks to vfio_ap_ops.c")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
[ Adjusted queue-initialization context because Linux 6.1 lacks the newer reset fields. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/crypto/vfio_ap_ops.c | 33 +++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 34dfe7493173e..0d884f340dc1c 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1768,6 +1768,23 @@ static ssize_t status_show(struct device *dev,
mutex_lock(&matrix_dev->mdevs_lock);
q = dev_get_drvdata(&apdev->device);
+
+ /*
+ * Make sure the drvdata has been set before proceeding. There is a
+ * possibility that the drvdata was not set if the vfio_ap_queue object
+ * could not be allocated when the queue device was probed. In that case,
+ * the locks used in vfio_ap_mdev_probe_queue() are released prior to
+ * removing the sysfs status attribute to avoid a lockdep
+ * splat. That opens a very small window where the status attribute is
+ * still available without the vfio_ap_queue object having been
+ * stored in the device drvdata. In that case, indicate the queue is not
+ * assigned.
+ */
+ if (!q) {
+ nchars = sysfs_emit(buf, "%s\n", AP_QUEUE_UNASSIGNED);
+ goto done;
+ }
+
matrix_mdev = vfio_ap_mdev_for_queue(q);
/* If the queue is assigned to the matrix mediated device, then
@@ -1795,6 +1812,7 @@ static ssize_t status_show(struct device *dev,
AP_QUEUE_UNASSIGNED);
}
+done:
mutex_unlock(&matrix_dev->mdevs_lock);
return nchars;
@@ -1864,13 +1882,16 @@ void vfio_ap_mdev_unregister(void)
int vfio_ap_mdev_probe_queue(struct ap_device *apdev)
{
- int ret;
+ int ret, apqn;
struct vfio_ap_queue *q;
struct ap_matrix_mdev *matrix_mdev;
+ apqn = to_ap_queue(&apdev->device)->qid;
+ matrix_mdev = get_update_locks_by_apqn(apqn);
+
ret = sysfs_create_group(&apdev->device.kobj, &vfio_queue_attr_group);
if (ret)
- return ret;
+ goto err_release_locks;
q = kzalloc(sizeof(*q), GFP_KERNEL);
if (!q) {
@@ -1878,9 +1899,8 @@ int vfio_ap_mdev_probe_queue(struct ap_device *apdev)
goto err_remove_group;
}
- q->apqn = to_ap_queue(&apdev->device)->qid;
+ q->apqn = apqn;
q->saved_isc = VFIO_AP_ISC_INVALID;
- matrix_mdev = get_update_locks_by_apqn(q->apqn);
if (matrix_mdev) {
vfio_ap_mdev_link_queue(matrix_mdev, q);
@@ -1907,8 +1927,13 @@ int vfio_ap_mdev_probe_queue(struct ap_device *apdev)
return 0;
err_remove_group:
+ release_update_locks_for_mdev(matrix_mdev);
sysfs_remove_group(&apdev->device.kobj, &vfio_queue_attr_group);
return ret;
+
+err_release_locks:
+ release_update_locks_for_mdev(matrix_mdev);
+ return ret;
}
void vfio_ap_mdev_remove_queue(struct ap_device *apdev)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0104/1887] iio: pressure: dps310: fix NULL pointer dereference on ACPI probe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0103/1887] s390/vfio-ap: Fix NULL deref in status_show() during queue probe Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0105/1887] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP Greg Kroah-Hartman
` (894 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rupesh Majhi, Jonathan Cameron,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rupesh Majhi <zoone.rupert@gmail.com>
[ Upstream commit 26e9213898fc949923188ef0aeea31fc87708836 ]
When the device is enumerated through its ACPI HID (IFX3100),
i2c_client_get_device_id() returns NULL: the ACPI-derived client name
does not match the driver's i2c_device_id table. dps310_probe() then
dereferences that NULL pointer in "iio->name = id->name" and crashes the
kernel during probe.
The IIO device name is always "dps310", so set it directly and drop the
now-unused device-id lookup.
Fixes: 72ff282819d0 ("iio: pressure: dps310: Add ACPI HID table")
Cc: stable@vger.kernel.org
Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/pressure/dps310.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
index 519fcd425b6a3..0057e14a45ddc 100644
--- a/drivers/iio/pressure/dps310.c
+++ b/drivers/iio/pressure/dps310.c
@@ -843,7 +843,7 @@ static int dps310_probe(struct i2c_client *client,
data->client = client;
mutex_init(&data->lock);
- iio->name = id->name;
+ iio->name = DPS310_DEV_NAME;
iio->channels = dps310_channels;
iio->num_channels = ARRAY_SIZE(dps310_channels);
iio->info = &dps310_info;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0105/1887] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0104/1887] iio: pressure: dps310: fix NULL pointer dereference on ACPI probe Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0106/1887] media: platform: mtk-mdp3: fix NULL deref on failed SCP lookup Greg Kroah-Hartman
` (893 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
syzbot+f12658786a4153df5113, Vlastimil Babka (SUSE), Kunwu Chan,
Pedro Falcato, Jann Horn, Liam R. Howlett, Li Xinhai,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 35b0fb391b0df57383bc15985bb769f4555c97ba ]
Uniquely an mremap() invocation using the MREMAP_DONTUNMAP flag can reset
a faulted VMA into an unfaulted one.
It does so after the page tables have been moved to the copied VMA with
MREMAP_DONTUNMAP leaving the old VMA in place which is naturally unfaulted
as the page tables it had are no longer present.
However, in doing so, it violates the invariant that the anonymous page
offset of an unfaulted VMA is vma->vm_start >> PAGE_SHIFT.
This is because a VMA may have been faulted in, mremap()'d (causing a
delta between its page offset and vma->vm_start >> PAGE_SHIFT), and then
mremap()'d again with MREMAP_DONTUNMAP resulting in the unfaulting.
This condition is a violation of a fundamental assumption in mm, but now
also triggers an assert in assert_sane_pgoff() which explicitly checks for
this condition.
Correct it by resetting the VMA's page offset at the point of completing
the MREMAP_DONTUNMAP operation.
Link: https://lore.kernel.org/20260825-fix-mremap-dontunmap-pgoff-v1-1-39a40b2c98b3@kernel.org
Fixes: 1583aa278f5f ("mm: mremap: unlink anon_vmas when mremap with MREMAP_DONTUNMAP success")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a87853b.ae6ddae5.3da009.0023.GAE@google.com/
Tested-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Li Xinhai <lixinhai.lxh@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ adapted dontunmap_complete() changes to move_vma() using direct vm_pgoff assignment instead of unavailable helpers. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mremap.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index 6ed28eeae5a84..7e39614d2e0e6 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -693,8 +693,18 @@ static unsigned long move_vma(struct vm_area_struct *vma,
* table has been moved.
*/
if (new_vma != vma && vma->vm_start == old_addr &&
- vma->vm_end == (old_addr + old_len))
+ vma->vm_end == (old_addr + old_len)) {
+ const pgoff_t pgoff_unfaulted = vma->vm_start >> PAGE_SHIFT;
+
unlink_anon_vmas(vma);
+ /*
+ * The VMA is now unfaulted and it is an invariant that
+ * unfaulted anonymous VMAs have page offset equal to
+ * vma->vm_start >> PAGE_SHIFT.
+ */
+ if (vma_is_anonymous(vma) && !vma->vm_file)
+ vma->vm_pgoff = pgoff_unfaulted;
+ }
/* Because we won't unmap we don't need to touch locked_vm */
return new_addr;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0106/1887] media: platform: mtk-mdp3: fix NULL deref on failed SCP lookup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0105/1887] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0107/1887] media: rkvdec: Propagate platform_get_irq() errors Greg Kroah-Hartman
` (892 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Moudy Ho, Johan Hovold,
Nicolas Dufresne, Hans Verkuil, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 90368323fb244da0504e3da37a182f8e89bcc3b9 ]
Add the missing sanity check after looking up the SCP to avoid
dereferencing a NULL-pointer in case its driver has not yet been bound.
Fixes: 61890ccaefaf ("media: platform: mtk-mdp3: add MediaTek MDP3 driver")
Cc: stable@vger.kernel.org # 6.1
Cc: Moudy Ho <moudy.ho@mediatek.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[ Adapted NULL-check placement to the older direct platform_get_drvdata() lookup. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 97edcd9d1c817..9a11064ecfa95 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -241,6 +241,11 @@ static int mdp_probe(struct platform_device *pdev)
goto err_destroy_clock_wq;
}
mdp->scp = platform_get_drvdata(mm_pdev);
+ if (!mdp->scp) {
+ ret = -EPROBE_DEFER;
+ goto err_destroy_clock_wq;
+ }
+
mdp->rproc_handle = scp_get_rproc(mdp->scp);
dev_dbg(&pdev->dev, "MDP rproc_handle: %pK", mdp->rproc_handle);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0107/1887] media: rkvdec: Propagate platform_get_irq() errors
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0106/1887] media: platform: mtk-mdp3: fix NULL deref on failed SCP lookup Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0108/1887] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
` (891 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Narasimharao Vadlamudi,
Detlev Casanova, Nicolas Dufresne, Hans Verkuil, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Narasimharao Vadlamudi <ahmisaranrao@gmail.com>
[ Upstream commit c37aca64206fafe938119e801a3fd10a537a051f ]
platform_get_irq() returns a positive IRQ number on success and a
negative error code on failure. It no longer returns zero. The driver
currently returns -ENXIO for all failures, which loses useful errors
such as -EPROBE_DEFER.
Return the error from platform_get_irq() directly.
Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Narasimharao Vadlamudi <ahmisaranrao@gmail.com>
Reviewed-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[ adjusted the patch path to drivers/staging/media/rkvdec/rkvdec.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/media/rkvdec/rkvdec.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index b5847259f4541..0b19a089e56ca 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -1044,8 +1044,8 @@ static int rkvdec_probe(struct platform_device *pdev)
vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
irq = platform_get_irq(pdev, 0);
- if (irq <= 0)
- return -ENXIO;
+ if (irq < 0)
+ return irq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
rkvdec_irq_handler, IRQF_ONESHOT,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0108/1887] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0107/1887] media: rkvdec: Propagate platform_get_irq() errors Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0109/1887] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
` (890 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 6d90f0feb929f6c0f3010f9af4747c7230b75993 ]
When qla2x00_mem_alloc() fails, qla2x00_probe_one() jumps to
probe_hw_failed and calls qla2x00_mem_free(). Several error labels in
qla2x00_mem_alloc() freed adapter members (elsrej.c, purex_dma_pool,
flt, sfp_data, loop_id_map, async_pd, sf_init_cb, ex_init_cb, npiv_info)
but left the pointers dangling. qla2x00_mem_free() then freed them a
second time. Worse, for the dma_pool members it issued
dma_pool_free(ha->s_dma_pool, ...) after s_dma_pool had already been
destroyed and set to NULL at fail_s_dma_pool, dereferencing a NULL pool.
Clear each freed pointer (and its DMA handle) in the error labels so the
subsequent qla2x00_mem_free() skips them.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-13-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adapted cleanup changes for missing fail_lsrjt and fail_flt_data blocks. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_os.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e1578808e27ee..0b21fb29a9fc5 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4464,23 +4464,36 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
fail_elsrej:
dma_pool_destroy(ha->purex_dma_pool);
+ ha->purex_dma_pool = NULL;
fail_flt:
dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
ha->flt, ha->flt_dma);
+ ha->flt = NULL;
+ ha->flt_dma = 0;
fail_flt_buffer:
dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
ha->sfp_data, ha->sfp_data_dma);
+ ha->sfp_data = NULL;
+ ha->sfp_data_dma = 0;
fail_sfp_data:
kfree(ha->loop_id_map);
+ ha->loop_id_map = NULL;
fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
+ ha->async_pd = NULL;
+ ha->async_pd_dma = 0;
fail_async_pd:
dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma);
+ ha->sf_init_cb = NULL;
+ ha->sf_init_cb_dma = 0;
fail_sf_init_cb:
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
+ ha->ex_init_cb = NULL;
+ ha->ex_init_cb_dma = 0;
fail_ex_init_cb:
kfree(ha->npiv_info);
+ ha->npiv_info = NULL;
fail_npiv_info:
dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0109/1887] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0108/1887] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0110/1887] scsi: qla2xxx: Quiesce response IRQ before freeing request queue Greg Kroah-Hartman
` (889 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 52fba32317ee631faa878725b2f7cd5c08acacd3 ]
qla2x00_get_data_rate() skips updating ha->link_data_rate when the
firmware returns mcp->mb[1] == 0x7. That value was a legacy sentinel
from before 64G hardware existed, but PORT_SPEED_64GB is now defined as
0x07 and ha->link_data_rate is decoded with the PORT_SPEED_* encoding.
On a 64G-capable adapter a genuine 64G link is therefore dropped, and
the port speed is misreported (port_speed sysfs, fc_host speed, FDMI).
Only 28xx and 29xx support 64G, so accept 0x07 on those adapters while
keeping the legacy filter for older ones. Also drop the duplicate copy
of the check at the end of the success branch; it repeated the first
assignment with no intervening change.
Fixes: ecc89f25e225 ("scsi: qla2xxx: Add Device ID for ISP28XX")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-46-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Omitted IS_QLA29XX() checks because this branch lacks 29xx adapter support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_mbx.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index ee22639fb54b8..583585783893c 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -5656,7 +5656,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_mbx, vha, 0x1107,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
} else {
- if (mcp->mb[1] != 0x7)
+ if (mcp->mb[1] != 0x7 || IS_QLA28XX(ha))
ha->link_data_rate = mcp->mb[1];
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -5667,8 +5667,6 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
"Done %s.\n", __func__);
- if (mcp->mb[1] != 0x7)
- ha->link_data_rate = mcp->mb[1];
}
return rval;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0110/1887] scsi: qla2xxx: Quiesce response IRQ before freeing request queue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0109/1887] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0111/1887] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
` (888 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 505753ec2594c6af09a601f0dd60be7d840c1d2d ]
qla2xxx_delete_qpair() deletes the request queue before the response
queue. qla25xx_delete_req_que() frees the request queue memory
(kfree(req) in qla25xx_free_req_que()), but the response-queue MSI-X is
only released later, in qla25xx_free_rsp_que(). In that window the
response interrupt can still fire, qla2xxx_msix_rsp_q() queues
qpair->q_work, and qla_do_work() -> qla24xx_process_response_queue()
dereferences the now-freed rsp->req (LOGINOUT/CT/ELS entries and the
status path), a use-after-free.
The cancel_work_sync() added for the qpair teardown lives in the
response free path, which runs after the request queue is already freed,
so it does not protect rsp->req.
Release the response-queue interrupt and flush qpair->q_work before
deleting the request queue, so no late completion can reach the freed
request queue. Clearing have_irq makes the subsequent
qla25xx_free_rsp_que() skip its free_irq(), and the firmware
queue-delete order (request then response) is preserved; the
request-delete mailbox completes on the default vector and is unaffected
by dropping the qpair response interrupt early.
Fixes: d74595278f4a ("scsi: qla2xxx: Add multiple queue pair functionality.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-18-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adjusted context due to missing qla_free_buf_pool() call ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_init.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index ace35581fd941..16470cfa333b3 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -9908,9 +9908,26 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
{
int ret = QLA_FUNCTION_FAILED;
struct qla_hw_data *ha = qpair->hw;
+ struct rsp_que *rsp = qpair->rsp;
qpair->delete_in_progress = 1;
+ /*
+ * The response-queue interrupt schedules qla_do_work(), which
+ * dereferences qpair->rsp->req. Release the interrupt and flush
+ * any pending work before the request queue is freed below so a
+ * late completion cannot touch the freed request queue. The
+ * firmware queue-delete order (request then response) is kept.
+ */
+ if (rsp && rsp->msix && rsp->msix->have_irq) {
+ free_irq(rsp->msix->vector, rsp->msix->handle);
+ rsp->msix->have_irq = 0;
+ rsp->msix->in_use = 0;
+ rsp->msix->handle = NULL;
+ }
+ if (rsp && ha->wq)
+ cancel_work_sync(&qpair->q_work);
+
ret = qla25xx_delete_req_que(vha, qpair->req);
if (ret != QLA_SUCCESS)
goto fail;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0111/1887] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0110/1887] scsi: qla2xxx: Quiesce response IRQ before freeing request queue Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0112/1887] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
` (887 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 626e44f3d8a924a97a3848a9fd45833947e081e9 ]
For QLAFX00 the request ring is ioremapped device I/O memory
(ha->iobase + req_que_off), not DMA-coherent RAM, which is why the rest
of the FX00 path accesses it through memcpy_toio() and the wrt_reg_*
helpers. __qla2x00_alloc_iocbs() however zeroed the producer slot with a
plain memset(). On architectures such as ARM64 a regular memset() may
emit unaligned or block-zeroing instructions (e.g. DC ZVA) that are
invalid on Device memory, leading to a synchronous external abort.
Use memset_io() to clear the slot for QLAFX00, matching the I/O
accessors used elsewhere on this ring. Other adapters keep the plain
memset() on their DMA-coherent rings. The zero-fill is retained for FX00
because its IOCB builders (e.g. qlafx00_fxdisc_iocb()) copy only part of
the entry and rely on the unused tail being pre-zeroed.
Fixes: 8ae6d9c7eb10 ("[SCSI] qla2xxx: Enhancements to support ISPFx00.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-12-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ replaced qla_req_ring_slot() and qla_req_entry_size() with req->ring_ptr and REQUEST_ENTRY_SIZE. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_iocb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 7bccd525ee19b..f080e19529272 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2347,11 +2347,13 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
/* Prep packet */
req->cnt -= req_cnt;
pkt = req->ring_ptr;
- memset(pkt, 0, REQUEST_ENTRY_SIZE);
if (IS_QLAFX00(ha)) {
+ memset_io((void __iomem __force *)pkt, 0,
+ REQUEST_ENTRY_SIZE);
wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
} else {
+ memset(pkt, 0, REQUEST_ENTRY_SIZE);
pkt->entry_count = req_cnt;
pkt->handle = handle;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0112/1887] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0111/1887] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0113/1887] f2fs: limit recovery filename logging to stored length Greg Kroah-Hartman
` (886 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit d7e3fa7d06bf7fcaac186d3c4d635caac166d36c ]
qla27xx_copy_multiple_pkt() and qla27xx_copy_fpin_pkt() poll
rsp_q->ring_ptr->signature for RESPONSE_PROCESSED (0xDEADDEAD) to decide
whether the next continuation IOCB has arrived, spinning on cpu_relax()
without advancing the ring or decrementing the entry count while it has
not. response_t::signature lives at byte offset 60, but a continuation
IOCB (sts_cont_entry_t / struct sts_cont_entry_ext) carries raw FC frame
payload at that offset (data[56..59]). A received frame whose payload
bytes happen to equal 0xDEADDEAD is therefore misread as "not yet
arrived", and the loop spins forever in interrupt/DPC context, causing a
CPU soft lockup.
The poll is also unnecessary: callers of qla27xx_copy_multiple_pkt()
(PT_LS4_UNSOL and the NVMe purls path) already gate on
qla_chk_cont_iocb_avail(), which guarantees all entry_count IOCBs are
present before copying begins. The sibling helper
__qla_copy_purex_to_buffer() already drops the signature poll and relies
on the entry_type == STATUS_CONT_TYPE guard instead.
Remove the signature busy-wait from both helpers, keeping the entry_type
guard, and gate the FPIN path with qla_chk_cont_iocb_avail() so it defers
and re-processes on the next interrupt once all continuation IOCBs have
arrived, mirroring the ELS_AUTH_ELS and PT_LS4_UNSOL arms. With this the
signature field is never read on a continuation IOCB, eliminating the
payload-aliasing lockup.
Fixes: 9f2475fe7406 ("scsi: qla2xxx: SAN congestion management implementation")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-15-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ replaced unavailable qla_rsp_ring_rewind_to() with direct ring_ptr and ring_index assignments ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_isr.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 72ecd39a75830..2b3885bd47ff9 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1053,14 +1053,6 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
- if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
- ql_dbg(ql_dbg_async, vha, 0x5084,
- "Ran out of IOCBs, partial data 0x%x\n",
- buffer_copy_offset);
- cpu_relax();
- continue;
- }
-
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
@@ -3993,9 +3985,24 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
"SCM not active for this port\n");
break;
}
+ if (qla_chk_cont_iocb_avail(vha, rsp,
+ (response_t *)pkt, rsp_in)) {
+ /*
+ * ring_ptr and ring_index were
+ * pre-incremented above. Reset them
+ * back to current. Wait for next
+ * interrupt with all IOCBs to arrive
+ * and re-process.
+ */
+ rsp->ring_ptr = (response_t *)pkt;
+ rsp->ring_index = cur_ring_index;
+
+ ql_dbg(ql_dbg_init, vha, 0x5095,
+ "Defer processing FPIN...\n");
+ return;
+ }
pure_item = qla27xx_copy_fpin_pkt(vha,
(void **)&pkt, &rsp);
- __update_rsp_in(is_shadow_hba, rsp, rsp_in);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0113/1887] f2fs: limit recovery filename logging to stored length
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0112/1887] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0114/1887] f2fs: fix dentry folio leak in find_in_level Greg Kroah-Hartman
` (885 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Wenjie Qi, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenjie Qi <qwjhust@gmail.com>
[ Upstream commit 01027b2fcb74dade59fb833b51023f6593b6a9a2 ]
F2FS stores recovery filenames as a length plus a fixed-size i_name
buffer. The buffer is not NUL-terminated, but recover_inode() and
recover_dentry() print it with %s.
For a 255-byte filename, recovery logging can read past i_name into the
following raw inode fields.
Print the name with a precision bounded by i_namelen and F2FS_NAME_LEN.
Fixes: f356fe0cba0e ("f2fs: add debug msgs in the recovery routine")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5.5
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ inlined recover_printable_name() logic into the existing page-based recovery functions. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/recovery.c | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index b33e5220aa187..45572d1d2d4ee 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -176,7 +176,8 @@ static int recover_dentry(struct inode *inode, struct page *ipage,
struct inode *dir, *einode;
struct fsync_inode_entry *entry;
int err = 0;
- char *name;
+ const char *name;
+ int name_len;
entry = get_fsync_inode(dir_list, pino);
if (!entry) {
@@ -235,12 +236,16 @@ static int recover_dentry(struct inode *inode, struct page *ipage,
out_put:
f2fs_put_page(page, 0);
out:
- if (file_enc_name(inode))
+ if (file_enc_name(inode)) {
name = "<encrypted>";
- else
+ name_len = sizeof("<encrypted>") - 1;
+ } else {
name = raw_inode->i_name;
- f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %s, dir = %lx, err = %d",
- __func__, ino_of_node(ipage), name,
+ name_len = min_t(unsigned int, le32_to_cpu(raw_inode->i_namelen),
+ F2FS_NAME_LEN);
+ }
+ f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, dir = %lx, err = %d",
+ __func__, ino_of_node(ipage), name_len, name,
IS_ERR(dir) ? 0 : dir->i_ino, err);
return err;
}
@@ -287,7 +292,8 @@ static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri)
static int recover_inode(struct inode *inode, struct page *page)
{
struct f2fs_inode *raw = F2FS_INODE(page);
- char *name;
+ const char *name;
+ int name_len;
int err;
inode->i_mode = le16_to_cpu(raw->i_mode);
@@ -336,13 +342,18 @@ static int recover_inode(struct inode *inode, struct page *page)
f2fs_mark_inode_dirty_sync(inode, true);
- if (file_enc_name(inode))
+ if (file_enc_name(inode)) {
name = "<encrypted>";
- else
- name = F2FS_INODE(page)->i_name;
+ name_len = sizeof("<encrypted>") - 1;
+ } else {
+ name = raw->i_name;
+ name_len = min_t(unsigned int, le32_to_cpu(raw->i_namelen),
+ F2FS_NAME_LEN);
+ }
- f2fs_notice(F2FS_I_SB(inode), "recover_inode: ino = %x, name = %s, inline = %x",
- ino_of_node(page), name, raw->i_inline);
+ f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, inline = %x",
+ __func__, ino_of_node(page), name_len, name,
+ raw->i_inline);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0114/1887] f2fs: fix dentry folio leak in find_in_level
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0113/1887] f2fs: limit recovery filename logging to stored length Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0115/1887] drm/sysfb: simpledrm: Improve stride validation Greg Kroah-Hartman
` (884 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chao Yu, Guanghui Yang, Jaegeuk Kim,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanghui Yang <3497809730@qq.com>
[ Upstream commit cca7d3e30bf30333314e31bc70b9a739f1342167 ]
find_in_level() gets a dentry folio with f2fs_find_data_folio() before
calling find_in_block(). If find_in_block() returns an error, the
function stores the error in res_folio and breaks out of the loop without
dropping the dentry folio.
This leaks the folio reference on the find_in_block() error path. Drop
the dentry folio before returning the error to the caller.
Fixes: 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption")
Cc: stable@vger.kernel.org
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ Replaced f2fs_folio_put(dentry_folio, false) with f2fs_put_page(dentry_page, 0) for the page-based API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/dir.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 29ac1e77b5d7a..cadc32959a23f 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -374,6 +374,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
de = find_in_block(dir, dentry_page, fname, &max_slots, use_hash);
if (IS_ERR(de)) {
+ f2fs_put_page(dentry_page, 0);
*res_page = ERR_CAST(de);
de = NULL;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0115/1887] drm/sysfb: simpledrm: Improve stride validation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0114/1887] f2fs: fix dentry folio leak in find_in_level Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0116/1887] ipmr: account multicast table and route memory Greg Kroah-Hartman
` (883 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann, Thierry Reding,
Maxime Ripard, Javier Martinez Canillas, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <tzimmermann@suse.de>
[ Upstream commit df6533f11688aa30be3bb883c7637f4ffdbb7cbd ]
Validate the computed stride against the maximum value INT_MAX.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Fixes: 7bfa5c7b28d6 ("drm/simpledrm: Compute linestride with drm_format_info_min_pitch()")
Cc: <stable@vger.kernel.org> # v6.1+
Link: https://patch.msgid.link/20260625094509.157581-5-tzimmermann@suse.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/tiny/simpledrm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 18489779fb8aa..4b5ccbb13ecfe 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -693,9 +693,15 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
return ERR_PTR(-ENODEV);
}
if (!stride) {
- stride = drm_format_info_min_pitch(format, 0, width);
- if (drm_WARN_ON(dev, !stride))
+ u64 pitch = drm_format_info_min_pitch(format, 0, width);
+
+ if (drm_WARN_ON(dev, !pitch)) {
+ return ERR_PTR(-EINVAL); /* driver bug */
+ } else if (pitch > INT_MAX) {
+ drm_warn(dev, "stride of %llu exceeds maximum\n", pitch);
return ERR_PTR(-EINVAL);
+ }
+ stride = pitch;
}
sdev->mode = simpledrm_mode(width, height);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0116/1887] ipmr: account multicast table and route memory
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0115/1887] drm/sysfb: simpledrm: Improve stride validation Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0117/1887] virtio-mmio: Remove virtqueue list from mmio device Greg Kroah-Hartman
` (882 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zihan Xi, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit b7ee18725f2292ab554aa96a101ae42d45f008bd ]
A netadmin in a user+net namespace can create many IPv4 and IPv6
multicast routing tables with MRT_TABLE and MRT6_TABLE. Each unseen
id allocates an mr_table via the shared mr_table_alloc(), links it
into the per-net list, and leaves it until netns teardown. Those
objects were not charged to memcg, so the host unreclaimable slab
grows with the table count.
Account mr_table allocations with GFP_KERNEL_ACCOUNT and mark the
IPv4/IPv6 MFC caches SLAB_ACCOUNT. This matches the established
handling of IP addresses, routes and alternate interface names.
Unresolved MFC entries are still allocated from softIRQ with
GFP_ATOMIC and are not charged. They expire after 10 seconds and are
bounded by the socket receive queue; see commit 0079ad8e8dc3
("ipmr: remove hard code cache_resolve_queue_len limit").
Fixes: f0ad0860d01e ("ipv4: ipmr: support multiple tables")
Fixes: d1db275dd3f6 ("ipv6: ip6mr: support multiple tables")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/050b58f7fc6b45da0fb12768ebb62d18fa46133d.1788784801.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted upstream allocation helpers to existing kzalloc() and kmem_cache_create() calls. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipmr.c | 3 ++-
net/ipv4/ipmr_base.c | 2 +-
net/ipv6/ip6mr.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 8d4f556fced2c..efc31dcbf4d26 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -3145,7 +3145,8 @@ int __init ip_mr_init(void)
mrt_cachep = kmem_cache_create("ip_mrt_cache",
sizeof(struct mfc_cache),
- 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC,
+ 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC |
+ SLAB_ACCOUNT,
NULL);
err = register_pernet_subsys(&ipmr_net_ops);
diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c
index de98ce66d38f3..ae5a685daeeac 100644
--- a/net/ipv4/ipmr_base.c
+++ b/net/ipv4/ipmr_base.c
@@ -38,7 +38,7 @@ mr_table_alloc(struct net *net, u32 id,
struct mr_table *mrt;
int err;
- mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
+ mrt = kzalloc(sizeof(*mrt), GFP_KERNEL_ACCOUNT);
if (!mrt)
return ERR_PTR(-ENOMEM);
mrt->id = id;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 3c60a63c9f31f..944097e9d9873 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1389,7 +1389,7 @@ int __init ip6_mr_init(void)
mrt_cachep = kmem_cache_create("ip6_mrt_cache",
sizeof(struct mfc6_cache),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
NULL);
if (!mrt_cachep)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0117/1887] virtio-mmio: Remove virtqueue list from mmio device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0116/1887] ipmr: account multicast table and route memory Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0118/1887] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
` (881 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Viresh Kumar, Michael S. Tsirkin,
Jason Wang, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viresh Kumar <viresh.kumar@linaro.org>
[ Upstream commit 564a69ad90d15c782176e1a8c9e1c95661e1aed0 ]
The MMIO transport implementation creates a list of virtqueues for a
virtio device, while the same is already available in the struct
virtio_device.
Don't create a duplicate list, and use the other one instead.
While at it, fix the virtio_device_for_each_vq() macro to accept an
argument like "&vm_dev->vdev" (which currently fails to build).
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Message-Id: <3e56c6f74002987e22f364d883cbad177cd9ad9c.1747827066.git.viresh.kumar@linaro.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
[Backport to 6.1: remove the obsolete queue-info declaration without
introducing the notify function pointer from the newer notification-data
support. Keep vm_notify and the existing find_vqs interface. This leaves
the device layout ready for d14d693adb055e98ca705822ba6daebc18602d9a.]
Stable-dep-of: d14d693adb05 ("virtio_mmio: disable IRQ wake before free_irq")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_mmio.c | 52 +++---------------------------------
include/linux/virtio.h | 2 +-
2 files changed, 4 insertions(+), 50 deletions(-)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 7651940aafd24..7909d4aec8a6e 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -64,7 +64,6 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
-#include <linux/spinlock.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
#include <uapi/linux/virtio_mmio.h>
@@ -87,22 +86,8 @@ struct virtio_mmio_device {
void __iomem *base;
unsigned long version;
-
- /* a list of queues so we can dispatch IRQs */
- spinlock_t lock;
- struct list_head virtqueues;
-};
-
-struct virtio_mmio_vq_info {
- /* the actual virtqueue */
- struct virtqueue *vq;
-
- /* the list node for the virtqueues list */
- struct list_head node;
};
-
-
/* Configuration interface */
static u64 vm_get_features(struct virtio_device *vdev)
@@ -289,9 +274,8 @@ static bool vm_notify(struct virtqueue *vq)
static irqreturn_t vm_interrupt(int irq, void *opaque)
{
struct virtio_mmio_device *vm_dev = opaque;
- struct virtio_mmio_vq_info *info;
+ struct virtqueue *vq;
unsigned long status;
- unsigned long flags;
irqreturn_t ret = IRQ_NONE;
/* Read and acknowledge interrupts */
@@ -304,10 +288,8 @@ static irqreturn_t vm_interrupt(int irq, void *opaque)
}
if (likely(status & VIRTIO_MMIO_INT_VRING)) {
- spin_lock_irqsave(&vm_dev->lock, flags);
- list_for_each_entry(info, &vm_dev->virtqueues, node)
- ret |= vring_interrupt(irq, info->vq);
- spin_unlock_irqrestore(&vm_dev->lock, flags);
+ virtio_device_for_each_vq(&vm_dev->vdev, vq)
+ ret |= vring_interrupt(irq, vq);
}
return ret;
@@ -318,14 +300,8 @@ static irqreturn_t vm_interrupt(int irq, void *opaque)
static void vm_del_vq(struct virtqueue *vq)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
- struct virtio_mmio_vq_info *info = vq->priv;
- unsigned long flags;
unsigned int index = vq->index;
- spin_lock_irqsave(&vm_dev->lock, flags);
- list_del(&info->node);
- spin_unlock_irqrestore(&vm_dev->lock, flags);
-
/* Select and deactivate the queue */
writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
if (vm_dev->version == 1) {
@@ -336,8 +312,6 @@ static void vm_del_vq(struct virtqueue *vq)
}
vring_del_virtqueue(vq);
-
- kfree(info);
}
static void vm_del_vqs(struct virtio_device *vdev)
@@ -363,9 +337,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
const char *name, bool ctx)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
- struct virtio_mmio_vq_info *info;
struct virtqueue *vq;
- unsigned long flags;
unsigned int num;
int err;
@@ -382,13 +354,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
goto error_available;
}
- /* Allocate and fill out our active queue description */
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info) {
- err = -ENOMEM;
- goto error_kmalloc;
- }
-
num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
if (num == 0) {
err = -ENOENT;
@@ -446,13 +411,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
}
- vq->priv = info;
- info->vq = vq;
-
- spin_lock_irqsave(&vm_dev->lock, flags);
- list_add(&info->node, &vm_dev->virtqueues);
- spin_unlock_irqrestore(&vm_dev->lock, flags);
-
return vq;
error_bad_pfn:
@@ -464,8 +422,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
}
- kfree(info);
-error_kmalloc:
error_available:
return ERR_PTR(err);
}
@@ -610,8 +566,6 @@ static int virtio_mmio_probe(struct platform_device *pdev)
vm_dev->vdev.dev.release = virtio_mmio_release_dev;
vm_dev->vdev.config = &virtio_mmio_config_ops;
vm_dev->pdev = pdev;
- INIT_LIST_HEAD(&vm_dev->virtqueues);
- spin_lock_init(&vm_dev->lock);
vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vm_dev->base)) {
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 82a29db54e7d1..8982611799e0b 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -156,7 +156,7 @@ void virtio_reset_device(struct virtio_device *dev);
size_t virtio_max_dma_size(struct virtio_device *vdev);
#define virtio_device_for_each_vq(vdev, vq) \
- list_for_each_entry(vq, &vdev->vqs, list)
+ list_for_each_entry(vq, &(vdev)->vqs, list)
/**
* struct virtio_driver - operations for a virtio I/O driver
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0118/1887] virtio_mmio: disable IRQ wake before free_irq
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0117/1887] virtio-mmio: Remove virtqueue list from mmio device Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0119/1887] net/sched: act_api: release all action references on NEWACTION failure Greg Kroah-Hartman
` (880 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiong Weimin <xiongweimin@kylinos.cn>
[ Upstream commit d14d693adb055e98ca705822ba6daebc18602d9a ]
When the DT node has "wakeup-source", vm_find_vqs() calls
enable_irq_wake() on the shared IRQ, but vm_del_vqs() freed that IRQ
without a matching disable_irq_wake(). That leaves a wake reference
behind and can warn on later free_irq()/request_irq() cycles.
Record whether enable_irq_wake() succeeded, and disable it in
vm_del_vqs() before free_irq().
Fixes: 02213273f72a ("virtio_mmio: add support to set IRQ of a virtio device as wakeup source")
Cc: stable@vger.kernel.org
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260805032937.1606737-1-xiongweimin@kylinos.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_mmio.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 7909d4aec8a6e..6395b8fba0050 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -86,6 +86,9 @@ struct virtio_mmio_device {
void __iomem *base;
unsigned long version;
+
+ /* True if enable_irq_wake() succeeded for the shared IRQ. */
+ bool wake_irq_enabled;
};
/* Configuration interface */
@@ -318,11 +321,17 @@ static void vm_del_vqs(struct virtio_device *vdev)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
struct virtqueue *vq, *n;
+ int irq = platform_get_irq(vm_dev->pdev, 0);
list_for_each_entry_safe(vq, n, &vdev->vqs, list)
vm_del_vq(vq);
- free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
+ if (vm_dev->wake_irq_enabled) {
+ disable_irq_wake(irq);
+ vm_dev->wake_irq_enabled = false;
+ }
+
+ free_irq(irq, vm_dev);
}
static void vm_synchronize_cbs(struct virtio_device *vdev)
@@ -445,8 +454,9 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
if (err)
return err;
- if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source"))
- enable_irq_wake(irq);
+ if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source") &&
+ !enable_irq_wake(irq))
+ vm_dev->wake_irq_enabled = true;
for (i = 0; i < nvqs; ++i) {
if (!names[i]) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0119/1887] net/sched: act_api: release all action references on NEWACTION failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0118/1887] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0120/1887] net: mana: Reserve extra CQ slot for the fence completion CQE Greg Kroah-Hartman
` (879 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Jamal Hadi Salim,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
[ Upstream commit 478eb5abb51931a152abab068f8a717b7ff480fd ]
When a batched RTM_NEWACTION request replaces an existing action,
tcf_idr_check_alloc() takes a temporary reference on it. If a later
action fails to initialize, tcf_action_destroy() uses strict release
semantics to clean up the actions initialized so far. For an action
bound to a filter, the strict check returns -EPERM without dropping
the temporary reference.
This error also makes tcf_action_destroy() return before releasing
subsequent entries. Any new action initialized between the bound
action and the failing entry is leaked together with its reserved
IDR slot, preventing reuse of its index.
Use tcf_idr_release() to drop each reference held by the batch without
rejecting bound actions. This allows cleanup to continue through all
initialized entries and preserves the module reference release when
an action is destroyed. Explicit action deletion and flushing retain
their separate bind-count checks.
Fixes: 55334a5db5cd ("net_sched: act: refuse to remove bound action outside")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260909070336.32979-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_api.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 630f285f8db07..8aa291b835e9b 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1142,19 +1142,14 @@ EXPORT_SYMBOL(tcf_action_exec);
int tcf_action_destroy(struct tc_action *actions[], int bind)
{
- const struct tc_action_ops *ops;
struct tc_action *a;
int ret = 0, i;
for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
a = actions[i];
actions[i] = NULL;
- ops = a->ops;
- ret = __tcf_idr_release(a, bind, true);
- if (ret == ACT_P_DELETED)
- module_put(ops->owner);
- else if (ret < 0)
- return ret;
+ /* Drop our reference even if the action is still bound to a filter. */
+ ret = tcf_idr_release(a, bind);
}
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0120/1887] net: mana: Reserve extra CQ slot for the fence completion CQE
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0119/1887] net/sched: act_api: release all action references on NEWACTION failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0121/1887] erofs: preserve LZMA decoders on resize failure Greg Kroah-Hartman
` (878 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sahil Chandna, Haiyang Zhang,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sahil Chandna <sahilchandna@linux.microsoft.com>
[ Upstream commit 80dd7e754b3aa9637a0758ad93fa209f9650ec48 ]
The RX completion queue is sized to hold exactly one CQE per posted RX WQE.
MANA_FENCE_RQ makes hardware post an additional CQE_RX_OBJECT_FENCE after
the packet CQEs. The current sizing reserves no extra slot for it and in
rare cases, CQ has no guaranteed slot for the fence CQE when it is full of
packet CQEs. This can lead to dropping the fence completion while the
driver waits holding RTNL lock throughout the timeout duration.
Reserve one extra CQE slot for CQE_RX_OBJECT_FENCE. mana_gd_alloc_memory()
requires queue_size to be a power-of-two and at least MANA_PAGE_SIZE;
the reservation pushes cq_size past a power-of-two, so round up the CQ size
in mana_create_rxq().
Cc: stable@vger.kernel.org
Fixes: 6cc74443a773 ("net: mana: Add RX fencing")
Signed-off-by: Sahil Chandna <sahilchandna@linux.microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Link: https://patch.msgid.link/20260901121837.3503240-1-sahilchandna@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Replaced MANA_PAGE_ALIGN() with PAGE_ALIGN() to match the older tree. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/microsoft/mana/mana_en.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 4afcb202e3509..2d1e5b83a0769 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -1662,6 +1662,10 @@ static int mana_alloc_rx_wqe(struct mana_port_context *apc,
*cq_size += COMP_ENTRY_SIZE;
}
+ /* Reserve an extra slot for Fence completion
+ * event (CQE_RX_OBJECT_FENCE) in case RX CQ is full.
+ */
+ *cq_size += COMP_ENTRY_SIZE;
return 0;
}
@@ -1715,7 +1719,7 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
goto out;
rq_size = PAGE_ALIGN(rq_size);
- cq_size = PAGE_ALIGN(cq_size);
+ cq_size = PAGE_ALIGN(roundup_pow_of_two(cq_size));
/* Create RQ */
memset(&spec, 0, sizeof(spec));
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0121/1887] erofs: preserve LZMA decoders on resize failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0120/1887] net: mana: Reserve extra CQ slot for the fence completion CQE Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0122/1887] mptcp: userspace pm: use a single point of exit Greg Kroah-Hartman
` (877 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikhil Gurudasani, Gao Xiang,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
[ Upstream commit 617d0d8d199ba1790c94310fd75a22d01c97a8d6 ]
The pool-resize path frees each stream's old decoder before allocating
its replacement. If an allocation fails after some streams have already
been replaced, the failed stream is put back on the list with state ==
NULL. z_erofs_lzma_max_dictsize is still advanced as if the whole
pool had been resized.
An existing LZMA mount can select the broken stream and pass
NULL to xz_dec_microlzma_reset(). A retry at the same size also
skip another resize attempt. Since the global maximum was advanced,
thus, the invalid state is left unrepaired.
Allocate each replacement before freeing the old decoder, temporarily
retaining one old decoder during allocation. Stop at the first failure
and advance z_erofs_lzma_max_dictsize only after all streams satisfy
the request.
Record each stream's dictionary capacity so retries can skip streams
already enlarged before a partial failure.
Fixes: 622ceaddb764 ("erofs: lzma compression support")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Gao Xiang <xiang@kernel.org>
[ Retained the existing `struct xz_buf buf` member alongside the new `dict_size` field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/decompressor_lzma.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c
index b1ac88a820f2d..c6e6ceae48a3b 100644
--- a/fs/erofs/decompressor_lzma.c
+++ b/fs/erofs/decompressor_lzma.c
@@ -6,6 +6,7 @@
struct z_erofs_lzma {
struct z_erofs_lzma *next;
struct xz_dec_microlzma *state;
+ unsigned int dict_size;
struct xz_buf buf;
u8 bounce[PAGE_SIZE];
};
@@ -132,11 +133,19 @@ int z_erofs_load_lzma_config(struct super_block *sb,
err = 0;
/* 2. walk each isolated stream and grow max dict_size if needed */
for (strm = head; strm; strm = strm->next) {
+ struct xz_dec_microlzma *state;
+
+ if (strm->dict_size >= dict_size)
+ continue;
+ state = xz_dec_microlzma_alloc(XZ_PREALLOC, dict_size);
+ if (!state) {
+ err = -ENOMEM;
+ break;
+ }
if (strm->state)
xz_dec_microlzma_end(strm->state);
- strm->state = xz_dec_microlzma_alloc(XZ_PREALLOC, dict_size);
- if (!strm->state)
- err = -ENOMEM;
+ strm->state = state;
+ strm->dict_size = dict_size;
}
/* 3. push back all to the global list and update max dict_size */
@@ -146,7 +155,8 @@ int z_erofs_load_lzma_config(struct super_block *sb,
spin_unlock(&z_erofs_lzma_lock);
wake_up_all(&z_erofs_lzma_wq);
- z_erofs_lzma_max_dictsize = dict_size;
+ if (!err)
+ z_erofs_lzma_max_dictsize = dict_size;
mutex_unlock(&lzma_resize_mutex);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0122/1887] mptcp: userspace pm: use a single point of exit
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0121/1887] erofs: preserve LZMA decoders on resize failure Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:36 ` [PATCH 6.1 0123/1887] mptcp: pm: drop match in userspace_pm_append_new_local_addr Greg Kroah-Hartman
` (876 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mat Martineau, Matthieu Baerts,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts <matthieu.baerts@tessares.net>
[ Upstream commit 40c71f763f87b68fe43199c1702220c91afed288 ]
Like in all other functions in this file, a single point of exit is used
when extra operations are needed: unlock, decrement refcount, etc.
There is no functional change for the moment but it is better to do the
same here to make sure all cleanups are done in case of intermediate
errors.
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_userspace.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 52ab9a3f070a8..129ae1fef054e 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -77,8 +77,8 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
*/
e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
if (!e) {
- spin_unlock_bh(&msk->pm.lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto append_err;
}
*e = *entry;
@@ -93,6 +93,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
ret = entry->addr.id;
}
+append_err:
spin_unlock_bh(&msk->pm.lock);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0123/1887] mptcp: pm: drop match in userspace_pm_append_new_local_addr
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0122/1887] mptcp: userspace pm: use a single point of exit Greg Kroah-Hartman
@ 2026-10-28 16:36 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0124/1887] sock: add sock_kmemdup helper Greg Kroah-Hartman
` (875 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <tanggeliang@kylinos.cn>
[ Upstream commit 640e3d69d0bc70d7d3de34800a1640793262bd08 ]
The variable 'match' in mptcp_userspace_pm_append_new_local_addr() is a
redundant one, and this patch drops it.
No need to define 'match' as 'struct mptcp_pm_addr_entry *' type. In this
function, it's only used to check whether it's NULL. It can be defined as
a Boolean one.
Also other variables 'addr_match' and 'id_match' make 'match' a redundant
one, which can be replaced by directly checking 'addr_match && id_match'.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250221-net-next-mptcp-pm-misc-cleanup-3-v1-5-2b70ab1cee79@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_userspace.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 129ae1fef054e..e203b7f878a90 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -43,7 +43,6 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
bool needs_id)
{
DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
- struct mptcp_pm_addr_entry *match = NULL;
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *e;
bool addr_match = false;
@@ -62,16 +61,12 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
if (addr_match && entry->addr.id == 0 && needs_id)
entry->addr.id = e->addr.id;
id_match = (e->addr.id == entry->addr.id);
- if (addr_match && id_match) {
- match = e;
+ if (addr_match || id_match)
break;
- } else if (addr_match || id_match) {
- break;
- }
__set_bit(e->addr.id, id_bitmap);
}
- if (!match && !addr_match && !id_match) {
+ if (!addr_match && !id_match) {
/* Memory for the entry is allocated from the
* sock option buffer.
*/
@@ -89,7 +84,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
msk->pm.local_addr_used++;
ret = e->addr.id;
- } else if (match) {
+ } else if (addr_match && id_match) {
ret = entry->addr.id;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0124/1887] sock: add sock_kmemdup helper
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-10-28 16:36 ` [PATCH 6.1 0123/1887] mptcp: pm: drop match in userspace_pm_append_new_local_addr Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0125/1887] mptcp: use sock_kmemdup for address entry Greg Kroah-Hartman
` (874 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Kuniyuki Iwashima,
Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <tanggeliang@kylinos.cn>
[ Upstream commit 456cc675b6d4cadd4872a477d8976ff56eef4b6f ]
This patch adds the sock version of kmemdup() helper, named sock_kmemdup(),
to duplicate the input "src" memory block using the socket's option memory
buffer.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/f828077394c7d1f3560123497348b438c875b510.1740735165.git.tanggeliang@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sock.h | 2 ++
net/core/sock.c | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/include/net/sock.h b/include/net/sock.h
index 9fe621f985740..d195cddb8559b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1977,6 +1977,8 @@ static inline struct sk_buff *sock_alloc_send_skb(struct sock *sk,
}
void *sock_kmalloc(struct sock *sk, int size, gfp_t priority);
+void *sock_kmemdup(struct sock *sk, const void *src,
+ int size, gfp_t priority);
void sock_kfree_s(struct sock *sk, void *mem, int size);
void sock_kzfree_s(struct sock *sk, void *mem, int size);
void sk_send_sigurg(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index 899ddf069940f..8593dc1b33eb3 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2670,6 +2670,22 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
}
EXPORT_SYMBOL(sock_kmalloc);
+/*
+ * Duplicate the input "src" memory block using the socket's
+ * option memory buffer.
+ */
+void *sock_kmemdup(struct sock *sk, const void *src,
+ int size, gfp_t priority)
+{
+ void *mem;
+
+ mem = sock_kmalloc(sk, size, priority);
+ if (mem)
+ memcpy(mem, src, size);
+ return mem;
+}
+EXPORT_SYMBOL(sock_kmemdup);
+
/* Free an option memory block. Note, we actually want the inline
* here as this allows gcc to detect the nullify and fold away the
* condition entirely.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0125/1887] mptcp: use sock_kmemdup for address entry
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0124/1887] sock: add sock_kmemdup helper Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0126/1887] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
` (873 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <tanggeliang@kylinos.cn>
[ Upstream commit 52f83c0b5f857dbe24f66fc9a7f035523e9ffbc9 ]
Instead of using sock_kmalloc() to allocate an address
entry "e" and then immediately duplicate the input "entry"
to it, the newly added sock_kmemdup() helper can be used in
mptcp_userspace_pm_append_new_local_addr() to simplify the code.
More importantly, the code "*e = *entry;" that assigns "entry"
to "e" is not easy to implemented in BPF if we use the same code
to implement an append_new_local_addr() helper of a BFP path
manager. This patch avoids this type of memory assignment
operation.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/3e5a307aed213038a87e44ff93b5793229b16279.1740735165.git.tanggeliang@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_userspace.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index e203b7f878a90..1bc270276db46 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -70,13 +70,12 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
/* Memory for the entry is allocated from the
* sock option buffer.
*/
- e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
+ e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC);
if (!e) {
ret = -ENOMEM;
goto append_err;
}
- *e = *entry;
if (!e->addr.id && needs_id)
e->addr.id = find_next_zero_bit(id_bitmap,
MPTCP_PM_MAX_ADDR_ID + 1,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0126/1887] mptcp: pm: userspace: fix address ID overflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0125/1887] mptcp: use sock_kmemdup for address entry Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0127/1887] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
` (872 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qing Luo, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qing Luo <luoqing@kylinos.cn>
[ Upstream commit f9f0068e8813d8c10d016b030fc3a320d0b6767c ]
When all MPTCP address IDs (1-255) are exhausted in the userspace PM,
find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value
overflows when stored in the u8 field e->addr.id, resulting in ID 0
being stored and the entry being incorrectly added to the list.
ID 0 is reserved for the initial connection in MPTCP, so this overflow
can cause address conflicts.
Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID'
check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before
reaching find_next_zero_bit(), preventing this overflow. So this fix only
addresses the userspace PM path.
Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and
return -ENOSPC if all IDs are truly exhausted. Move the ID allocation
check before the memory allocation so that the error path does not need
to free the allocated entry.
Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs")
Cc: stable@vger.kernel.org
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-8-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_userspace.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 1bc270276db46..a455303d2ed64 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -67,6 +67,19 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
}
if (!addr_match && !id_match) {
+ unsigned int id;
+
+ if (!entry->addr.id && needs_id) {
+ id = find_next_zero_bit(id_bitmap,
+ MPTCP_PM_MAX_ADDR_ID + 1, 1);
+ if (id > MPTCP_PM_MAX_ADDR_ID) {
+ ret = -ENOSPC;
+ goto append_err;
+ }
+ } else {
+ id = entry->addr.id;
+ }
+
/* Memory for the entry is allocated from the
* sock option buffer.
*/
@@ -76,10 +89,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
goto append_err;
}
- if (!e->addr.id && needs_id)
- e->addr.id = find_next_zero_bit(id_bitmap,
- MPTCP_PM_MAX_ADDR_ID + 1,
- 1);
+ e->addr.id = id;
list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
msk->pm.local_addr_used++;
ret = e->addr.id;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0127/1887] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0126/1887] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0128/1887] smb: client: fix file type corruption in cifs_reparse_point_to_fattr() Greg Kroah-Hartman
` (871 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mat Martineau,
Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
[ Upstream commit f968190c0b42ea2004dc1426359a53ec365a7a37 ]
When an ADD_ADDR entry is reused, the timer is re-armed, because the
goal is to re-announce an ADD_ADDR, and eventually retransmit it if
needed.
In this case, the retransmission counter should be reset as well, so the
re-announced address gets its retransmissions back instead of relying on
what was left before, and possibly not being able to retransmit it.
Fixes: 304ab97f4c7c ("mptcp: allow ADD_ADDR reissuance by userspace PMs")
Cc: stable@vger.kernel.org
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=4
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-9-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted mptcp_pm_announced_alloc() in pm.c to mptcp_pm_alloc_anno_list() in pm_netlink.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_netlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 0d8316bc50775..532f75d29124d 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -428,10 +428,10 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
add_entry->addr = *addr;
add_entry->sock = msk;
- add_entry->retrans_times = 0;
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
reset_timer:
+ add_entry->retrans_times = 0;
add_entry->timer_done = false;
timeout = mptcp_get_add_addr_timeout(net);
if (timeout)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0128/1887] smb: client: fix file type corruption in cifs_reparse_point_to_fattr()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0127/1887] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0129/1887] smb: client: fix cifsFileInfo reference leak in deferred close Greg Kroah-Hartman
` (870 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
[ Upstream commit 6bd360447941357e959414a525aa62576a448116 ]
Setting the file type in cf_mode without clearing the existing S_IFMT
bits first is wrong as it corrupts the file type when cf_mode already
has type bits set (e.g. S_IFREG | S_IFLNK == S_IFDIR | S_IFREG).
Clear S_IFMT before setting S_IFLNK for native and SMB1 symlinks.
Closes: https://sashiko.dev/#/patchset/20260906181540.647469-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
[ Moved the fix from missing reparse.c to smb311_posix_info_to_fattr() in inode.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/inode.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 51d38449ca855..5d21cb051a602 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -672,6 +672,7 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope
/* fattr->cf_rdev = le32_to_cpu(info->DeviceId); */
if (symlink) {
+ fattr->cf_mode &= ~S_IFMT;
fattr->cf_mode |= S_IFLNK;
fattr->cf_dtype = DT_LNK;
fattr->cf_symlink_target = data->symlink_target;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0129/1887] smb: client: fix cifsFileInfo reference leak in deferred close
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0128/1887] smb: client: fix file type corruption in cifs_reparse_point_to_fattr() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0130/1887] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy() Greg Kroah-Hartman
` (869 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Paulo Alcantara,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 5520e89a5a4f834bced64cf2ac927001cc513a40 ]
When cifs_close() defers a close, it hands the cifsFileInfo reference
of the closing struct file to the queued work. Each execution of
smb2_deferred_work_close() drops one such reference.
deferred_close_scheduled can be false while the work is pending: the
workqueue clears PENDING when the callback starts to run, before the
callback clears the flag under deferred_lock. A close in that
interval requeues the running work, and the callback then clears the
flag, leaving the requeued work pending with the flag down. A later
cifs_open() can reuse the handle and its cifs_close() reaches the
same branch: queue_delayed_work() fails because the work is still
pending, but cifs_close() returns without dropping the closing file's
reference. The cifsFileInfo count stays pinned and its tlink, dentry
and server handle are leaked.
Check the return value and hand off the reference only when work was
actually queued. Otherwise, use the shared _cifsFileInfo_put(), like
the mod_delayed_work() branch above: the pending execution already
owns its reference.
This issue was found by an in-house static analysis tool.
Fixes: c3f207ab29f7 ("cifs: Deferred close for files")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Adjusted cifs_close() context due to missing trace_smb3_close_cached(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/file.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 466d25c90a10f..35689e7bb16a7 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -1042,11 +1042,18 @@ int cifs_close(struct inode *inode, struct file *file)
cifsFileInfo_get(cfile);
} else {
/* Deferred close for files */
- queue_delayed_work(deferredclose_wq,
- &cfile->deferred, cifs_sb->ctx->closetimeo);
- cfile->deferred_close_scheduled = true;
- spin_unlock(&cinode->deferred_lock);
- return 0;
+ /*
+ * Each queued execution owns one reference.
+ * If nothing was queued, the reference of
+ * the closing file is dropped below.
+ */
+ if (queue_delayed_work(deferredclose_wq,
+ &cfile->deferred,
+ cifs_sb->ctx->closetimeo)) {
+ cfile->deferred_close_scheduled = true;
+ spin_unlock(&cinode->deferred_lock);
+ return 0;
+ }
}
spin_unlock(&cinode->deferred_lock);
_cifsFileInfo_put(cfile, true, false);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0130/1887] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0129/1887] smb: client: fix cifsFileInfo reference leak in deferred close Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0131/1887] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
` (868 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Thumshirn, Hongling Zeng,
David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongling Zeng <zenghongling@kylinos.cn>
[ Upstream commit 0594e3423f4ba3137c734371169491f9a98e9af4 ]
mark_block_group_to_copy() iterates over the commit root with
skip_locking=true. A concurrent transaction commit can swap and free
the commit root during iteration, causing use-after-free when
accessing extent buffers.
Fix it by using path->need_commit_sem to protect the commit root search.
Fixes: 78ce9fc269af ("btrfs: zoned: mark block groups to copy for device-replace")
CC: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.5
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
[ changed path->need_commit_sem assignment from true to 1 to match the older unsigned bitfield representation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/dev-replace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 9c856a73d5333..f9c43aadc78ad 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -520,6 +520,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
path->reada = READA_FORWARD;
path->search_commit_root = 1;
path->skip_locking = 1;
+ path->need_commit_sem = 1;
key.objectid = src_dev->devid;
key.type = BTRFS_DEV_EXTENT_KEY;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0131/1887] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0130/1887] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0132/1887] watchdog: rtd119x: Use devm_clk_get_enabled() helper Greg Kroah-Hartman
` (867 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shakeel Butt,
syzbot+cd2073ee6d958a8d0fcd, Hugh Dickins, Jann Horn,
Liam R. Howlett, Lorenzo Stoakes, Matthew Wilcox (Oracle),
Pedro Falcato, Vlastimil Babka, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shakeel Butt <shakeel.butt@linux.dev>
[ Upstream commit e14a3454806468b086fe2e4ca2e1bff95b528531 ]
NR_MLOCK is updated from interrupt context. __free_pages_prepare() clears
a stray PG_mlocked and adjusts NR_MLOCK, and a folio can reach it with the
flag still set from a bio completion handler:
__free_pages_ok+0x6af/0x7a0
<IRQ>
__bio_release_pages+0xde/0x260
__iomap_dio_bio_end_io+0x16e/0x1a0
blk_update_request+0x14b/0x3d0
blk_mq_end_request+0x18/0x30
blk_done_softirq+0x49/0x60
The folio gets there like this. A MAP_SHARED file mapping is mlocked, so
its page cache folios carry PG_mlocked, and an O_DIRECT write sourced from
that mapping GUP-pins those same folios. munlock() then runs
mlock_vma_pages_range(), which clears VM_LOCKED before walking the page
tables to munlock each folio. A concurrent hole punch reaches the folio
through the rmap (i_mmap_rwsem, not mmap_lock) and can land inside that
window: __folio_remove_rmap() -> munlock_vma_folio() sees VM_LOCKED
already clear, so it neither queues the folio on the mlock batch nor takes
a reference, and the pte it clears makes the pending mlock_pte_range()
walk skip the folio at its !pte_present() check. filemap_remove_folio()
then drops the page cache reference, leaving the bio's pin as the last
one, released from the completion handler above.
So __zone_stat_mod_folio() here needs interrupts disabled, not merely
preemption, and __munlock_folio() has a path where they are not: when the
folio has already been taken off the LRU by somebody else the function
jumps straight to the counter update without taking the lruvec lock. The
read-modify-write of the per-CPU NR_MLOCK diff can then be interrupted by
the softirq above, and one of the two decrements is lost, leaving Mlocked
in /proc/meminfo permanently overstated.
Use zone_stat_mod_folio(). mod_zone_state()'s this_cpu_try_cmpxchg() is
atomic against a same-CPU interrupt and retries, and on the path where the
lruvec lock is held its cost is negligible next to the lock itself.
The UNEVICTABLE_PG* events are deliberately left on the __ accessors: they
occupy different vm_event_states slots from the UNEVICTABLE_PGCLEARED that
__free_pages_prepare() bumps, and nothing updates those two from interrupt
context.
Link: https://lore.kernel.org/20260901180109.3797944-1-shakeel.butt@linux.dev
Fixes: 2fbb0c10d1e8 ("mm/munlock: mlock_page() munlock_page() batch by pagevec")
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Reported-by: syzbot+cd2073ee6d958a8d0fcd@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-mm/6a931c5a.08e933ee.dbf97.0093.GAE@google.com/
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mlock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/mlock.c b/mm/mlock.c
index 3bf9e1d263da4..0124022f0f379 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -141,7 +141,7 @@ static struct lruvec *__munlock_page(struct page *page, struct lruvec *lruvec)
munlock:
if (TestClearPageMlocked(page)) {
- __mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages);
+ mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages);
if (isolated || !PageUnevictable(page))
__count_vm_events(UNEVICTABLE_PGMUNLOCKED, nr_pages);
else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0132/1887] watchdog: rtd119x: Use devm_clk_get_enabled() helper
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0131/1887] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0133/1887] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
` (866 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christophe JAILLET, Guenter Roeck,
Wim Van Sebroeck, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
[ Upstream commit 6cc0768ba6f5293a4435612164a2cfbf2edbd025 ]
The devm_clk_get_enabled() helper:
- calls devm_clk_get()
- calls clk_prepare_enable() and registers what is needed in order to
call clk_disable_unprepare() when needed, as a managed resource.
This simplifies the code and avoids the need of a dedicated function used
with devm_add_action_or_reset().
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/14b521b821279bc5111dc80b55d0936c5767c737.1672418470.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
Stable-dep-of: 5af7d2cbd20f ("watchdog: rtd119x: Avoid division by zero")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/rtd119x_wdt.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/drivers/watchdog/rtd119x_wdt.c b/drivers/watchdog/rtd119x_wdt.c
index 834b94ff3f903..95c8d7abce42e 100644
--- a/drivers/watchdog/rtd119x_wdt.c
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -94,16 +94,10 @@ static const struct of_device_id rtd119x_wdt_dt_ids[] = {
{ }
};
-static void rtd119x_clk_disable_unprepare(void *data)
-{
- clk_disable_unprepare(data);
-}
-
static int rtd119x_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rtd119x_watchdog_device *data;
- int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -113,18 +107,10 @@ static int rtd119x_wdt_probe(struct platform_device *pdev)
if (IS_ERR(data->base))
return PTR_ERR(data->base);
- data->clk = devm_clk_get(dev, NULL);
+ data->clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
- ret = clk_prepare_enable(data->clk);
- if (ret)
- return ret;
- ret = devm_add_action_or_reset(dev, rtd119x_clk_disable_unprepare,
- data->clk);
- if (ret)
- return ret;
-
data->wdt_dev.info = &rtd119x_wdt_info;
data->wdt_dev.ops = &rtd119x_wdt_ops;
data->wdt_dev.timeout = 120;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0133/1887] watchdog: rtd119x: Avoid division by zero
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0132/1887] watchdog: rtd119x: Use devm_clk_get_enabled() helper Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0134/1887] hwmon: (pwm-fan) Stop RPM timer before freeing tach data Greg Kroah-Hartman
` (865 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 5af7d2cbd20f893def03c8310a460ade66a5d822 ]
clk_get_rate() could return 0. Avoid a division by zero panic.
Fixes: 2bdf6acbfead ("watchdog: Add Realtek RTD1295")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260913064851.8239-3-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/rtd119x_wdt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/rtd119x_wdt.c b/drivers/watchdog/rtd119x_wdt.c
index 95c8d7abce42e..e963be4df8c4e 100644
--- a/drivers/watchdog/rtd119x_wdt.c
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -98,6 +98,7 @@ static int rtd119x_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rtd119x_watchdog_device *data;
+ unsigned long rate;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -111,10 +112,14 @@ static int rtd119x_wdt_probe(struct platform_device *pdev)
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
+ rate = clk_get_rate(data->clk);
+ if (!rate)
+ return -EINVAL;
+
data->wdt_dev.info = &rtd119x_wdt_info;
data->wdt_dev.ops = &rtd119x_wdt_ops;
data->wdt_dev.timeout = 120;
- data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
+ data->wdt_dev.max_timeout = 0xffffffff / rate;
data->wdt_dev.min_timeout = 1;
data->wdt_dev.parent = dev;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0134/1887] hwmon: (pwm-fan) Stop RPM timer before freeing tach data
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0133/1887] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0135/1887] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown Greg Kroah-Hartman
` (864 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yibo Tan, Guenter Roeck, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yibo Tan <lhfff@tju.edu.cn>
[ Upstream commit 26d5ff79768548efb1e604bb6e8697c101e06269 ]
sample_timer() rearms the RPM timer and accesses the devm-managed
ctx->tachs and ctx->pulses_per_revolution arrays. The cleanup action
which stops the timer is registered before those arrays are allocated.
Since devres releases entries in reverse order, driver detach can free
the arrays before pwm_fan_cleanup() shuts down the timer. A timer expiry
in that window accesses the freed tach data.
With a KASAN kernel, a test-only kprobe delayed entry to
pwm_fan_cleanup() while normal sysfs unbind ran. Each of three runs
reported three four-byte reads and two four-byte writes in sample_timer()
after its backing devm allocations had been freed. The helper did not
invoke the timer callback, cleanup actions or free functions.
With the fix, three matching unbind runs completed without KASAN, BUG,
WARNING, Oops or panic. Instrumentation confirmed that timer retirement
completed before the first timer backing allocation was released.
Split timer retirement from the power cleanup and register its devres
action after the timer backing data and IRQ actions are installed. This
preserves the early power rollback action while ensuring the timer is
retired before its backing data is released. Use timer_shutdown_sync()
because the callback can rearm itself.
Fixes: 01695410d452 ("hwmon: (pwm-fan) Store tach data separately")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Link: https://patch.msgid.link/20260911071809.130151-1-lhfff@tju.edu.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[ Adapted cleanup changes to the older pwm_fan_cleanup() using del_timer_sync() without pwm_shutdown handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pwm-fan.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 83a347ca35da5..a6449586d4d7b 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -466,12 +466,18 @@ static void pwm_fan_cleanup(void *__ctx)
{
struct pwm_fan_ctx *ctx = __ctx;
- del_timer_sync(&ctx->rpm_timer);
/* Switch off everything */
ctx->enable_mode = pwm_disable_reg_disable;
pwm_fan_power_off(ctx);
}
+static void pwm_fan_timer_cleanup(void *__ctx)
+{
+ struct pwm_fan_ctx *ctx = __ctx;
+
+ timer_shutdown_sync(&ctx->rpm_timer);
+}
+
static int pwm_fan_probe(struct platform_device *pdev)
{
struct thermal_cooling_device *cdev;
@@ -598,6 +604,10 @@ static int pwm_fan_probe(struct platform_device *pdev)
}
if (ctx->tach_count > 0) {
+ ret = devm_add_action_or_reset(dev, pwm_fan_timer_cleanup, ctx);
+ if (ret)
+ return ret;
+
ctx->sample_start = ktime_get();
mod_timer(&ctx->rpm_timer, jiffies + HZ);
@@ -639,6 +649,7 @@ static void pwm_fan_shutdown(struct platform_device *pdev)
{
struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
+ pwm_fan_timer_cleanup(ctx);
pwm_fan_cleanup(ctx);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0135/1887] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0134/1887] hwmon: (pwm-fan) Stop RPM timer before freeing tach data Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0136/1887] smb/client: send lease break ACKs thru correct session for multiuser mounts Greg Kroah-Hartman
` (863 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Loic Poulain,
Jeff Johnson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit d9be5e75530772fc31637070d51e5717d6aeaa2a ]
wcn36xx_dxe_deinit() tears down the TX ack timer with timer_delete(),
which only dequeues the timer and does not wait for a callback that is
already executing; the preceding free_irq() calls synchronize the
interrupt handlers only. The callback, wcn36xx_dxe_tx_timer(), can
therefore be running past the teardown and use the wcn freed along
with the ieee80211_hw in wcn36xx_remove(): it takes wcn->dxe_lock,
reads wcn->tx_ack_skb and passes wcn->hw to
ieee80211_tx_status_irqsafe().
Fix this by using timer_shutdown_sync(), which waits for a running
callback and also prevents the timer from being rearmed again. The
timer is set up again by wcn36xx_dxe_init() on the next start, so the
start/stop cycle is unaffected.
This issue was found by an in-house static analysis tool.
Fixes: fdf21cc37149 ("wcn36xx: Add TX ack support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Link: https://patch.msgid.link/20260910020907.3353-1-fanwu01@zju.edu.cn
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
[ Adapted the patch to replace del_timer() instead of timer_delete(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/wcn36xx/dxe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 4e9e13941c8f4..b168db800e07e 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -1054,7 +1054,7 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn)
free_irq(wcn->tx_irq, wcn);
free_irq(wcn->rx_irq, wcn);
- del_timer(&wcn->tx_ack_timer);
+ timer_shutdown_sync(&wcn->tx_ack_timer);
if (wcn->tx_ack_skb) {
ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0136/1887] smb/client: send lease break ACKs thru correct session for multiuser mounts
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0135/1887] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0137/1887] bna: prevent IOC timer rearm during teardown Greg Kroah-Hartman
` (862 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, April Cardenas, Namjae Jeon,
Bharath S M, Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: April Cardenas <april.cardenas@canonical.com>
[ Upstream commit ebc5660132ddd244b57f03ed324922013a3d7363 ]
Currently, when cifs_oplock_break handles a break request from the server
it searches for the appropriate tlink to handle the request
but incorrectly uses the current fsuid as the search key, eventually
causing read errors for users with multiuser mounts on NetApp.
Fix this by using the tlink from the cfile struct instead to respond
through the correct session.
As breaks are handled in a worker thread, the current fsuid
isn't guaranteed to match the session that the break is intended for.
This means that cifs_sb_tlink may search the rbtree using the wrong fsuid,
and return a tlink with an incorrect session than
the lease break was intended for. As a result, the breaks
may be ACKed through an incorrect session.
While it seems that Samba/Windows Servers 2016-2025 ignore this as long as
the lease key is correct, we ran into a case where if you're using
NetApp ONTAP or Azure NetApp Files they will reject the ACK
and return `STATUS_LOCK_NOT_GRANTED` errors on any future read requests
a user may initiate through their still held open file handle,
and the server will eventually close the file.
In the dmesg logs, the user may see errors like these:
CIFS: Status code returned 0xc0000128 STATUS_FILE_CLOSED
CIFS: VFS: Send error in read = -9
With a multiuser mount using NetApp, this issue is really easy
for users to hit on a wide variety of kernel versions
by attempting to copy a file from the share
to the local machine through GNOME Files/Nautilus.
This copy will always result in Nautilus throwing
a `Bad File Descriptor` error to the user and fail.
With this fix, you can copy files through Nautilus without issue.
>From looking at the traces, it seems that glib will
open the file first, and call listxattr before actually attempting
to copy the file data. The listxattr call always triggers a break,
causing the copy to fail.
The proposed fix returns to the way the client grabbed the tlink before
commit e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break").
The bulk of that commit (checking for list empty) remains untouched, and
I think the change to using cifs_sb_tlink was intended to avoid a
NULL/ERR deference on the tlink as well as update the reference count.
I believe this fix should preserve those safety properties, but of course
I'd appreciate any corrections here.
Fixes: e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break")
Cc: stable@vger.kernel.org
Signed-off-by: April Cardenas <april.cardenas@canonical.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: Bharath S M <bharathsm@microsoft.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Removed unused cifs_sb and sb declarations because this branch lacks their remaining upstream use. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/file.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 35689e7bb16a7..d2187882c236f 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -5180,8 +5180,6 @@ void cifs_oplock_break(struct work_struct *work)
struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
oplock_break);
struct inode *inode = d_inode(cfile->dentry);
- struct super_block *sb = inode->i_sb;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsInodeInfo *cinode = CIFS_I(inode);
struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
@@ -5194,8 +5192,8 @@ void cifs_oplock_break(struct work_struct *work)
wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
TASK_UNINTERRUPTIBLE);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
+ tlink = cifs_get_tlink(cfile->tlink);
+ if (IS_ERR_OR_NULL(tlink)) {
/* drop the reference taken when the break was queued */
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0137/1887] bna: prevent IOC timer rearm during teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0136/1887] smb/client: send lease break ACKs thru correct session for multiuser mounts Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0138/1887] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
` (861 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Paolo Abeni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 77b1718e39e5c9f6956fb60807326af20baf889d ]
bna: prevent IOC timer rearm during teardown
bnad_pci_remove() and the probe disable_ioceth path call
timer_delete_sync() for ioc_timer, sem_timer and hb_timer, but not for
iocpf_timer. bnad_iocpf_timeout() then takes bnad->bna_lock after
free_netdev() has freed the struct bnad.
Deleting iocpf_timer last does not fix this. sem_timer and
iocpf_timer rearm each other: bnad_iocpf_sem_timeout() can arm
iocpf_timer, and bnad_iocpf_timeout() arms sem_timer from
bfa_ioc_hw_sem_get() when the semaphore is busy.
timer_delete_sync() only waits out its own callback.
bnad_ioceth_disable() can time out and leave that callback live.
Shut all four IOC timers down with timer_shutdown_sync() on both
paths, so a later mod_timer() is ignored.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: 1d32f7696286 ("bna: IOC failure auto recovery fix")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260922014605.588040-1-mhun512@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ inlined bnad_ioc_timers_shutdown() into the existing teardown functions. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/brocade/bna/bnad.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index aecdb98f8a9c1..1733ccb89311d 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -3728,9 +3728,11 @@ bnad_pci_probe(struct pci_dev *pdev,
bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
disable_ioceth:
bnad_ioceth_disable(bnad);
- del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ /* The IOC timers rearm one another. Shut down all of them. */
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.sem_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.iocpf_timer);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -3771,9 +3773,11 @@ bnad_pci_remove(struct pci_dev *pdev)
mutex_lock(&bnad->conf_mutex);
bnad_ioceth_disable(bnad);
- del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ /* The IOC timers rearm one another. Shut down all of them. */
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.sem_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ timer_shutdown_sync(&bnad->bna.ioceth.ioc.iocpf_timer);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0138/1887] tcp: prevent collapsing skbs across boundary in rtx queue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0137/1887] bna: prevent IOC timer rearm during teardown Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0139/1887] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Greg Kroah-Hartman
` (860 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Willem de Bruijn, Eric Dumazet,
Daniel Zahka, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <willemb@google.com>
[ Upstream commit fc6d80eb504458d6416b75a94188b268c95c6533 ]
tcp_write_collapse_fence() sets TCP_SKB_CB(skb)->eor = 1 on
tcp_write_queue_tail(sk) to prevent skbs queued after a switch to
device encryption from being collapsed into earlier skbs.
The fence is a no-op if all earlier data has already been transmitted
when the switch happens: sk->sk_write_queue is empty. The not yet
acknowledged earlier skbs wait in sk->tcp_rtx_queue with eor 0.
On a subsequent retransmit or SACK shift, tcp_retrans_try_collapse() or
tcp_shift_skb_data() can then merge an skb queued after the switch into
one queued before it.
Both users of the fence are affected:
- psp: devices only encrypt skbs with skb->decrypted set. The merged skb
keeps decrypted = 0 from the earlier skb, so merged data sent after
psp_sock_assoc_set_tx() is retransmitted in cleartext.
- tls device offload: the merged skb straddles the start marker set in
tls_set_device_offload(). The software fallback (fill_sg_in() returns
-EINVAL) and the mlx5, nfp and funeth drivers cannot handle such an
skb and drop it. Every retransmit rebuilds the same skb, so the
connection stalls.
Fix this in two places, for defense in depth:
1. Fall back to tcp_rtx_queue_tail(sk) in tcp_write_collapse_fence()
when tcp_write_queue_tail(sk) is NULL.
2. Check !skb_cmp_decrypted(to, from) in tcp_skb_can_collapse(), as
tcp_skb_can_collapse_rx() does on receive. skb_shift(), which both
collapse paths call, already has a DEBUG_NET_WARN_ON_ONCE() for this
condition.
Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
Link: https://patch.msgid.link/20260924154427.953800-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Applied tcp_write_collapse_fence() changes directly to the existing TLS code blocks because the helper is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/tcp.h | 1 +
net/tls/tls_device.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c25cd0df7a904..245c522387315 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1019,6 +1019,7 @@ static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
{
return likely(tcp_skb_can_collapse_to(to) &&
mptcp_skb_can_collapse(to, from) &&
+ !skb_cmp_decrypted(to, from) &&
skb_pure_zcopy_same(to, from));
}
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index 753c45ecc3562..74b61318a60ac 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -239,7 +239,7 @@ static void tls_device_resync_tx(struct sock *sk, struct tls_context *tls_ctx,
int err = 0;
u8 *rcd_sn;
- skb = tcp_write_queue_tail(sk);
+ skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
if (skb)
TCP_SKB_CB(skb)->eor = 1;
@@ -1181,7 +1181,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
* SKBs where only part of the payload needs to be encrypted.
* So mark the last skb in the write queue as end of record.
*/
- skb = tcp_write_queue_tail(sk);
+ skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
if (skb)
TCP_SKB_CB(skb)->eor = 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0139/1887] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0138/1887] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0140/1887] tracing/user_events: Dont destroy fields when event removal fails Greg Kroah-Hartman
` (859 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namhyung Kim, Dapeng Mi,
Peter Zijlstra (Intel), Zide Chen, Thomas Falcon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
[ Upstream commit 8767b4d73018bd3143f4c55b672064fad292f11b ]
AnyThread mode deprecation is enumerated by CPUID.0AH:EDX[15] instead of
PERF_CAPABILITIES MSR. It's not a good practice to define a bit to
represent "anythread deprecation" in perf_capabilities. It leads to the
anythread_deprecated bit could be overwritten by the real value of
PERF_CAPABILITIES MSR, just like the below code in update_pmu_cap() does.
if (!intel_pmu_broken_perf_cap()) {
/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
rdmsrq(MSR_IA32_PERF_CAPABILITIES, hybrid(pmu, intel_cap).capabilities);
}
It leads to the anythread_deprecated bit is cleared to 0 and the "any"
attribute is incorrectly shown in the /sys/devices/cpu/format/ folder on
these support Perfmon v6 platforms, like Clearwater Forest.
$ grep . /sys/devices/cpu/format/*
/sys/devices/cpu/format/acr_mask:config2:0-63
/sys/devices/cpu/format/any:config:21
/sys/devices/cpu/format/cmask:config:24-31
So remove the anythread_deprecated bit from perf_capabilities structure
and directly depends on CPUID.0AH:EDX[15] to judge if anythread is
deprecated.
Fixes: cadbaa039b99 ("perf/x86/intel: Make anythread filter support conditional")
Reported-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Zide Chen <zide.chen@intel.com>
Reviewed-by: Thomas Falcon <thomas.falcon@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616044654.3468742-2-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 10 +++-------
arch/x86/events/perf_event.h | 2 +-
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 4ddd967a9d3d1..4615a21b9e852 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -5990,12 +5990,6 @@ __init int intel_pmu_init(void)
x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
- if (version >= 5) {
- x86_pmu.intel_cap.anythread_deprecated = edx.split.anythread_deprecated;
- if (x86_pmu.intel_cap.anythread_deprecated)
- pr_cont(" AnyThread deprecated, ");
- }
-
/*
* Install the hw-cache-events table:
*/
@@ -6734,8 +6728,10 @@ __init int intel_pmu_init(void)
(u64)fixed_mask);
/* AnyThread may be deprecated on arch perfmon v5 or later */
- if (x86_pmu.intel_cap.anythread_deprecated)
+ if (version >= 5 && edx.split.anythread_deprecated) {
x86_pmu.format_attrs = intel_arch_formats_attr;
+ pr_cont("AnyThread deprecated, ");
+ }
intel_pmu_check_event_constraints(x86_pmu.event_constraints,
x86_pmu.num_counters,
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index b95cab9846dd7..5f93316c60216 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -606,7 +606,7 @@ union perf_capabilities {
u64 pebs_baseline:1;
u64 perf_metrics:1;
u64 pebs_output_pt_available:1;
- u64 anythread_deprecated:1;
+ u64 __reserved:1;
};
u64 capabilities;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0140/1887] tracing/user_events: Dont destroy fields when event removal fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0139/1887] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0141/1887] mm/kmemleak: simplify kmemleak_cond_resched() usage Greg Kroah-Hartman
` (858 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henry Martin, Beau Belgrave,
Steven Rostedt, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <bsdhenrymartin@gmail.com>
[ Upstream commit 2deb753127d7b7035e893955c5e91875e767d1f8 ]
destroy_user_event() destroys the event's fields before attempting to
remove the trace event call. If user_event_set_call_visible() fails,
e.g. because the event is still enabled and trace_remove_event_call()
returns -EBUSY, the event is left registered with an irreversibly
destroyed field list. Any subsequent interaction with the event then
operates on an empty field list while it is still fully visible in
tracefs.
Move the field destruction after the call removal, and splice the
field list back onto the event when the removal fails so the event
remains in a consistent state.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260904115223.2976446-1-bsdhenrymartin@gmail.com
Fixes: 7f5a08c79df35 ("user_events: Add minimal support for trace_event into ftrace")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Reviewed-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ Adjusted context for the missing lockdep_assert_held(&event_mutex) in destroy_user_event(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace_events_user.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index bff699fe9e712..6186474c027fa 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -430,10 +430,9 @@ static void user_event_destroy_validators(struct user_event *user)
}
}
-static void user_event_destroy_fields(struct user_event *user)
+static void user_event_destroy_fields(struct list_head *head)
{
struct ftrace_event_field *field, *next;
- struct list_head *head = &user->fields;
list_for_each_entry_safe(field, next, head, link) {
list_del(&field->link);
@@ -821,15 +820,30 @@ static int user_event_set_call_visible(struct user_event *user, bool visible)
static int destroy_user_event(struct user_event *user)
{
+ LIST_HEAD(fields);
int ret = 0;
- /* Must destroy fields before call removal */
- user_event_destroy_fields(user);
+ /*
+ * Detach the fields before removing the call. Removing the event
+ * frees the field list memory (trace_destroy_fields() is run on
+ * successful removal and kmem_cache_free()s the fields), but the
+ * fields here are allocated and owned by user_events. Destroy
+ * them separately once removal has succeeded.
+ */
+ list_splice_init(&user->fields, &fields);
ret = user_event_set_call_visible(user, false);
- if (ret)
+ if (ret) {
+ /*
+ * Removal failed and the event stays registered, recover
+ * the fields so it is left in a consistent state.
+ */
+ list_splice(&fields, &user->fields);
return ret;
+ }
+
+ user_event_destroy_fields(&fields);
dyn_event_remove(&user->devent);
@@ -1360,7 +1374,7 @@ static int user_event_parse(struct user_event_group *group, char *name,
put_user_lock:
mutex_unlock(&event_mutex);
put_user:
- user_event_destroy_fields(user);
+ user_event_destroy_fields(&user->fields);
user_event_destroy_validators(user);
kfree(user->call.print_fmt);
kfree(user);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0141/1887] mm/kmemleak: simplify kmemleak_cond_resched() usage
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0140/1887] tracing/user_events: Dont destroy fields when event removal fails Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0142/1887] mm/kmemleak: fix UAF bug in kmemleak_scan() Greg Kroah-Hartman
` (857 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Waiman Long, Catalin Marinas,
Muchun Song, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <longman@redhat.com>
[ Upstream commit 6061e740822530a4ef443548b19c4e0bc6342c7a ]
Patch series "mm/kmemleak: Simplify kmemleak_cond_resched() & fix UAF", v2.
It was found that a KASAN use-after-free error was reported in the
kmemleak_scan() function. After further examination, it is believe that
even though a reference is taken from the current object, it does not
prevent the object pointed to by the next pointer from going away after a
cond_resched().
To fix that, additional flags are added to make sure that the current
object won't be removed from the object_list during the duration of the
cond_resched() to ensure the validity of the next pointer.
While making the change, I also simplify the current usage of
kmemleak_cond_resched() to make it easier to understand.
This patch (of 2):
The presence of a pinned argument and the 64k loop count make
kmemleak_cond_resched() a bit more complex to read. The pinned argument
is used only by first kmemleak_scan() loop.
Simplify the usage of kmemleak_cond_resched() by removing the pinned
argument and always do a get_object()/put_object() sequence. In addition,
the 64k loop is removed by using need_resched() to decide if
kmemleak_cond_resched() should be called.
Link: https://lkml.kernel.org/r/20230119040111.350923-1-longman@redhat.com
Link: https://lkml.kernel.org/r/20230119040111.350923-2-longman@redhat.com
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Muchun Song <songmuchun@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kmemleak.c | 48 ++++++++++++------------------------------------
1 file changed, 12 insertions(+), 36 deletions(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index d3c9a63d7a9d5..fa01854e32b09 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1466,22 +1466,17 @@ static void scan_gray_list(void)
/*
* Conditionally call resched() in a object iteration loop while making sure
* that the given object won't go away without RCU read lock by performing a
- * get_object() if !pinned.
- *
- * Return: false if can't do a cond_resched() due to get_object() failure
- * true otherwise
+ * get_object() if necessaary.
*/
-static bool kmemleak_cond_resched(struct kmemleak_object *object, bool pinned)
+static void kmemleak_cond_resched(struct kmemleak_object *object)
{
- if (!pinned && !get_object(object))
- return false;
+ if (!get_object(object))
+ return; /* Try next object */
rcu_read_unlock();
cond_resched();
rcu_read_lock();
- if (!pinned)
- put_object(object);
- return true;
+ put_object(object);
}
/*
@@ -1495,15 +1490,12 @@ static void kmemleak_scan(void)
struct zone *zone;
int __maybe_unused i;
int new_leaks = 0;
- int loop_cnt = 0;
jiffies_last_scan = jiffies;
/* prepare the kmemleak_object's */
rcu_read_lock();
list_for_each_entry_rcu(object, &object_list, object_list) {
- bool obj_pinned = false;
-
raw_spin_lock_irq(&object->lock);
#ifdef DEBUG
/*
@@ -1529,19 +1521,13 @@ static void kmemleak_scan(void)
/* reset the reference count (whiten the object) */
object->count = 0;
- if (color_gray(object) && get_object(object)) {
+ if (color_gray(object) && get_object(object))
list_add_tail(&object->gray_list, &gray_list);
- obj_pinned = true;
- }
raw_spin_unlock_irq(&object->lock);
- /*
- * Do a cond_resched() every 64k objects to avoid soft lockup.
- */
- if (!(++loop_cnt & 0xffff) &&
- !kmemleak_cond_resched(object, obj_pinned))
- loop_cnt--; /* Try again on next object */
+ if (need_resched())
+ kmemleak_cond_resched(object);
}
rcu_read_unlock();
@@ -1608,14 +1594,9 @@ static void kmemleak_scan(void)
* scan and color them gray until the next scan.
*/
rcu_read_lock();
- loop_cnt = 0;
list_for_each_entry_rcu(object, &object_list, object_list) {
- /*
- * Do a cond_resched() every 64k objects to avoid soft lockup.
- */
- if (!(++loop_cnt & 0xffff) &&
- !kmemleak_cond_resched(object, false))
- loop_cnt--; /* Try again on next object */
+ if (need_resched())
+ kmemleak_cond_resched(object);
/*
* This is racy but we can save the overhead of lock/unlock
@@ -1650,14 +1631,9 @@ static void kmemleak_scan(void)
* Scanning result reporting.
*/
rcu_read_lock();
- loop_cnt = 0;
list_for_each_entry_rcu(object, &object_list, object_list) {
- /*
- * Do a cond_resched() every 64k objects to avoid soft lockup.
- */
- if (!(++loop_cnt & 0xffff) &&
- !kmemleak_cond_resched(object, false))
- loop_cnt--; /* Try again on next object */
+ if (need_resched())
+ kmemleak_cond_resched(object);
/*
* This is racy but we can save the overhead of lock/unlock
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0142/1887] mm/kmemleak: fix UAF bug in kmemleak_scan()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0141/1887] mm/kmemleak: simplify kmemleak_cond_resched() usage Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0143/1887] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish Greg Kroah-Hartman
` (856 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Waiman Long, Catalin Marinas,
Muchun Song, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <longman@redhat.com>
[ Upstream commit 782e4179535971c3574c367bfaaefea8970b3e0b ]
Commit 6edda04ccc7c ("mm/kmemleak: prevent soft lockup in first object
iteration loop of kmemleak_scan()") fixes soft lockup problem in
kmemleak_scan() by periodically doing a cond_resched(). It does take a
reference of the current object before doing it. Unfortunately, if the
object has been deleted from the object_list, the next object pointed to
by its next pointer may no longer be valid after coming back from
cond_resched(). This can result in use-after-free and other nasty
problem.
Fix this problem by adding a del_state flag into kmemleak_object structure
to synchronize the object deletion process between kmemleak_cond_resched()
and __remove_object() to make sure that the object remained in the
object_list in the duration of the cond_resched() call.
Link: https://lkml.kernel.org/r/20230119040111.350923-3-longman@redhat.com
Fixes: 6edda04ccc7c ("mm/kmemleak: prevent soft lockup in first object iteration loop of kmemleak_scan()")
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Muchun Song <songmuchun@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kmemleak.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index fa01854e32b09..3e41e669e2528 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -13,11 +13,12 @@
*
* The following locks and mutexes are used by kmemleak:
*
- * - kmemleak_lock (raw_spinlock_t): protects the object_list modifications and
- * accesses to the object_tree_root (or object_phys_tree_root). The
- * object_list is the main list holding the metadata (struct kmemleak_object)
- * for the allocated memory blocks. The object_tree_root and object_phys_tree_root
- * are red black trees used to look-up metadata based on a pointer to the
+ * - kmemleak_lock (raw_spinlock_t): protects the object_list as well as
+ * del_state modifications and accesses to the object_tree_root (or
+ * object_phys_tree_root). The object_list is the main list holding the
+ * metadata (struct kmemleak_object) for the allocated memory blocks.
+ * The object_tree_root and object_phys_tree_root are red
+ * black trees used to look-up metadata based on a pointer to the
* corresponding memory block. The object_phys_tree_root is for objects
* allocated with physical address. The kmemleak_object structures are
* added to the object_list and object_tree_root (or object_phys_tree_root)
@@ -147,6 +148,7 @@ struct kmemleak_object {
struct rcu_head rcu; /* object_list lockless traversal */
/* object usage count; object freed when use_count == 0 */
atomic_t use_count;
+ unsigned int del_state; /* deletion state */
unsigned long pointer;
size_t size;
/* pass surplus references to this pointer */
@@ -177,6 +179,11 @@ struct kmemleak_object {
/* flag set for object allocated with physical address */
#define OBJECT_PHYS (1 << 4)
+/* set when __remove_object() called */
+#define DELSTATE_REMOVED (1 << 0)
+/* set to temporarily prevent deletion from object_list */
+#define DELSTATE_NO_DELETE (1 << 1)
+
#define HEX_PREFIX " "
/* number of bytes to print per line; must be 16 or 32 */
#define HEX_ROW_SIZE 16
@@ -570,7 +577,9 @@ static void __remove_object(struct kmemleak_object *object)
rb_erase(&object->rb_node, object->flags & OBJECT_PHYS ?
&object_phys_tree_root :
&object_tree_root);
- list_del_rcu(&object->object_list);
+ if (!(object->del_state & DELSTATE_NO_DELETE))
+ list_del_rcu(&object->object_list);
+ object->del_state |= DELSTATE_REMOVED;
}
/*
@@ -636,6 +645,7 @@ static void __create_object(unsigned long ptr, size_t size,
object->count = 0; /* white color initially */
object->jiffies = jiffies;
object->checksum = 0;
+ object->del_state = 0;
/* task information */
if (in_hardirq()) {
@@ -1473,9 +1483,22 @@ static void kmemleak_cond_resched(struct kmemleak_object *object)
if (!get_object(object))
return; /* Try next object */
+ raw_spin_lock_irq(&kmemleak_lock);
+ if (object->del_state & DELSTATE_REMOVED)
+ goto unlock_put; /* Object removed */
+ object->del_state |= DELSTATE_NO_DELETE;
+ raw_spin_unlock_irq(&kmemleak_lock);
+
rcu_read_unlock();
cond_resched();
rcu_read_lock();
+
+ raw_spin_lock_irq(&kmemleak_lock);
+ if (object->del_state & DELSTATE_REMOVED)
+ list_del_rcu(&object->object_list);
+ object->del_state &= ~DELSTATE_NO_DELETE;
+unlock_put:
+ raw_spin_unlock_irq(&kmemleak_lock);
put_object(object);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0143/1887] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0142/1887] mm/kmemleak: fix UAF bug in kmemleak_scan() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0144/1887] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
` (855 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jinjiang Tu, Andrew Morton,
Lance Yang, Lorenzo Stoakes (ARM), David Hildenbrand (Arm),
Vlastimil Babka (SUSE), Minchan Kim, Harry Yoo,
Hiroyouki Kamezawa, Jann Horn, Kefeng Wang, Larry Woodman,
Liam R. Howlett, Nanyong Sun, Rik van Riel, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu <tujinjiang@huawei.com>
[ Upstream commit b6ac0b3f6013c168f22cad97e79967accacb08e1 ]
On arm64 server, we find that a task trying to grab the anon_vma lock
triggers hungtask.
INFO: task main:2354726 blocked for more than 120 seconds.
Tainted: G E 5.10.0-0021.aarch64 #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:main state:D stack: 0 pid:2354726 ppid:2350673 flags:0x00000a01
Call trace:
__switch_to+0x7c/0xbc
__schedule+0x3b4/0x8a0
schedule+0x50/0xe0
rwsem_down_write_slowpath+0x3cc/0x6cc
down_write+0x60/0x260
__anon_vma_prepare+0x6c/0x210
do_anonymous_page+0x258/0x660
handle_pte_fault+0x188/0x214
__handle_mm_fault+0x1b0/0x380
handle_mm_fault+0xf4/0x284
do_page_fault+0x19c/0x494
do_translation_fault+0xcc/0xf8
do_mem_abort+0x48/0xac
el0_da+0x44/0x80
el0_sync_handler+0x88/0xb4
el0_sync+0x160/0x180
After analyzing the vmcore, we found the anon_vma->root->rwsem.count is
-1. There is another anon_vma whose anon_vma->root->rwsem.count is 1, the
anon_vma->root->rwsem.owner shows the lock is held, but the stack of the
task shows the task doesn't hold the anon_vma lock.
After adding more debugging info, we found __anon_vma_prepare() reuses
anon_vma and triggers the UAF of anon_vma->root due to missing memory
barrier, leading to locking and unlocking two different anon_vma->root,
thus leading to an anon_vma will never be unlocked, and another anon_vma
couldn't be locked anymore.
This race requires two adjacent VMAs that are not merged but are
anon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be
changed by mprotect()). Two threads fault on each VMA concurrently, both
calling __anon_vma_prepare() with only mmap_lock held for reading.
THREAD A THREAD B
__anon_vma_prepare __anon_vma_prepare
find_mergeable_anon_vma() -> NULL
anon_vma = anon_vma_alloc();
anon_vma->root = anon_vma;
// the two stores may be reordered
vma->anon_vma = anon_vma;
// finds A's anon_vma
anon_vma = find_mergeable_anon_vma(vma);
anon_vma_lock_write(anon_vma);
// may still see the old root
down_write(&anon_vma->root->rwsem);
anon_vma_unlock_write(anon_vma);
// see the new root, never unlock old
up_write(&anon_vma->root->rwsem);
thread A triggers page fault and calls __anon_vma_prepare() to prepare
anon_vma for the faulting vma. __anon_vma_prepare() allocates and
initializes a new anon_vma, and then publishes it to the vma with a plain
store. anon_vma_prepare() only requires the mmap_lock to be held for
reading, so two threads can fault on adjacent VMAs at the same time.
While thread A publishes a new anon_vma, thread B could find the anon_vma
via find_mergeable_anon_vma() and then locks anon_vma->root->rwsem.
The store to anon_vma->root in anon_vma_alloc() and the store to
vma->anon_vma can be reordered. The anon_vma_lock_write() and spin_lock()
only provide acquire semantics, which do not prevent prior stores from
being reordered after them. The release semantics of the corresponding
spin_unlock() and anon_vma_unlock_write() come too late, the store to
vma->anon_vma is already published before they take effect. As a result,
thread B can observe the following order:
vma->anon_vma = anon_vma;
anon_vma->root = anon_vma;
The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma
may reuse memory from a previously freed one. The constructor
(anon_vma_ctor) does not reset anon_vma->root, and __put_anon_vma()
doesn't clear it either, so the old root value persists until
anon_vma_alloc() overwrites it. If that store isn't visible, thread B
reads a root that points to the old anon_vma and locks it.
As a result, thread B can call anon_vma_lock_write() with the old root,
and call anon_vma_unlock_write() with the new root, leading to an anon_vma
will never be unlocked, and another anon_vma couldn't be locked anymore
(its count is dropped from 0 to -1 due to wrong unlock).
To fix it, change the plain store `vma->anon_vma = anon_vma` to store
release, so that the fields of anon_vma are visible before anon_vma is
published to vma->anon_vma.
At read side, the load of anon_vma and anon_vma->root have address
dependency. According to Documentation/memory-barriers.txt and some
investigations, only Alpha needs address-dependency barriers and it has
been handled by READ_ONCE() in reusable_anon_vma().
We reproduced this issue in v5.10 with KSM enabled. The kernel doesn't
merge commit cf7e7a3503df ("mm: prevent KSM from breaking VMA merging for
new VMAs"), so there are many adjacent VMAs that aren't merged but are
compatible for anon_vma.
Without this fix, our production environment could reproduce this issue
about 2-5 times each month. After adding a smp_mb() before
anon_vma_lock_write(anon_vma) in __anon_vma_prepare(), which is different
to this patch, this issue hasn't been reproduced for one month.
Link: https://lore.kernel.org/20260908122924.554373-1-tujinjiang@huawei.com
Fixes: 5c341ee1dfc8 ("mm: track the root (oldest) anon_vma")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Harry Yoo <harry@kernel.org>
Cc: Hiroyouki Kamezawa <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Jann Horn <jannh@google.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Larry Woodman <lwoodman@redhat.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: <stable@vger.kernel.org>
[ adjusted context for mm/mmap.c and the existing anon_vma_chain_link() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mmap.c | 8 ++++++++
mm/rmap.c | 6 +++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/mm/mmap.c b/mm/mmap.c
index f93526b3df0c3..d39e31f15e86c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1131,6 +1131,13 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *
* acceptable for merging, so we can do all of this optimistically. But
* we do that READ_ONCE() to make sure that we never re-load the pointer.
*
+ * The READ_ONCE() establishes an address dependency between anon_vma and
+ * any access to its fields, which pairs with the assignment to
+ * vma->anon_vma performed with release semantics in __anon_vma_prepare().
+ *
+ * This is especially important as anon_vma's are SLAB_TYPESAFE_BY_RCU so
+ * accessing an uninitialised anon_vma's fields may result in a UAF.
+ *
* IOW: that the "list_is_singular()" test on the anon_vma_chain only
* matters for the 'stable anon_vma' case (ie the thing we want to avoid
* is to return an anon_vma that is "complex" due to having gone through
@@ -1143,6 +1150,7 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *
static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
{
if (anon_vma_compatible(a, b)) {
+ /* Paired with a memory barrier in __anon_vma_prepare(). */
struct anon_vma *anon_vma = READ_ONCE(old->anon_vma);
if (anon_vma && list_is_singular(&old->anon_vma_chain))
diff --git a/mm/rmap.c b/mm/rmap.c
index 886000da89a6f..8e74d143433ae 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -210,7 +210,11 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
if (likely(!vma->anon_vma)) {
- vma->anon_vma = anon_vma;
+ /*
+ * Make anon_vma fields visible before anon_vma is published.
+ * Paired with an address dependency in reusable_anon_vma().
+ */
+ smp_store_release(&vma->anon_vma, anon_vma);
anon_vma_chain_link(vma, avc, anon_vma);
anon_vma->num_active_vmas++;
allocated = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0144/1887] mm/hugetlb: preserve mremap address delta when skipping page tables
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0143/1887] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0145/1887] openvswitch: prepare for stolen verdict coming from conntrack and nat engine Greg Kroah-Hartman
` (854 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jaewook You, Andrew Morton,
David Hildenbrand (Arm), Johan Hovold, Muchun Song,
Oscar Salvador, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaewook You <jaewook376@gmail.com>
[ Upstream commit 9bdad082d44bdcf93716973dcba6be77e8a06e7b ]
move_hugetlb_page_tables() optimizes mremap() by advancing to the last
entry in the page table when the source page table does not exist, either
initially or after unsharing a PMD table. The common loop increment then
steps to the first entry in the next page table.
However, the code advances both the source and destination addresses to
the last entries in their respective page tables, which is wrong. The
destination address must be advanced only by the same amount as the source
address.
If the source and destination offsets within their page tables differ, the
destination address can be advanced too far, causing follow-up issues.
Fix this by advancing the destination address by the source advance
distance.
With a reproducer, we were able to trigger a kernel panic on x86-64. With
this fix in place, we can no longer reproduce the issue.
Link: https://lore.kernel.org/20260914132352.472-1-jaewook376@gmail.com
Fixes: e95a9851787b ("hugetlb: skip to end of PT page mapping when pte not present")
Fixes: 4ddb4d91b82f ("hugetlb: do not update address in huge_pmd_unshare")
Signed-off-by: Jaewook You <jaewook376@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Assisted-by: LLM
[ Adjusted context to retain huge_pte_offset() instead of hugetlb_walk(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bfcb936084e85..a44a6602659cf 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5278,18 +5278,21 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
hugetlb_vma_lock_write(vma);
i_mmap_lock_write(mapping);
for (; old_addr < old_end; old_addr += sz, new_addr += sz) {
+ const unsigned long offset_to_last_entry =
+ (old_addr | last_addr_mask) - old_addr;
+
src_pte = huge_pte_offset(mm, old_addr, sz);
if (!src_pte) {
- old_addr |= last_addr_mask;
- new_addr |= last_addr_mask;
+ old_addr += offset_to_last_entry;
+ new_addr += offset_to_last_entry;
continue;
}
if (huge_pte_none(huge_ptep_get(src_pte)))
continue;
if (huge_pmd_unshare(&tlb, vma, old_addr, src_pte)) {
- old_addr |= last_addr_mask;
- new_addr |= last_addr_mask;
+ old_addr += offset_to_last_entry;
+ new_addr += offset_to_last_entry;
continue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0145/1887] openvswitch: prepare for stolen verdict coming from conntrack and nat engine
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0144/1887] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0146/1887] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
` (853 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Florian Westphal, Aaron Conole,
David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit c7f79f2620b7776586c626edf21eb6ed6ed3d1eb ]
At this time, conntrack either returns NF_ACCEPT or NF_DROP.
To improve debuging it would be nice to be able to replace NF_DROP
verdict with NF_DROP_REASON() helper,
This helper releases the skb instantly (so drop_monitor can pinpoint
precise location) and returns NF_STOLEN.
Prepare call sites to deal with this before introducing such changes
in conntrack and nat core.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Aaron Conole <aconole@redhat.om>
Signed-off-by: David S. Miller <davem@davemloft.net>
[Stable 6.1 adaptation: retain the local NAT implementation, which already
updates the flow key only on NF_ACCEPT, and return before restoring skb
headers on NF_STOLEN. Rename the existing OVS helper and pass its existing
connection and ctinfo explicitly so the following helper-UAF fix can use
the upstream call signature without importing the shared-helper refactor.
Use a single-evaluation verdict_to_errno macro instead of adding a function.
Remove the dead add_helper flag and align the helper-call condition with
1a4151e6be57; the flag was set only for unconfirmed connections but tested
only for confirmed ones. The helper relocation itself remains in the target.]
Stable-dep-of: 1a4151e6be57 ("net: openvswitch: conntrack: fix helper UAF due to extensions realloc")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/openvswitch/conntrack.c | 56 ++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index a7bb9e360ed37..8c5f6602af44a 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -435,16 +435,14 @@ static int ovs_ct_set_labels(struct nf_conn *ct, struct sw_flow_key *key,
}
/* 'skb' should already be pulled to nh_ofs. */
-static int ovs_ct_helper(struct sk_buff *skb, u16 proto)
+static int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo, u16 proto)
{
const struct nf_conntrack_helper *helper;
const struct nf_conn_help *help;
- enum ip_conntrack_info ctinfo;
unsigned int protoff;
- struct nf_conn *ct;
int err;
- ct = nf_ct_get(skb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
return NF_ACCEPT;
@@ -799,7 +797,7 @@ static void ovs_nat_update_key(struct sw_flow_key *key,
/* Modelled after nf_nat_ipv[46]_fn().
* range is only used for new, uninitialized NAT state.
- * Returns either NF_ACCEPT or NF_DROP.
+ * Returns NF_ACCEPT, NF_DROP or NF_STOLEN.
*/
static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
@@ -874,6 +872,9 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
err = nf_nat_packet(ct, ctinfo, hooknum, skb);
push:
+ if ((err & NF_VERDICT_MASK) == NF_STOLEN)
+ return err;
+
skb_push_rcsum(skb, nh_off);
/* Update the flow key if NAT successful. */
@@ -951,6 +952,14 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
}
#endif
+/* Translate netfilter verdicts without evaluating the argument twice. */
+#define verdict_to_errno(verdict) ({ \
+ unsigned int __verdict = (verdict) & NF_VERDICT_MASK; \
+ \
+ __verdict == NF_ACCEPT ? 0 : \
+ __verdict == NF_STOLEN ? -EINPROGRESS : -EINVAL; \
+})
+
/* Pass 'skb' through conntrack in 'net', using zone configured in 'info', if
* not done already. Update key with new CT state after passing the packet
* through conntrack.
@@ -1001,7 +1010,7 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
err = nf_conntrack_in(skb, &state);
if (err != NF_ACCEPT)
- return -ENOENT;
+ return verdict_to_errno(err);
/* Clear CT state NAT flags to mark that we have not yet done
* NAT after the nf_conntrack_in() call. We can actually clear
@@ -1015,8 +1024,6 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
ct = nf_ct_get(skb, &ctinfo);
if (ct) {
- bool add_helper = false;
-
/* Packets starting a new connection must be NATted before the
* helper, so that the helper knows about the NAT. We enforce
* this by delaying both NAT and helper calls for unconfirmed
@@ -1028,9 +1035,12 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
* the key->ct_state.
*/
if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) &&
- (nf_ct_is_confirmed(ct) || info->commit) &&
- ovs_ct_nat(net, key, info, skb, ct, ctinfo) != NF_ACCEPT) {
- return -EINVAL;
+ (nf_ct_is_confirmed(ct) || info->commit)) {
+ int err = ovs_ct_nat(net, key, info, skb, ct, ctinfo);
+
+ err = verdict_to_errno(err);
+ if (err)
+ return err;
}
/* Userspace may decide to perform a ct lookup without a helper
@@ -1045,7 +1055,6 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
GFP_ATOMIC);
if (err)
return err;
- add_helper = true;
/* helper installed, add seqadj if NAT is required */
if (info->nat && !nfct_seqadj(ct)) {
@@ -1055,15 +1064,15 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
}
/* Call the helper only if:
- * - nf_conntrack_in() was executed above ("!cached") or a
- * helper was just attached ("add_helper") for a confirmed
- * connection, or
+ * - nf_conntrack_in() was executed above ("!cached"), or
* - When committing an unconfirmed connection.
*/
- if ((nf_ct_is_confirmed(ct) ? !cached || add_helper :
- info->commit) &&
- ovs_ct_helper(skb, info->family) != NF_ACCEPT) {
- return -EINVAL;
+ if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
+ int err = nf_ct_helper(skb, ct, ctinfo, info->family);
+
+ err = verdict_to_errno(err);
+ if (err)
+ return err;
}
if (nf_ct_protonum(ct) == IPPROTO_TCP &&
@@ -1291,10 +1300,9 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
/* This will take care of sending queued events even if the connection
* is already confirmed.
*/
- if (nf_conntrack_confirm(skb) != NF_ACCEPT)
- return -EINVAL;
+ err = nf_conntrack_confirm(skb);
- return 0;
+ return verdict_to_errno(err);
}
/* Trim the skb to the length specified by the IP/IPv6 header,
@@ -1357,6 +1365,10 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
else
err = ovs_ct_lookup(net, key, info, skb);
+ /* conntrack core returned NF_STOLEN */
+ if (err == -EINPROGRESS)
+ return err;
+
skb_push_rcsum(skb, nh_ofs);
if (err)
kfree_skb(skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0146/1887] net: openvswitch: conntrack: fix helper UAF due to extensions realloc
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0145/1887] openvswitch: prepare for stolen verdict coming from conntrack and nat engine Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0147/1887] smb3: make query_on_disk_id open context consistent and move to common code Greg Kroah-Hartman
` (852 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
Aaron Conole, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <i.maximets@ovn.org>
[ Upstream commit 1a4151e6be57b098b7a5ebfbde58585e83200cdc ]
While calling the helpers, a raw pointer to the extensions area is
wired into expectations list:
-> nf_ct_helper()
-> helper->help()
-> nf_ct_expect_related_report()
-> nf_ct_expect_insert()
-> hlist_add_head_rcu(&exp->lnode, &master_help->expectations)
In case the connection is not confirmed yet, more extensions can be
added afterwards with *_ext_add() calls reallocating the extension
space and leaving the now invalid pointer in the expectations list
that is later accessed while removing the expectation.
Make sure that helpers are called at the end after all the other
extensions are already added.
Note that the helper rejection now leaves the mark and labels set,
but that's not different from how the NAT was handled before or how
the mark and the labels were handled on confirmation failure. And
there are no atomicity guarantees provided by the API anyway.
Fixes: cae3a2627520 ("openvswitch: Allow attaching helpers to ct action")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-4-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/openvswitch/conntrack.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 8c5f6602af44a..9407fdcbb52a7 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -1063,11 +1063,14 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
}
}
- /* Call the helper only if:
- * - nf_conntrack_in() was executed above ("!cached"), or
- * - When committing an unconfirmed connection.
+ /* Call the helper only if nf_conntrack_in() was executed
+ * above ("!cached").
+ *
+ * For unconfirmed connections it will be called later during
+ * commit as we need to have all the other extensions allocated
+ * before the call.
*/
- if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
+ if (nf_ct_is_confirmed(ct) && !cached) {
int err = nf_ct_helper(skb, ct, ctinfo, info->family);
err = verdict_to_errno(err);
@@ -1290,6 +1293,14 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
return err;
nf_conn_act_ct_ext_add(skb, ct, ctinfo);
+
+ /* Call the helpers now. We couldn't do this before as
+ * all the extensions must be allocated before the call.
+ */
+ err = nf_ct_helper(skb, ct, ctinfo, info->family);
+ err = verdict_to_errno(err);
+ if (err)
+ return err;
} else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
labels_nonzero(&info->labels.mask)) {
err = ovs_ct_set_labels(ct, key, &info->labels.value,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0147/1887] smb3: make query_on_disk_id open context consistent and move to common code
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0146/1887] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0148/1887] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
` (851 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulo Alcantara (SUSE), Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <stfrench@microsoft.com>
[ Upstream commit 1149c8467ddebfb6bb9aab37830f70a49cab7085 ]
cifs and ksmbd were using a slightly different version of the query_on_disk_id
struct which could be confusing. Use the ksmbd version of this struct, and
move it to common code.
Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: 67f4c1c6a1b5 ("smb: client: fix create context out-of-bounds reads")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.c | 2 +-
fs/smb/client/smb2pdu.h | 9 ---------
fs/smb/common/smb2pdu.h | 11 +++++++++++
fs/smb/server/smb2pdu.h | 8 --------
4 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index e23060ed57da3..5aa5db211997a 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2179,7 +2179,7 @@ create_reconnect_durable_buf(struct cifs_fid *fid)
static void
parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
{
- struct create_on_disk_id *pdisk_id = (struct create_on_disk_id *)cc;
+ struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
pdisk_id->DiskFileId, pdisk_id->VolumeId);
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index d12ca9c7e62bc..2c2a2177b553c 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -170,15 +170,6 @@ struct durable_reconnect_context_v2 {
__le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
} __packed;
-/* See MS-SMB2 2.2.14.2.9 */
-struct create_on_disk_id {
- struct create_context ccontext;
- __u8 Name[8];
- __le64 DiskFileId;
- __le64 VolumeId;
- __u32 Reserved[4];
-} __packed;
-
/* See MS-SMB2 2.2.14.2.12 */
struct durable_reconnect_context_v2_rsp {
__le32 Timeout;
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 7d69a2a1d3ba4..430b65512228f 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1240,6 +1240,7 @@ struct create_posix {
#define SMB2_LEASE_KEY_SIZE 16
+/* See MS-SMB2 2.2.13.2.8 */
struct lease_context {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
@@ -1247,6 +1248,7 @@ struct lease_context {
__le64 LeaseDuration;
} __packed;
+/* See MS-SMB2 2.2.13.2.10 */
struct lease_context_v2 {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
@@ -1270,6 +1272,15 @@ struct create_lease_v2 {
__u8 Pad[4];
} __packed;
+/* See MS-SMB2 2.2.14.2.9 */
+struct create_disk_id_rsp {
+ struct create_context ccontext;
+ __u8 Name[8];
+ __le64 DiskFileId;
+ __le64 VolumeId;
+ __u8 Reserved[16];
+} __packed;
+
/* See MS-SMB2 2.2.31 and 2.2.32 */
struct smb2_ioctl_req {
struct smb2_hdr hdr;
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 6011fca980456..7518aa42f11ed 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -146,14 +146,6 @@ struct create_mxac_rsp {
__le32 MaximalAccess;
} __packed;
-struct create_disk_id_rsp {
- struct create_context ccontext;
- __u8 Name[8];
- __le64 DiskFileId;
- __le64 VolumeId;
- __u8 Reserved[16];
-} __packed;
-
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
struct create_posix_rsp {
struct create_context ccontext;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0148/1887] smb: client: fix create context out-of-bounds reads
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0147/1887] smb3: make query_on_disk_id open context consistent and move to common code Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0149/1887] PCI: Fix Resizable BAR restore order Greg Kroah-Hartman
` (850 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit 67f4c1c6a1b51e203d986779299824d1c2c590a6 ]
smb2_parse_contexts() validates the complete create-context area but
does not limit each record to its Next field before dispatching it. A
malformed chain can therefore expose bytes beyond the current context to
a handler. The QFid handler also used a full response-structure cast
although it only reads DiskFileId.
The SMB2/SMB3 lease parsers made the same layout assumption: they read
LeaseState and LeaseFlags at canonical offsets rather than at
DataOffset. A valid non-canonical DataOffset could therefore yield
unrelated in-bounds data, while a short DataLength was still accepted.
Limit each context to its Next value, reject offsets before the context
header, and reject malformed chains. Bound the name range by the current
context and do not dispatch a known handler when DataLength is zero. Read
the QFid DiskFileId only when the context data covers that field. Parse the
lease context from DataOffset and require DataLength to match the v1 or v2
lease_context size used by ksmbd. A size mismatch skips lease parsing
without failing the open.
Fixes: b8c32dbb0deb ("CIFS: Request SMB2.1 leases")
Fixes: f047390a097e ("CIFS: Add create lease v2 context for SMB3")
Fixes: 89a5bfa350fa ("smb3: optimize open to not send query file internal info")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 28 ++++++++++++++++++--------
fs/smb/client/smb2pdu.c | 44 +++++++++++++++++++++++++++++++----------
2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 07e003163d66b..973a46daa37b3 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4391,25 +4391,37 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock)
static __u8
smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
- struct create_lease *lc = (struct create_lease *)buf;
+ struct create_context *cc = buf;
+ struct lease_context lc;
*epoch = 0; /* not used */
- if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+ if (le32_to_cpu(cc->DataLength) != sizeof(lc))
+ return 0;
+
+ memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+ if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE;
- return le32_to_cpu(lc->lcontext.LeaseState);
+ return le32_to_cpu(lc.LeaseState);
}
static __u8
smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
- struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
+ struct create_context *cc = buf;
+ struct lease_context_v2 lc;
+
+ if (le32_to_cpu(cc->DataLength) != sizeof(lc)) {
+ *epoch = 0;
+ return 0;
+ }
- *epoch = le16_to_cpu(lc->lcontext.Epoch);
- if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+ memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+ *epoch = le16_to_cpu(lc.Epoch);
+ if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE;
if (lease_key)
- memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
- return le32_to_cpu(lc->lcontext.LeaseState);
+ memcpy(lease_key, lc.LeaseKey, SMB2_LEASE_KEY_SIZE);
+ return le32_to_cpu(lc.LeaseState);
}
static unsigned int
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 5aa5db211997a..d55858a12b18a 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2179,11 +2179,17 @@ create_reconnect_durable_buf(struct cifs_fid *fid)
static void
parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
{
- struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
+ u16 doff = le16_to_cpu(cc->DataOffset);
+ u32 dlen = le32_to_cpu(cc->DataLength);
+ u8 *beg;
+
+ if (dlen < sizeof(__le64))
+ return;
- cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
- pdisk_id->DiskFileId, pdisk_id->VolumeId);
- buf->IndexNumber = pdisk_id->DiskFileId;
+ beg = (u8 *)cc + doff;
+ memcpy(&buf->IndexNumber, beg, sizeof(__le64));
+ cifs_dbg(FYI, "parse query id context 0x%llx\n",
+ le64_to_cpu(buf->IndexNumber));
}
static void
@@ -2234,6 +2240,7 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
struct smb2_create_rsp *rsp = rsp_iov->iov_base;
struct create_context *cc;
size_t rem, off, len;
+ size_t cc_len;
size_t doff, dlen;
size_t noff, nlen;
char *name;
@@ -2256,29 +2263,41 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
buf->IndexNumber = 0;
while (rem >= sizeof(*cc)) {
+ off = le32_to_cpu(cc->Next);
+ if (off) {
+ if ((off & 0x7) || off >= rem || off < sizeof(*cc))
+ return -EINVAL;
+ cc_len = off;
+ } else {
+ cc_len = rem;
+ }
+
doff = le16_to_cpu(cc->DataOffset);
dlen = le32_to_cpu(cc->DataLength);
- if (check_add_overflow(doff, dlen, &len) || len > rem)
+ if (doff < sizeof(*cc) ||
+ check_add_overflow(doff, dlen, &len) || len > cc_len)
return -EINVAL;
noff = le16_to_cpu(cc->NameOffset);
nlen = le16_to_cpu(cc->NameLength);
- if (noff + nlen > doff)
+ if (noff < sizeof(*cc) ||
+ check_add_overflow(noff, nlen, &len) || len > cc_len ||
+ (dlen && len > doff))
return -EINVAL;
name = (char *)cc + noff;
switch (nlen) {
case 4:
- if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
+ if (dlen && !strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
*oplock = server->ops->parse_lease_buf(cc, epoch,
lease_key);
- } else if (buf &&
+ } else if (dlen && buf &&
!strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) {
parse_query_id_ctxt(cc, buf);
}
break;
case 16:
- if (posix && !memcmp(name, smb3_create_tag_posix, 16))
+ if (dlen && posix && !memcmp(name, smb3_create_tag_posix, 16))
parse_posix_ctxt(cc, buf, posix);
break;
default:
@@ -2290,13 +2309,18 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
}
off = le32_to_cpu(cc->Next);
- if (!off)
+ if (!off) {
+ rem = 0;
break;
+ }
if (check_sub_overflow(rem, off, &rem))
return -EINVAL;
cc = (struct create_context *)((u8 *)cc + off);
}
+ if (rem)
+ return -EINVAL;
+
if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
*oplock = rsp->OplockLevel;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0149/1887] PCI: Fix Resizable BAR restore order
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0148/1887] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0150/1887] PCI: Fix BAR resize for devices on a root bus Greg Kroah-Hartman
` (849 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ville Syrjälä,
Ilpo Järvinen, Bjorn Helgaas, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[ Upstream commit 5528fd38f230c906fcebb202cc94fbb8ed8f122a ]
The commit 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback
path") changed BAR resize to layer rebar code and resource setup/restore
code cleanly. Unfortunately, it did not consider how the value of the BAR
Size field impacts the read-only bits in the Base Address Register (PCIe7
spec, sec. 7.8.6.3). That is, it very much matters in which order the BAR
Size and Base Address Register are restored.
Post-337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
during BAR resize rollback, pci_do_resource_release_and_resize() attempts
to restore the old address to the BAR that was resized, but it can fail to
setup the address correctly if the address has low bits set that collide
with the bits that are still read-only. As a result, kernel's resource and
BAR will be out-of-sync.
Fix this by restoring BAR Size before rolling back the resource changes and
restoring the BAR.
Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/linux-pci/aW_w1oFQCzUxGYtu@intel.com/
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260121131417.9582-3-ilpo.jarvinen@linux.intel.com
[6.12 dependency preparation for d58384c22739848efe14b34e9586e4f1242f33c0:
Keep the existing memory-decoding and supported-size checks in rebar.c.
Move BAR size programming and rollback into the resource release helper,
so the old size is restored before restoring BAR addresses.
Use the assigned parent window to select resources for release, retaining
the old flags-based selection when the resized BAR has no parent. Provide
file-local macro mappings for the follow-up's bridge reassignment and
resource assignment checks; no functions are added.
Retain the upstream pre-target pci_bus_sem placement to allow the target
to apply without conflicts. This preparatory dependency must be applied
together with d58384c22739848efe14b34e9586e4f1242f33c0, which takes the lock
before releasing resources and assigns released BARs on root buses.]
Stable-dep-of: d58384c22739 ("PCI: Fix BAR resize for devices on a root bus")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/rebar.c | 19 +------------------
drivers/pci/setup-bus.c | 39 ++++++++++++++++++++++++++++++++-------
2 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/drivers/pci/rebar.c b/drivers/pci/rebar.c
index 920ef3ab4bda3..d5e432d084e51 100644
--- a/drivers/pci/rebar.c
+++ b/drivers/pci/rebar.c
@@ -177,7 +177,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
int exclude_bars)
{
struct pci_host_bridge *host;
- int old, ret;
u32 sizes;
u16 cmd;
@@ -197,22 +196,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size,
if (!(sizes & BIT(size)))
return -EINVAL;
- old = pci_rebar_get_current_size(dev, resno);
- if (old < 0)
- return old;
-
- ret = pci_rebar_set_size(dev, resno, size);
- if (ret)
- return ret;
-
- ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
- if (ret)
- goto error_resize;
-
- return 0;
-
-error_resize:
- pci_rebar_set_size(dev, resno, old);
- return ret;
+ return pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
}
EXPORT_SYMBOL(pci_resize_resource);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index df345ebbb991f..73427c09f983a 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2294,6 +2294,11 @@ static int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long t
return 0;
}
+/* Keep the resize follow-up compatible with the 6.12 resource helpers. */
+#define pbus_reassign_bridge_resources(bus, res, saved) \
+ pci_reassign_bridge_resources((bus)->self, (res)->flags, (saved))
+#define resource_assigned(res) ((res)->parent != NULL)
+
int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size,
int exclude_bars)
{
@@ -2301,12 +2306,20 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
unsigned long flags = res->flags;
struct pci_dev_resource *dev_res;
struct pci_bus *bus = pdev->bus;
- struct resource *r;
+ struct resource *b_win, *r;
LIST_HEAD(saved);
unsigned int i;
- int ret = 0;
+ int old, ret;
- down_read(&pci_bus_sem);
+ b_win = res->parent;
+
+ old = pci_rebar_get_current_size(pdev, resno);
+ if (old < 0)
+ return old;
+
+ ret = pci_rebar_set_size(pdev, resno, size);
+ if (ret)
+ return ret;
pci_dev_for_each_resource(pdev, r, i) {
if (i >= PCI_BRIDGE_RESOURCES)
@@ -2315,7 +2328,10 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
if (exclude_bars & BIT(i))
continue;
- if (!pci_resource_len(pdev, i) || r->flags != flags)
+ if (!pci_resource_len(pdev, i))
+ continue;
+
+ if (b_win ? r->parent != b_win : r->flags != flags)
continue;
ret = add_to_list(&saved, pdev, r, 0, 0);
@@ -2329,7 +2345,8 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
if (!bus->self)
goto out;
- ret = pci_reassign_bridge_resources(bus->self, res->flags, &saved);
+ down_read(&pci_bus_sem);
+ ret = pbus_reassign_bridge_resources(bus, res, &saved);
if (ret)
goto restore;
@@ -2339,14 +2356,22 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
return ret;
restore:
- /* Revert to the old configuration */
+ /*
+ * Revert to the old configuration.
+ *
+ * BAR Size must be restored first because it affects the read-only
+ * bits in BAR (the old address might not be restorable otherwise
+ * due to low address bits).
+ */
+ pci_rebar_set_size(pdev, resno, old);
+
list_for_each_entry(dev_res, &saved, list) {
struct resource *res = dev_res->res;
struct pci_dev *dev = dev_res->dev;
i = res - dev->resource;
- if (res->parent) {
+ if (resource_assigned(res)) {
release_child_resources(res);
pci_release_resource(dev, i);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0150/1887] PCI: Fix BAR resize for devices on a root bus
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0149/1887] PCI: Fix Resizable BAR restore order Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0151/1887] net: ipconfig: Remove outdated comment and indent code block Greg Kroah-Hartman
` (848 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ilpo Järvinen, Liz Fong-Jones,
Bjorn Helgaas, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liz Fong-Jones <lizf@honeycomb.io>
[ Upstream commit d58384c22739848efe14b34e9586e4f1242f33c0 ]
pci_do_resource_release_and_resize() releases device BARs that share a
bridge window with the BAR being resized, but when the device sits directly
on a root bus (pdev->bus->self == NULL) it then skips resource assignment
entirely and returns success, leaving the BARs it just released unassigned
(IORESOURCE_UNSET).
Skipping pbus_reassign_bridge_resources() is correct in that case -- there
is no bridge window to adjust -- but the device BARs still have to be
reassigned. Before the BAR release was consolidated into the PCI core, this
case worked for amdgpu because the driver released the BARs itself and then
called pci_assign_unassigned_bus_resources() unconditionally after the
resize, which assigns unassigned device BARs also on a root bus. Commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call, so nothing assigns the released BARs anymore.
This breaks amdgpu completely on the SolidRun HoneyComb LX2K (NXP LX2160A,
arm64, ACPI), where ACPI doesn't expose the Root Port so the GPU endpoint
appears directly on a "root bus" of its segment:
amdgpu 0004:01:00.0: BAR 0 [mem 0xa400000000-0xa40fffffff 64bit pref]: releasing
amdgpu 0004:01:00.0: BAR 2 [mem 0xa410000000-0xa4101fffff 64bit pref]: releasing
amdgpu 0004:01:00.0: sw_init of IP block <gmc_v8_0> failed -19
amdgpu 0004:01:00.0: amdgpu_device_ip_init failed
amdgpu 0004:01:00.0: Fatal error during GPU init
No error is logged because the resize path reports success; amdgpu then
finds BAR 0 IORESOURCE_UNSET and bails out with -ENODEV.
When there is no upstream bridge, call pci_bus_assign_resources() on the
root bus to place the BARs released above, using the same alignment-sorted
algorithm as normal enumeration instead of a manual per-BAR loop. This also
walks the rest of the hierarchy under the root bus, as
pci_assign_unassigned_bus_resources() used to for amdgpu before commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call -- the core-side fix that commit asked for ("such a
problem should be fixed inside pci_resize_resource() instead").
pci_bus_assign_resources() returns void, so failure is detected by checking
whether the released BARs are still assigned afterward; if not, roll back
as in the bridged case. This is stricter than the bridged path -- it fails
on any unplaced resource, not just required ones -- since a root bus
typically has one shared window, and failing loudly seemed better than
leaving something silently unassigned.
The root bus path also had a locking bug that any fix here necessarily
touches: the old "goto out" jumped to up_read(&pci_bus_sem) without a
matching down_read() (as does the "goto restore" taken when
pci_dev_res_add_to_list() fails in the release loop). Take pci_bus_sem
before the BAR release loop so every path through the function holds it
exactly once.
Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
Link: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-7.0/+bug/2159596
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Assisted-by: Claude:claude-fable-5 checkpatch
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260918035633.566823-1-lizf@honeycomb.io
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/setup-bus.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 73427c09f983a..cd09f1e26b8a2 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2306,6 +2306,7 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
unsigned long flags = res->flags;
struct pci_dev_resource *dev_res;
struct pci_bus *bus = pdev->bus;
+ struct pci_dev *bridge = pci_upstream_bridge(pdev);
struct resource *b_win, *r;
LIST_HEAD(saved);
unsigned int i;
@@ -2321,6 +2322,8 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
if (ret)
return ret;
+ down_read(&pci_bus_sem);
+
pci_dev_for_each_resource(pdev, r, i) {
if (i >= PCI_BRIDGE_RESOURCES)
break;
@@ -2342,13 +2345,21 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
- if (!bus->self)
- goto out;
+ if (bridge) {
+ ret = pbus_reassign_bridge_resources(bus, res, &saved);
+ if (ret)
+ goto restore;
+ } else {
+ /* No bridge window to adjust; let the core reassign the bus. */
+ pci_bus_assign_resources(bus);
- down_read(&pci_bus_sem);
- ret = pbus_reassign_bridge_resources(bus, res, &saved);
- if (ret)
- goto restore;
+ list_for_each_entry(dev_res, &saved, list) {
+ if (!resource_assigned(dev_res->res)) {
+ ret = -ENOSPC;
+ goto restore;
+ }
+ }
+ }
out:
up_read(&pci_bus_sem);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0151/1887] net: ipconfig: Remove outdated comment and indent code block
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0150/1887] PCI: Fix BAR resize for devices on a root bus Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0152/1887] net: ipconfig: bound DHCP option construction Greg Kroah-Hartman
` (847 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit e405b3c9d4aaa10972525fe2ea5cf94224020561 ]
The comment has been around ever since commit 1da177e4c3f4
("Linux-2.6.12-rc2") and can be removed. Remove it and indent the code
block accordingly.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260109121128.170020-2-thorsten.blum@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: e47a1958e12a ("net: ipconfig: bound DHCP option construction")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipconfig.c | 89 +++++++++++++++++++++------------------------
1 file changed, 42 insertions(+), 47 deletions(-)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index e90bc0aa85c77..a7f5182c97fba 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -676,8 +676,18 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
static void __init
ic_dhcp_init_options(u8 *options, struct ic_device *d)
{
- u8 mt = ((ic_servaddr == NONE)
- ? DHCPDISCOVER : DHCPREQUEST);
+ static const u8 ic_req_params[] = {
+ 1, /* Subnet mask */
+ 3, /* Default gateway */
+ 6, /* DNS server */
+ 12, /* Host name */
+ 15, /* Domain name */
+ 17, /* Boot path */
+ 26, /* MTU */
+ 40, /* NIS domain name */
+ 42, /* NTP servers */
+ };
+ u8 mt = (ic_servaddr == NONE) ? DHCPDISCOVER : DHCPREQUEST;
u8 *e = options;
int len;
@@ -702,51 +712,36 @@ ic_dhcp_init_options(u8 *options, struct ic_device *d)
e += 4;
}
- /* always? */
- {
- static const u8 ic_req_params[] = {
- 1, /* Subnet mask */
- 3, /* Default gateway */
- 6, /* DNS server */
- 12, /* Host name */
- 15, /* Domain name */
- 17, /* Boot path */
- 26, /* MTU */
- 40, /* NIS domain name */
- 42, /* NTP servers */
- };
-
- *e++ = 55; /* Parameter request list */
- *e++ = sizeof(ic_req_params);
- memcpy(e, ic_req_params, sizeof(ic_req_params));
- e += sizeof(ic_req_params);
-
- if (ic_host_name_set) {
- *e++ = 12; /* host-name */
- len = strlen(utsname()->nodename);
- *e++ = len;
- memcpy(e, utsname()->nodename, len);
- e += len;
- }
- if (*vendor_class_identifier) {
- pr_info("DHCP: sending class identifier \"%s\"\n",
- vendor_class_identifier);
- *e++ = 60; /* Class-identifier */
- len = strlen(vendor_class_identifier);
- *e++ = len;
- memcpy(e, vendor_class_identifier, len);
- e += len;
- }
- len = strlen(dhcp_client_identifier + 1);
- /* the minimum length of identifier is 2, include 1 byte type,
- * and can not be larger than the length of options
- */
- if (len >= 1 && len < 312 - (e - options) - 1) {
- *e++ = 61;
- *e++ = len + 1;
- memcpy(e, dhcp_client_identifier, len + 1);
- e += len + 1;
- }
+ *e++ = 55; /* Parameter request list */
+ *e++ = sizeof(ic_req_params);
+ memcpy(e, ic_req_params, sizeof(ic_req_params));
+ e += sizeof(ic_req_params);
+
+ if (ic_host_name_set) {
+ *e++ = 12; /* host-name */
+ len = strlen(utsname()->nodename);
+ *e++ = len;
+ memcpy(e, utsname()->nodename, len);
+ e += len;
+ }
+ if (*vendor_class_identifier) {
+ pr_info("DHCP: sending class identifier \"%s\"\n",
+ vendor_class_identifier);
+ *e++ = 60; /* Class-identifier */
+ len = strlen(vendor_class_identifier);
+ *e++ = len;
+ memcpy(e, vendor_class_identifier, len);
+ e += len;
+ }
+ len = strlen(dhcp_client_identifier + 1);
+ /* the minimum length of identifier is 2, include 1 byte type,
+ * and can not be larger than the length of options
+ */
+ if (len >= 1 && len < 312 - (e - options) - 1) {
+ *e++ = 61;
+ *e++ = len + 1;
+ memcpy(e, dhcp_client_identifier, len + 1);
+ e += len + 1;
}
*e++ = 255; /* End of the list */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0152/1887] net: ipconfig: bound DHCP option construction
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0151/1887] net: ipconfig: Remove outdated comment and indent code block Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0153/1887] net: ena: Remove autopolling mode Greg Kroah-Hartman
` (846 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei, Simon Horman,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
[ Upstream commit e47a1958e12abc3a17b5231a4f21c8f1bf662e08 ]
ic_dhcp_init_options() appends the hostname (option 12), vendor-class
(option 60) and client-ID (option 61) options into the fixed 312-byte
bootp_pkt.exten[] buffer. Only the client-ID branch checked the
remaining space; the hostname and vendor-class writes were unbounded.
A 64-byte hostname together with the maximum 252-byte dhcpclass=
identifier needs 18 + (2 + 64) + (2 + 252) = 338 of the 312 available
bytes even before the terminating END marker, so the vendor-class memcpy
runs past the end of exten[]. With CONFIG_FORTIFY_SOURCE this is
reported as a field-spanning write and, when the kernel is booted with
panic_on_warn=1, aborts boot with a panic.
Route the optional options through a common helper that makes sure the
option, its 2-byte header and the END marker all fit and drops an option
that would not. Configurations with short options keep sending exactly
the same bytes as before.
Fixes: 130c0f47fdf9 ("ipconfig: send host-name in DHCP requests")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/7808dfbfa2162dfd0b19f59aff5742d6e0db2abb.1789798023.git.xuyuqiabc@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipconfig.c | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index a7f5182c97fba..024c54a5b0e13 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -673,6 +673,24 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
#ifdef IPCONFIG_DHCP
+static bool __init
+ic_dhcp_add_option(u8 **options, const u8 *end, u8 type, const void *value,
+ int len)
+{
+ u8 *e = *options;
+
+ /* leave room for the option header and the END marker */
+ if (len > U8_MAX || end - e < len + 3)
+ return false;
+
+ *e++ = type;
+ *e++ = len;
+ memcpy(e, value, len);
+ *options = e + len;
+
+ return true;
+}
+
static void __init
ic_dhcp_init_options(u8 *options, struct ic_device *d)
{
@@ -688,6 +706,7 @@ ic_dhcp_init_options(u8 *options, struct ic_device *d)
42, /* NTP servers */
};
u8 mt = (ic_servaddr == NONE) ? DHCPDISCOVER : DHCPREQUEST;
+ u8 *end = options + sizeof(((struct bootp_pkt *)0)->exten);
u8 *e = options;
int len;
@@ -718,31 +737,19 @@ ic_dhcp_init_options(u8 *options, struct ic_device *d)
e += sizeof(ic_req_params);
if (ic_host_name_set) {
- *e++ = 12; /* host-name */
len = strlen(utsname()->nodename);
- *e++ = len;
- memcpy(e, utsname()->nodename, len);
- e += len;
+ ic_dhcp_add_option(&e, end, 12, utsname()->nodename, len);
}
if (*vendor_class_identifier) {
- pr_info("DHCP: sending class identifier \"%s\"\n",
- vendor_class_identifier);
- *e++ = 60; /* Class-identifier */
len = strlen(vendor_class_identifier);
- *e++ = len;
- memcpy(e, vendor_class_identifier, len);
- e += len;
+ if (ic_dhcp_add_option(&e, end, 60, vendor_class_identifier, len))
+ pr_info("DHCP: sending class identifier \"%s\"\n",
+ vendor_class_identifier);
}
len = strlen(dhcp_client_identifier + 1);
- /* the minimum length of identifier is 2, include 1 byte type,
- * and can not be larger than the length of options
- */
- if (len >= 1 && len < 312 - (e - options) - 1) {
- *e++ = 61;
- *e++ = len + 1;
- memcpy(e, dhcp_client_identifier, len + 1);
- e += len + 1;
- }
+ /* the minimum length of identifier is 2, include 1 byte type */
+ if (len >= 1)
+ ic_dhcp_add_option(&e, end, 61, dhcp_client_identifier, len + 1);
*e++ = 255; /* End of the list */
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0153/1887] net: ena: Remove autopolling mode
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0152/1887] net: ipconfig: bound DHCP option construction Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0154/1887] net: ena: fix MMIO read buffer leak on probe failure Greg Kroah-Hartman
` (845 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Arinzon,
Dr. David Alan Gilbert, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dr. David Alan Gilbert <linux@treblig.org>
[ Upstream commit b356b9170815f822394667010d478d53901ff581 ]
This manually reverts
commit a4e262cde3cd ("net: ena: allow automatic fallback to polling mode")
which is unused.
(I did it manually because there are other minor comment
and function changes surrounding it).
Build tested only.
Suggested-by: David Arinzon <darinzon@amazon.com>
Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
Link: https://patch.msgid.link/20241103194149.293456-1-linux@treblig.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 9476b4468862 ("net: ena: fix MMIO read buffer leak on probe failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amazon/ena/ena_com.c | 25 +++++------------------
drivers/net/ethernet/amazon/ena/ena_com.h | 14 -------------
2 files changed, 5 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
index 276f6a8631fb1..a7b98c0b5f285 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -763,25 +763,16 @@ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *com
if (comp_ctx->status == ENA_CMD_COMPLETED) {
netdev_err(admin_queue->ena_dev->net_device,
- "The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d), autopolling mode is %s\n",
- comp_ctx->cmd_opcode, admin_queue->auto_polling ? "ON" : "OFF");
- /* Check if fallback to polling is enabled */
- if (admin_queue->auto_polling)
- admin_queue->polling = true;
+ "The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d)\n",
+ comp_ctx->cmd_opcode);
} else {
netdev_err(admin_queue->ena_dev->net_device,
"The ena device didn't send a completion for the admin cmd %d status %d\n",
comp_ctx->cmd_opcode, comp_ctx->status);
}
- /* Check if shifted to polling mode.
- * This will happen if there is a completion without an interrupt
- * and autopolling mode is enabled. Continuing normal execution in such case
- */
- if (!admin_queue->polling) {
- admin_queue->running_state = false;
- ret = -ETIME;
- goto err;
- }
+ admin_queue->running_state = false;
+ ret = -ETIME;
+ goto err;
}
ret = ena_com_comp_status_to_errno(admin_queue, comp_ctx->comp_status);
@@ -1658,12 +1649,6 @@ void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling)
ena_dev->admin_queue.polling = polling;
}
-void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
- bool polling)
-{
- ena_dev->admin_queue.auto_polling = polling;
-}
-
int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev)
{
struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h
index 3c5081d9d25d6..bb33fe209eec0 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -227,9 +227,6 @@ struct ena_com_admin_queue {
/* Indicate if the admin queue should poll for completion */
bool polling;
- /* Define if fallback to polling mode should occur */
- bool auto_polling;
-
u16 curr_cmd_id;
/* Indicate that the ena was initialized and can
@@ -484,17 +481,6 @@ bool ena_com_get_admin_running_state(struct ena_com_dev *ena_dev);
*/
void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling);
-/* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode
- * @ena_dev: ENA communication layer struct
- * @polling: Enable/Disable polling mode
- *
- * Set the autopolling mode.
- * If autopolling is on:
- * In case of missing interrupt when data is available switch to polling.
- */
-void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
- bool polling);
-
/* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler
* @ena_dev: ENA communication layer struct
*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0154/1887] net: ena: fix MMIO read buffer leak on probe failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0153/1887] net: ena: Remove autopolling mode Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0155/1887] netfilter: nf_tables: set->ops->insert returns opaque set element in case of EEXIST Greg Kroah-Hartman
` (844 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
[ Upstream commit 9476b4468862927297c94c440863cd8ed1e7cc83 ]
ena_device_init() initializes the MMIO read mechanism with
ena_com_mmio_reg_read_request_init(), which allocates a coherent DMA
buffer for MMIO read responses.
The normal removal path releases this buffer through
ena_com_mmio_reg_read_request_destroy(). However, if ena_probe() fails
after ena_device_init() succeeds, the error path destroys the admin
resources and eventually frees ena_dev without destroying the MMIO read
request, leaving the coherent DMA buffer allocated.
Call ena_com_mmio_reg_read_request_destroy() in the probe error path
before releasing the remaining device resources.
This issue was found by manual code inspection.
Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260921154202.471662-3-lgs201920130244@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Adjusted cleanup context due to missing PHC, devlink, and customer-metrics code. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 5159fb9fbe66f..9e92ccf13419f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -4497,6 +4497,7 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_device_destroy:
ena_com_delete_host_info(ena_dev);
ena_com_admin_destroy(ena_dev);
+ ena_com_mmio_reg_read_request_destroy(ena_dev);
err_netdev_destroy:
free_netdev(netdev);
err_free_region:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0155/1887] netfilter: nf_tables: set->ops->insert returns opaque set element in case of EEXIST
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0154/1887] net: ena: fix MMIO read buffer leak on probe failure Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0156/1887] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
` (843 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit 078996fcd657e6e0c3a72b7d5806d04c32e74250 ]
Return struct nft_elem_priv instead of struct nft_set_ext for
consistency with ("netfilter: nf_tables: expose opaque set element as
struct nft_elem_priv") and to prepare the introduction of element
timeout updates from control path.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Backport notes for Linux 6.1:
Keep the existing void-pointer representation of opaque set elements.
The typed nft_elem_priv API and embedded priv members are not present in
this branch, so return backend element pointers through void ** and derive
the extension with nft_set_elem_ext() in the EEXIST handling path.
Preserve the stable set_full accounting and PIPAPO's early initialization
of e, and omit the unrelated timeout declaration reorder. No functions or
new element representations are introduced. This prepares the catchall
insert context for 70194dc37670 ("netfilter: nf_tables: skip expired
catchall elements on insert and delete"); its timestamp and expiration
helpers already exist in this branch.
Stable-dep-of: 70194dc37670 ("netfilter: nf_tables: skip expired catchall elements on insert and delete")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netfilter/nf_tables.h | 2 +-
net/netfilter/nf_tables_api.c | 15 +++++++++------
net/netfilter/nft_set_bitmap.c | 4 ++--
net/netfilter/nft_set_hash.c | 8 ++++----
net/netfilter/nft_set_pipapo.c | 10 +++++-----
net/netfilter/nft_set_rbtree.c | 10 +++++-----
6 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 7e63281f2d5a8..b8f283a6e718f 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -454,7 +454,7 @@ struct nft_set_ops {
int (*insert)(const struct net *net,
const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext);
+ void **priv);
void (*activate)(const struct net *net,
const struct nft_set *set,
const struct nft_set_elem *elem);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a373a0969e994..17092456431db 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6218,7 +6218,7 @@ EXPORT_SYMBOL_GPL(nft_set_catchall_lookup);
static int nft_setelem_catchall_insert(const struct net *net,
struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **pext)
+ void **priv)
{
struct nft_set_elem_catchall *catchall;
u8 genmask = nft_genmask_next(net);
@@ -6227,7 +6227,7 @@ static int nft_setelem_catchall_insert(const struct net *net,
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
if (nft_set_elem_active(ext, genmask)) {
- *pext = ext;
+ *priv = catchall->elem;
return -EEXIST;
}
}
@@ -6245,14 +6245,15 @@ static int nft_setelem_catchall_insert(const struct net *net,
static int nft_setelem_insert(const struct net *net,
struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext, unsigned int flags)
+ void **elem_priv,
+ unsigned int flags)
{
int ret;
if (flags & NFT_SET_ELEM_CATCHALL)
- ret = nft_setelem_catchall_insert(net, set, elem, ext);
+ ret = nft_setelem_catchall_insert(net, set, elem, elem_priv);
else
- ret = set->ops->insert(net, set, elem, ext);
+ ret = set->ops->insert(net, set, elem, elem_priv);
return ret;
}
@@ -6420,6 +6421,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
enum nft_registers dreg;
struct nft_trans *trans;
bool set_full = false;
+ void *elem_priv;
u64 timeout;
u64 expiration;
int err, i;
@@ -6728,9 +6730,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
ext->genmask = nft_genmask_cur(ctx->net);
- err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags);
+ err = nft_setelem_insert(ctx->net, set, &elem, &elem_priv, flags);
if (err) {
if (err == -EEXIST) {
+ ext2 = nft_set_elem_ext(set, elem_priv);
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
diff --git a/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
index cbf7f7825f1b8..06b77100bef71 100644
--- a/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -123,7 +123,7 @@ static void *nft_bitmap_get(const struct net *net, const struct nft_set *set,
static int nft_bitmap_insert(const struct net *net, const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext)
+ void **elem_priv)
{
struct nft_bitmap *priv = nft_set_priv(set);
struct nft_bitmap_elem *new = elem->priv, *be;
@@ -132,7 +132,7 @@ static int nft_bitmap_insert(const struct net *net, const struct nft_set *set,
be = nft_bitmap_elem_find(set, new, genmask);
if (be) {
- *ext = &be->ext;
+ *elem_priv = be;
return -EEXIST;
}
diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
index 5a74ee4b7dfb3..60c0d72fb98b1 100644
--- a/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -168,7 +168,7 @@ static bool nft_rhash_update(struct nft_set *set, const u32 *key,
static int nft_rhash_insert(const struct net *net, const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext)
+ void **elem_priv)
{
struct nft_rhash *priv = nft_set_priv(set);
struct nft_rhash_elem *he = elem->priv;
@@ -185,7 +185,7 @@ static int nft_rhash_insert(const struct net *net, const struct nft_set *set,
if (IS_ERR(prev))
return PTR_ERR(prev);
if (prev) {
- *ext = &prev->ext;
+ *elem_priv = prev;
return -EEXIST;
}
return 0;
@@ -588,7 +588,7 @@ static u32 nft_jhash(const struct nft_set *set, const struct nft_hash *priv,
static int nft_hash_insert(const struct net *net, const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext)
+ void **elem_priv)
{
struct nft_hash_elem *this = elem->priv, *he;
struct nft_hash *priv = nft_set_priv(set);
@@ -600,7 +600,7 @@ static int nft_hash_insert(const struct net *net, const struct nft_set *set,
if (!memcmp(nft_set_ext_key(&this->ext),
nft_set_ext_key(&he->ext), set->klen) &&
nft_set_elem_active(&he->ext, genmask)) {
- *ext = &he->ext;
+ *elem_priv = he;
return -EEXIST;
}
}
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index 4b37c6684bff6..c27ba1c5ae5da 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -1260,13 +1260,13 @@ static struct nft_pipapo_match *pipapo_maybe_clone(const struct nft_set *set)
* @net: Network namespace
* @set: nftables API set representation
* @elem: nftables API element representation containing key data
- * @ext2: Filled with pointer to &struct nft_set_ext in inserted element
+ * @elem_priv: Filled with pointer to opaque set element
*
* Return: 0 on success, error pointer on failure.
*/
static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext2)
+ void **elem_priv)
{
const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
@@ -1301,7 +1301,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
if (!memcmp(start, dup_key->data, sizeof(*dup_key->data)) &&
!memcmp(end, dup_end->data, sizeof(*dup_end->data))) {
- *ext2 = &dup->ext;
+ *elem_priv = dup;
return -EEXIST;
}
@@ -1317,7 +1317,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
if (PTR_ERR(dup) != -ENOENT) {
if (IS_ERR(dup))
return PTR_ERR(dup);
- *ext2 = &dup->ext;
+ *elem_priv = dup;
return -ENOTEMPTY;
}
@@ -1379,7 +1379,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
put_cpu_ptr(m->scratch);
}
- *ext2 = &e->ext;
+ *elem_priv = e;
pipapo_map(m, rulemap, e);
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 433094c4200f9..e82e5cf107ee4 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -319,7 +319,7 @@ static struct nft_rbtree_elem *nft_rbtree_prev_active(struct nft_rbtree_elem *rb
static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
struct nft_rbtree_elem *new,
- struct nft_set_ext **ext)
+ void **elem_priv)
{
struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL, *rbe_prev;
struct rb_node *node, *next, *parent, **p, *first = NULL;
@@ -437,7 +437,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
*/
if (rbe_ge && !nft_rbtree_cmp(set, new, rbe_ge) &&
nft_rbtree_interval_start(rbe_ge) == nft_rbtree_interval_start(new)) {
- *ext = &rbe_ge->ext;
+ *elem_priv = rbe_ge;
return -EEXIST;
}
@@ -446,7 +446,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
*/
if (rbe_le && !nft_rbtree_cmp(set, new, rbe_le) &&
nft_rbtree_interval_end(rbe_le) == nft_rbtree_interval_end(new)) {
- *ext = &rbe_le->ext;
+ *elem_priv = rbe_le;
return -EEXIST;
}
@@ -506,7 +506,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
static int nft_rbtree_insert(const struct net *net, const struct nft_set *set,
const struct nft_set_elem *elem,
- struct nft_set_ext **ext)
+ void **elem_priv)
{
struct nft_rbtree *priv = nft_set_priv(set);
struct nft_rbtree_elem *rbe = elem->priv;
@@ -520,7 +520,7 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set,
write_lock_bh(&priv->lock);
write_seqcount_begin(&priv->count);
- err = __nft_rbtree_insert(net, set, rbe, ext);
+ err = __nft_rbtree_insert(net, set, rbe, elem_priv);
write_seqcount_end(&priv->count);
write_unlock_bh(&priv->lock);
} while (err == -EAGAIN);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0156/1887] netfilter: nf_tables: skip expired catchall elements on insert and delete
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0155/1887] netfilter: nf_tables: set->ops->insert returns opaque set element in case of EEXIST Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0157/1887] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL Greg Kroah-Hartman
` (842 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Aohan Mei,
Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
[ Upstream commit 70194dc37670bd08e44b471389861cc01bd3a3c9 ]
nft_setelem_catchall_insert() looks up duplicates with
nft_set_elem_active() only, while nft_set_catchall_lookup() and the
dump path additionally skip expired elements.
Once a catchall element with a timeout expires, this predicate drift
makes it invisible to userspace dumps, yet it still blocks
re-insertion: with NLM_F_EXCL the request fails with -EEXIST, and
without it the request reports success but silently inserts nothing.
The stale entry only goes away when the (user-tunable) gc interval
elapses, so the catchall rule may silently stop matching for an
arbitrarily long time after its first expiration.
The delete path shows the same drift: nft_setelem_catchall_deactivate()
picks the first active-next entry in the catchall list, so with an
expired entry still pending GC it retires the stale entry instead of
the fresh one, and it deactivates an element that userspace no longer
sees instead of failing with -ENOENT.
Align both walks with the lookup and dump predicates: only an element
that is active and not expired counts as a duplicate or delete
candidate, using the per-netns timestamp taken at transaction start,
in line with the set backend .insert/.deactivate and catchall GC sync
paths.
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Fixes: aaa31047a6d2 ("netfilter: nftables: add catch-all set element support")
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_tables_api.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 17092456431db..9f71ad2669c7e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6222,11 +6222,14 @@ static int nft_setelem_catchall_insert(const struct net *net,
{
struct nft_set_elem_catchall *catchall;
u8 genmask = nft_genmask_next(net);
+ u64 tstamp = nft_net_tstamp(net);
struct nft_set_ext *ext;
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
- if (nft_set_elem_active(ext, genmask)) {
+ if (nft_set_elem_active(ext, genmask) &&
+ !__nft_set_elem_expired(ext, tstamp) &&
+ !nft_set_elem_is_dead(ext)) {
*priv = catchall->elem;
return -EEXIST;
}
@@ -6287,11 +6290,14 @@ static int nft_setelem_catchall_deactivate(const struct net *net,
struct nft_set_elem *elem)
{
struct nft_set_elem_catchall *catchall;
+ u64 tstamp = nft_net_tstamp(net);
struct nft_set_ext *ext;
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
- if (!nft_is_active_next(net, ext))
+ if (!nft_is_active_next(net, ext) ||
+ __nft_set_elem_expired(ext, tstamp) ||
+ nft_set_elem_is_dead(ext))
continue;
kfree(elem->priv);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0157/1887] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0156/1887] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0158/1887] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification Greg Kroah-Hartman
` (841 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
[ Upstream commit 4ef863352bcde482d65722ed721c3fd3967a67d6 ]
Update perf hard-coded event constraints and cache_extra_regs[] for
Alderlake according to the latest ADL perfmon events (V1.39).
One important note is that ADL has differences on the L3/node related
OCR events although it shares same uarch with SPR server, e.g.,
ADL has different extra MSR values and no node events. So some variants
of structures and functions are introduced to reflect these
differences, like adl_glc_hw_cache_event_ids[],
adl_glc_hw_cache_extra_regs[] and intel_pmu_init_glc_hybrid(), etc.
Please note these changes would temporarily impact other platforms like
MTL/ARL-U which shares hard-coded event structures, but it would be
fixed soon in subsequent patches.
ADL perfmon events:
https://github.com/intel/perfmon/blob/main/ADL/events/alderlake_goldencove_core.json
https://github.com/intel/perfmon/blob/main/ADL/events/alderlake_gracemont_core.json
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260515061143.338553-5-dapeng1.mi@linux.intel.com
[Backport preparation for 89dc568e8c0b on Linux 6.1:
Retain the Gracemont STORE_LATENCY counter-mask update to 0x3f.
Drop the upstream cache/extra-register and fixed-counter changes: they
depend on newer PMU initialization infrastructure and are not needed
by the target's PEBS sample-classification fix.
Prepare the target's existing-function context without adding functions.
Rename and adapt adl_latency_data_small() as __grt_latency_data(), with
its record fields supplied by the caller. Rename load_latency_data()
as grt_latency_data() and reuse it for Gracemont dispatch as well as
its existing non-Gracemont load-latency path. Preserve the original
TLB/lock/block decoding and update the callback and prototype names.
Guard the hybrid-only assertion for non-hybrid Gracemont systems.
Provide the upstream INTEL_HYBRID_LDLAT/STLAT_CONSTRAINT macros so the
unmodified target can set direction flags while retaining hybrid
latency decoding. The target itself remains a separate backport.]
Stable-dep-of: 89dc568e8c0b ("perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 4 ++--
arch/x86/events/intel/ds.c | 34 ++++++++++++++++++----------------
arch/x86/events/perf_event.h | 10 +++++++++-
3 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 4615a21b9e852..6f5805ad723bf 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -6195,7 +6195,7 @@ __init int intel_pmu_init(void)
x86_pmu.flags |= PMU_FL_INSTR_LATENCY;
intel_pmu_pebs_data_source_grt();
- x86_pmu.pebs_latency_data = adl_latency_data_small;
+ x86_pmu.pebs_latency_data = grt_latency_data;
x86_pmu.get_event_constraints = tnt_get_event_constraints;
x86_pmu.limit_period = spr_limit_period;
td_attr = tnt_events_attrs;
@@ -6578,7 +6578,7 @@ __init int intel_pmu_init(void)
x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX;
x86_pmu.lbr_pt_coexist = true;
intel_pmu_pebs_data_source_adl();
- x86_pmu.pebs_latency_data = adl_latency_data_small;
+ x86_pmu.pebs_latency_data = grt_latency_data;
x86_pmu.num_topdown_events = 8;
static_call_update(intel_pmu_update_topdown_event,
&adl_update_topdown_event);
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 4b7faa3180e57..d1cf9876c931d 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -221,24 +221,19 @@ static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock)
}
/* Retrieve the latency data for e-core of ADL */
-u64 adl_latency_data_small(struct perf_event *event, u64 status)
+static u64 __grt_latency_data(struct perf_event *event, u64 status,
+ u8 dse, bool tlb, bool lock, bool blk)
{
- union intel_x86_pebs_dse dse;
u64 val;
- WARN_ON_ONCE(hybrid_pmu(event->pmu)->cpu_type == hybrid_big);
+ WARN_ON_ONCE(is_hybrid() &&
+ hybrid_pmu(event->pmu)->cpu_type == hybrid_big);
- dse.val = status;
+ val = hybrid_var(event->pmu, pebs_data_source)[dse];
- val = hybrid_var(event->pmu, pebs_data_source)[dse.ld_dse];
+ pebs_set_tlb_lock(&val, tlb, lock);
- /*
- * For the atom core on ADL,
- * bit 4: lock, bit 5: TLB access.
- */
- pebs_set_tlb_lock(&val, dse.ld_locked, dse.ld_stlb_miss);
-
- if (dse.ld_data_blk)
+ if (blk)
val |= P(BLK, DATA);
else
val |= P(BLK, NA);
@@ -246,15 +241,22 @@ u64 adl_latency_data_small(struct perf_event *event, u64 status)
return val;
}
-static u64 load_latency_data(struct perf_event *event, u64 status)
+u64 grt_latency_data(struct perf_event *event, u64 status)
{
union intel_x86_pebs_dse dse;
u64 val;
dse.val = status;
+ /* Gracemont uses bit 4 for lock and bit 5 for TLB access. */
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_LAT_HYBRID)
+ return __grt_latency_data(event, status, dse.ld_dse,
+ dse.ld_locked, dse.ld_stlb_miss,
+ dse.ld_data_blk);
+
/*
- * use the mapping table for bit 0-3
+ * For non-Gracemont load-latency events, use the mapping table
+ * for bit 0-3 and retain the legacy TLB, lock and block decoding.
*/
val = hybrid_var(event->pmu, pebs_data_source)[dse.ld_dse];
@@ -838,7 +840,7 @@ struct event_constraint intel_glm_pebs_event_constraints[] = {
struct event_constraint intel_grt_pebs_event_constraints[] = {
/* Allow all events as PEBS with no flags */
INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0x3),
- INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0xf),
+ INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0x3f),
EVENT_CONSTRAINT_END
};
@@ -1511,7 +1513,7 @@ static u64 get_data_src(struct perf_event *event, u64 aux)
bool fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
if (fl & PERF_X86_EVENT_PEBS_LDLAT)
- val = load_latency_data(event, aux);
+ val = grt_latency_data(event, aux);
else if (fl & PERF_X86_EVENT_PEBS_STLAT)
val = store_latency_data(event, aux);
else if (fl & PERF_X86_EVENT_PEBS_LAT_HYBRID)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 5f93316c60216..897d0abd94105 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -468,6 +468,14 @@ struct cpu_hw_events {
__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID)
+#define INTEL_HYBRID_LDLAT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID|PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_HYBRID_STLAT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID|PERF_X86_EVENT_PEBS_ST_HSW)
+
/* Event constraint, but match on all event flags too. */
#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS)
@@ -1497,7 +1505,7 @@ void intel_pmu_disable_bts(void);
int intel_pmu_drain_bts_buffer(void);
-u64 adl_latency_data_small(struct perf_event *event, u64 status);
+u64 grt_latency_data(struct perf_event *event, u64 status);
extern struct event_constraint intel_core2_pebs_event_constraints[];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0158/1887] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0157/1887] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0159/1887] smb: client: use finish_no_open() for non-regular inodes Greg Kroah-Hartman
` (840 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
Ingo Molnar, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
[ Upstream commit 89dc568e8c0be60e05e5fcd0b528c79077d7b84b ]
On Gracemont, intel_grt_pebs_event_constraints[] applies LAT_CONSTRAINT
constraints to MEM_UOPS_RETIRED.{LOAD,STORE}_LATENCY, but does not set
explicit LOAD/STORE flags for those events.
The PEBS latency path (pebs_latency_data(), via __grt_latency_data())
uses the event flags to determine memory operation direction. Without an
explicit STORE flag, samples from MEM_UOPS_RETIRED.STORE_LATENCY can be
misclassified as LOADs.
Set explicit LOAD/STORE flags in intel_grt_pebs_event_constraints[] for:
- MEM_UOPS_RETIRED.LOAD_LATENCY
- MEM_UOPS_RETIRED.STORE_LATENCY
Also update __grt_latency_data() to explicitly interpret these flags when
assigning the sampled memory operation direction.
This fixes incorrect STORE sample classification.
Fixes: 39a41278f041 ("perf/x86/intel: Fix PEBS memory access info encoding for ADL")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: <stable@vger.kernel.org> # v7.2+
Link: https://patch.msgid.link/20260917015234.981153-2-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/ds.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index d1cf9876c931d..d05db7aeef78a 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -224,6 +224,7 @@ static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock)
static u64 __grt_latency_data(struct perf_event *event, u64 status,
u8 dse, bool tlb, bool lock, bool blk)
{
+ union perf_mem_data_src src;
u64 val;
WARN_ON_ONCE(is_hybrid() &&
@@ -238,7 +239,16 @@ static u64 __grt_latency_data(struct perf_event *event, u64 status,
else
val |= P(BLK, NA);
- return val;
+ src.val = val;
+
+ if (event->hw.flags &
+ (PERF_X86_EVENT_PEBS_LDLAT | PERF_X86_EVENT_PEBS_LD_HSW))
+ src.mem_op = P(OP, LOAD);
+ if (event->hw.flags &
+ (PERF_X86_EVENT_PEBS_STLAT | PERF_X86_EVENT_PEBS_ST_HSW))
+ src.mem_op = P(OP, STORE);
+
+ return src.val;
}
u64 grt_latency_data(struct perf_event *event, u64 status)
@@ -839,8 +849,8 @@ struct event_constraint intel_glm_pebs_event_constraints[] = {
struct event_constraint intel_grt_pebs_event_constraints[] = {
/* Allow all events as PEBS with no flags */
- INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0x3),
- INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0x3f),
+ INTEL_HYBRID_LDLAT_CONSTRAINT(0x5d0, 0x3),
+ INTEL_HYBRID_STLAT_CONSTRAINT(0x6d0, 0x3f),
EVENT_CONSTRAINT_END
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0159/1887] smb: client: use finish_no_open() for non-regular inodes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0158/1887] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0160/1887] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
` (839 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit e66cf1625ec4a3fe68346119f371def713fd0a4d ]
An O_CREAT open can find an existing symlink or another non-regular
inode. cifs_atomic_open() calls finish_open() on it and attaches a
cifsFileInfo. Symlink inodes have no CIFS release operation, so the
dentry reference held by cifsFileInfo is leaked. FMODE_OPENED also
prevents the VFS from following the symlink.
Track whether cifs_do_create() returned an open server handle. For
non-regular inodes, close the handle if present, remove the pending
open, and call finish_no_open() so the VFS can continue the lookup.
Do not set FMODE_CREATED unless a regular file was opened. For
O_NOFOLLOW with __O_REGULAR, return -ELOOP before the VFS's
-EFTYPE check.
Defer closing a legacy POSIX handle on a non-regular inode until
after inode lookup. This avoids closing it again if lookup fails.
Fixes: d2c127197dfc ("cifs: implement i_op->atomic_open()")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: stable@vger.kernel.org
[ replaced S_ISREG(inode->i_mode) with d_is_reg(direntry) because the older cifs_do_create() already attaches the inode. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/dir.c | 39 +++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index b5b64b061b715..d34230b8e1246 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -176,7 +176,8 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock,
- struct cifs_fid *fid, struct cifs_open_info_data *buf)
+ struct cifs_fid *fid, struct cifs_open_info_data *buf,
+ bool *opened)
{
int rc = -ENOENT;
int create_options = CREATE_NOT_DIR;
@@ -191,6 +192,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
struct cifs_open_parms oparms;
int rdwr_for_fscache = 0;
+ *opened = false;
*oplock = 0;
if (tcon->ses->server->oplocks)
*oplock = REQ_OPLOCK;
@@ -213,6 +215,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
oflags, oplock, &fid->netfid, xid);
switch (rc) {
case 0:
+ *opened = true;
if (newinode == NULL) {
/* query inode info */
goto cifs_create_get_file_info;
@@ -229,11 +232,9 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
/*
* The server may allow us to open things like
* FIFOs, but the client isn't set up to deal
- * with that. If it's not a regular file, just
- * close it and proceed as if it were a normal
- * lookup.
+ * with that. Keep the handle until the caller
+ * can finish the lookup.
*/
- CIFSSMBClose(xid, tcon, fid->netfid);
goto cifs_create_get_file_info;
}
/* success, no need to query */
@@ -333,6 +334,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
}
goto out;
}
+ *opened = true;
if (rdwr_for_fscache == 2)
cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
@@ -423,7 +425,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
return rc;
out_err:
- if (server->ops->close)
+ if (*opened && server->ops->close)
server->ops->close(xid, tcon, fid);
if (newinode)
iput(newinode);
@@ -442,6 +444,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
struct cifs_fid fid = {};
struct cifs_pending_open open;
__u32 oplock;
+ bool is_regular;
+ bool opened;
struct cifsFileInfo *file_info;
struct cifs_open_info_data buf = {};
@@ -501,15 +505,28 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
cifs_add_pending_open(&fid, tlink, &open);
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
- &oplock, &fid, &buf);
+ &oplock, &fid, &buf, &opened);
if (rc) {
cifs_del_pending_open(&open);
goto out;
}
- if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ is_regular = d_is_reg(direntry);
+ if (!is_regular || !opened) {
+ if (opened && server->ops->close)
+ server->ops->close(xid, tcon, &fid);
+ cifs_del_pending_open(&open);
+ }
+
+ if (is_regular && opened &&
+ (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
file->f_mode |= FMODE_CREATED;
+ if (!is_regular || !opened) {
+ rc = finish_no_open(file, NULL);
+ goto out;
+ }
+
rc = finish_open(file, direntry, generic_file_open);
if (rc) {
if (server->ops->close)
@@ -564,6 +581,7 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
struct TCP_Server_Info *server;
struct cifs_fid fid;
__u32 oplock;
+ bool opened;
struct cifs_open_info_data buf = {};
cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
@@ -585,8 +603,9 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
if (server->ops->new_lease_key)
server->ops->new_lease_key(&fid);
- rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf);
- if (!rc && server->ops->close)
+ rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+ &oplock, &fid, &buf, &opened);
+ if (!rc && opened && server->ops->close)
server->ops->close(xid, tcon, &fid);
cifs_free_open_info(&buf);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0160/1887] Bluetooth: mgmt: fix race in read_unconf_index_list()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0159/1887] smb: client: use finish_no_open() for non-regular inodes Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0161/1887] Bluetooth: btusb: Add IMC Networks QCA9377 to quirks table Greg Kroah-Hartman
` (838 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
[ Upstream commit b5dbb41b212c50c095a4dbee3017a84fe94f033b ]
read_unconf_index_list() counts unconfigured controllers before allocating
its response, then checks the device flags again while filling it.
hci_dev_list_lock stabilizes list membership, but it does not serialize the
per-device flags. During asynchronous controller setup, the worker can set
HCI_UNCONFIGURED and clear HCI_SETUP between the two passes. A controller
omitted from the allocation count can then become eligible for the fill
pass, causing an out-of-bounds write to rp->index[].
Allocate space for every device on hci_dev_list. Since list membership
cannot change while hci_dev_list_lock is held, the response remains large
enough regardless of flag transitions. The reported count and response
length still include only eligible unconfigured controllers.
Fixes: 73d1df2a7a10 ("Bluetooth: Add support for Read Unconfigured Index List command")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Replaced unavailable list_count_nodes() with a list_for_each_entry() counting loop. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/mgmt.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 251e0c0a062a7..7758210c927bc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -500,12 +500,10 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
read_lock(&hci_dev_list_lock);
count = 0;
- list_for_each_entry(d, &hci_dev_list, list) {
- if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
- count++;
- }
+ list_for_each_entry(d, &hci_dev_list, list)
+ count++;
- rp_len = sizeof(*rp) + (2 * count);
+ rp_len = sizeof(*rp) + (sizeof(__le16) * count);
rp = kmalloc(rp_len, GFP_ATOMIC);
if (!rp) {
read_unlock(&hci_dev_list_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0161/1887] Bluetooth: btusb: Add IMC Networks QCA9377 to quirks table
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0160/1887] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0162/1887] HID: core: remove #ifdef CONFIG_PM from hid_driver Greg Kroah-Hartman
` (837 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tibor Harcsa, Luiz Augusto von Dentz,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tibor Harcsa <silurust@gmail.com>
[ Upstream commit dc16388d45ecbd3be0d8c9424dbbaa2c81806578 ]
Add the USB ID (13d3:3503) for the IMC Networks Qualcomm Atheros
QCA9377 Bluetooth controller to the btusb quirks table. This device
requires Qualcomm Rome firmware and wideband speech support to function
properly; otherwise, BLE scanning fails with HCI unexpected event
opcode 0x2005 errors.
The device reports the following in /sys/kernel/debug/usb/devices:
P: Vendor=13d3 ProdID=3503 Rev= 0.01
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Tibor Harcsa <silurust@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btusb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 3c1d6a711338d..3ffe8e3bcac9a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -304,6 +304,8 @@ static const struct usb_device_id blacklist_table[] = {
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3501), .driver_info = BTUSB_QCA_ROME |
BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3503), .driver_info = BTUSB_QCA_ROME |
+ BTUSB_WIDEBAND_SPEECH },
/* QCA WCN6855 chipset */
{ USB_DEVICE(0x0cf3, 0xe600), .driver_info = BTUSB_QCA_WCN6855 |
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0162/1887] HID: core: remove #ifdef CONFIG_PM from hid_driver
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0161/1887] Bluetooth: btusb: Add IMC Networks QCA9377 to quirks table Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0163/1887] HID: hid-alps: use default remove for hid device Greg Kroah-Hartman
` (836 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Weißschuh,
Benjamin Tissoires, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <linux@weissschuh.net>
[ Upstream commit df8b030d82dd1224881acb4e778fa06c4824f72b ]
Allow HID drivers to pass ->suspend, ->resume and ->reset_resume via
pm_ptr().
Through the usage of pm_ptr() the CONFIG_PM-dependent code will always be
compiled, protecting against bitrot.
The linker will then garbage-collect the unused function avoiding any overhead.
The only overhead in the final kernel image and at runtime are a few
extra bytes in 'struct hid_driver'.
The same approach is chosen by 'struct usb_driver' and other subsystems.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/r/20231012-hid-pm_ptr-v1-1-0a71531ca93b@weissschuh.net
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/hid.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 536a4750b905b..9fde4e8839c91 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -837,11 +837,11 @@ struct hid_driver {
void (*feature_mapping)(struct hid_device *hdev,
struct hid_field *field,
struct hid_usage *usage);
-#ifdef CONFIG_PM
+
int (*suspend)(struct hid_device *hdev, pm_message_t message);
int (*resume)(struct hid_device *hdev);
int (*reset_resume)(struct hid_device *hdev);
-#endif
+
/* private: */
struct device_driver driver;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0163/1887] HID: hid-alps: use default remove for hid device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0162/1887] HID: core: remove #ifdef CONFIG_PM from hid_driver Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0164/1887] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM Greg Kroah-Hartman
` (835 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marcus Folkesson, Jiri Kosina,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcus Folkesson <marcus.folkesson@gmail.com>
[ Upstream commit 989f7cc94f1174269282a4a46bb735c7f11527de ]
hid_device_remove() will call hid_hw_stop() as default .remove function
if no function is specified.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Stable-dep-of: aa9dde93e05a ("HID: alps: unregister DualPoint Stick input device on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-alps.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index 72c21014de845..8aed5e17e5819 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -825,11 +825,6 @@ static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
return 0;
}
-static void alps_remove(struct hid_device *hdev)
-{
- hid_hw_stop(hdev);
-}
-
static const struct hid_device_id alps_id[] = {
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
@@ -847,7 +842,6 @@ static struct hid_driver alps_driver = {
.name = "hid-alps",
.id_table = alps_id,
.probe = alps_probe,
- .remove = alps_remove,
.raw_event = alps_raw_event,
.input_mapping = alps_input_mapping,
.input_configured = alps_input_configured,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0164/1887] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0163/1887] HID: hid-alps: use default remove for hid device Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0165/1887] HID: alps: unregister DualPoint Stick input device on remove Greg Kroah-Hartman
` (834 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bastien Nocera, Jiri Kosina,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bastien Nocera <hadess@hadess.net>
[ Upstream commit 5e130f58629a2819c9d053507ad368160d25eb65 ]
This increases build coverage and allows to drop an #ifdef.
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Stable-dep-of: aa9dde93e05a ("HID: alps: unregister DualPoint Stick input device on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-alps.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index 8aed5e17e5819..35df84426196c 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -845,10 +845,8 @@ static struct hid_driver alps_driver = {
.raw_event = alps_raw_event,
.input_mapping = alps_input_mapping,
.input_configured = alps_input_configured,
-#ifdef CONFIG_PM
- .resume = alps_post_resume,
- .reset_resume = alps_post_reset,
-#endif
+ .resume = pm_ptr(alps_post_resume),
+ .reset_resume = pm_ptr(alps_post_reset),
};
module_hid_driver(alps_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0165/1887] HID: alps: unregister DualPoint Stick input device on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0164/1887] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0166/1887] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Greg Kroah-Hartman
` (833 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chen Changcheng, Jiri Kosina,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Changcheng <chenchangcheng@kylinos.cn>
[ Upstream commit aa9dde93e05a837645fdfd577eea71f0733f0694 ]
alps_input_configured() allocates a second input device ("DualPoint
Stick") with input_allocate_device() and registers it, but the
alps_driver struct has no .remove handler and input2 is not tracked in
hdev->inputs. The default remove path (hid_hw_stop -> hidinput_disconnect)
only iterates hdev->inputs, so input2 is never unregistered and leaks
on every device removal.
Add a .remove handler that stops the device first (preventing URB
callbacks from touching input2 during teardown) and then unregisters
input2.
Fixes: 2562756dde55 ("HID: add Alps I2C HID Touchpad-Stick support")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-alps.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index 35df84426196c..25da180175007 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -825,6 +825,24 @@ static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
return 0;
}
+static void alps_remove(struct hid_device *hdev)
+{
+ struct alps_dev *data = hid_get_drvdata(hdev);
+
+ /*
+ * input2 ("DualPoint Stick") is allocated separately and is not
+ * tracked in hdev->inputs, so the default remove path
+ * (hid_hw_stop -> hidinput_disconnect) does not unregister it.
+ *
+ * Stop the device first so that no URB callback can touch input2
+ * while it is being unregistered, then drop it explicitly.
+ */
+ hid_hw_stop(hdev);
+
+ if (data->input2)
+ input_unregister_device(data->input2);
+}
+
static const struct hid_device_id alps_id[] = {
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
@@ -847,6 +865,7 @@ static struct hid_driver alps_driver = {
.input_configured = alps_input_configured,
.resume = pm_ptr(alps_post_resume),
.reset_resume = pm_ptr(alps_post_reset),
+ .remove = alps_remove,
};
module_hid_driver(alps_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0166/1887] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0165/1887] HID: alps: unregister DualPoint Stick input device on remove Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0167/1887] smb/client: pass cifs_open_info_data to SMB2_open() Greg Kroah-Hartman
` (832 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit fc8789bb57e625e5f32ac57ca2e7d3e7b7fda225 ]
SMB2_open() only fills the fixed fields, so a stack-allocated
smb2_file_all_info is sufficient here.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: 566820af017e ("smb: client: close handle after create-context parsing failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/link.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
index d71feb3fdbd2c..ce76807cfe915 100644
--- a/fs/smb/client/link.c
+++ b/fs/smb/client/link.c
@@ -355,7 +355,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int buf_type = CIFS_NO_BUFFER;
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
- struct smb2_file_all_info *pfile_info = NULL;
+ struct smb2_file_all_info file_info = {};
oparms = (struct cifs_open_parms) {
.tcon = tcon,
@@ -371,20 +371,12 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
if (utf16_path == NULL)
return -ENOMEM;
- pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
- GFP_KERNEL);
-
- if (pfile_info == NULL) {
- kfree(utf16_path);
- return -ENOMEM;
- }
-
- rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
+ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &file_info, NULL,
NULL, NULL);
if (rc)
goto qmf_out_open_fail;
- if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
+ if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
/* it's not a symlink */
rc = -ENOENT; /* Is there a better rc to return? */
goto qmf_out;
@@ -402,7 +394,6 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
qmf_out_open_fail:
kfree(utf16_path);
- kfree(pfile_info);
return rc;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0167/1887] smb/client: pass cifs_open_info_data to SMB2_open()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0166/1887] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0168/1887] smb: client: close handle after create-context parsing failure Greg Kroah-Hartman
` (831 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 1f551e407bb49dce0bbd34ed6a499dad69e18020 ]
Let SMB2_open() fill the smb2_file_all_info embedded in cifs_open_info_data
directly. This removes the temporary smb2_file_all_info copy in
smb2_open_file().
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
[6.1 dependency adaptation]
Keep the stable branch's request setup and extern declarations while
passing cifs_open_info_data through SMB2_open() and its non-NULL callers.
Use the embedded fi directly, retaining the existing symlink retry reset.
Move the existing six-argument trace_smb3_open_done() call after
smb2_parse_contexts(), matching the layout needed for a clean three-way
application of 566820af017e ("smb: client: close handle after create-context
parsing failure"). Do not import upstream replay support or the newer
tracepoint signature. No functions are added.
Stable-dep-of: 566820af017e ("smb: client: close handle after create-context parsing failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/link.c | 6 +++---
fs/smb/client/smb2file.c | 19 ++++++++-----------
fs/smb/client/smb2pdu.c | 31 ++++++++++++++++---------------
fs/smb/client/smb2proto.h | 2 +-
4 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
index ce76807cfe915..cf90ef0404710 100644
--- a/fs/smb/client/link.c
+++ b/fs/smb/client/link.c
@@ -355,7 +355,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int buf_type = CIFS_NO_BUFFER;
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
- struct smb2_file_all_info file_info = {};
+ struct cifs_open_info_data data = {};
oparms = (struct cifs_open_parms) {
.tcon = tcon,
@@ -371,12 +371,12 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
if (utf16_path == NULL)
return -ENOMEM;
- rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &file_info, NULL,
+ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &data, NULL,
NULL, NULL);
if (rc)
goto qmf_out_open_fail;
- if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
+ if (data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
/* it's not a symlink */
rc = -ENOENT; /* Is there a better rc to return? */
goto qmf_out;
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
index 2d0dd87dae0dd..e3da8107bda45 100644
--- a/fs/smb/client/smb2file.c
+++ b/fs/smb/client/smb2file.c
@@ -112,8 +112,6 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
__le16 *smb2_path;
__u8 smb2_oplock;
struct cifs_open_info_data *data = buf;
- struct smb2_file_all_info file_info = {};
- struct smb2_file_all_info *smb2_data = data ? &file_info : NULL;
struct kvec err_iov = {};
int err_buftype = CIFS_NO_BUFFER;
struct cifs_fid *fid = oparms->fid;
@@ -130,14 +128,14 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
}
smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
- rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
+ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data, NULL, &err_iov,
&err_buftype);
if (rc == -EACCES && retry_without_read_attributes) {
free_rsp_buf(err_buftype, err_iov.iov_base);
memset(&err_iov, 0, sizeof(err_iov));
err_buftype = CIFS_NO_BUFFER;
oparms->desired_access &= ~FILE_READ_ATTRIBUTES;
- rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
+ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data, NULL, &err_iov,
&err_buftype);
}
if (rc && data) {
@@ -149,9 +147,9 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
&data->symlink_target);
if (!rc) {
- memset(smb2_data, 0, sizeof(*smb2_data));
+ memset(&data->fi, 0, sizeof(data->fi));
oparms->create_options |= OPEN_REPARSE_POINT;
- rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data,
+ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data,
NULL, NULL, NULL);
oparms->create_options &= ~OPEN_REPARSE_POINT;
}
@@ -180,23 +178,22 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
rc = 0;
}
- if (smb2_data) {
+ if (data) {
/* if open response does not have IndexNumber field - get it */
- if (smb2_data->IndexNumber == 0) {
+ if (data->fi.IndexNumber == 0) {
rc = SMB2_get_srv_num(xid, oparms->tcon,
fid->persistent_fid,
fid->volatile_fid,
- &smb2_data->IndexNumber);
+ &data->fi.IndexNumber);
if (rc) {
/*
* let get_inode_info disable server inode
* numbers
*/
- smb2_data->IndexNumber = 0;
+ data->fi.IndexNumber = 0;
rc = 0;
}
}
- memcpy(&data->fi, smb2_data, sizeof(data->fi));
}
*oplock = smb2_oplock;
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d55858a12b18a..6a75d36bc5402 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -3121,7 +3121,7 @@ SMB2_open_free(struct smb_rqst *rqst)
int
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
- __u8 *oplock, struct smb2_file_all_info *buf,
+ __u8 *oplock, struct cifs_open_info_data *buf,
struct create_posix_rsp *posix,
struct kvec *err_iov, int *buftype)
{
@@ -3135,6 +3135,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
int resp_buftype = CIFS_NO_BUFFER;
int rc = 0;
int flags = 0;
+ struct smb2_file_all_info *file_info = buf ? &buf->fi : NULL;
cifs_dbg(FYI, "create/open\n");
if (!ses || !server)
@@ -3179,9 +3180,6 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
goto creat_exit;
} else if (rsp == NULL) /* unlikely to happen, but safer to check */
goto creat_exit;
- else
- trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
- oparms->create_options, oparms->desired_access);
atomic_inc(&tcon->num_remote_opens);
oparms->fid->persistent_fid = rsp->PersistentFileId;
@@ -3191,21 +3189,24 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
#endif /* CIFS_DEBUG2 */
- if (buf) {
- buf->CreationTime = rsp->CreationTime;
- buf->LastAccessTime = rsp->LastAccessTime;
- buf->LastWriteTime = rsp->LastWriteTime;
- buf->ChangeTime = rsp->ChangeTime;
- buf->AllocationSize = rsp->AllocationSize;
- buf->EndOfFile = rsp->EndofFile;
- buf->Attributes = rsp->FileAttributes;
- buf->NumberOfLinks = cpu_to_le32(1);
- buf->DeletePending = 0;
+ if (file_info) {
+ file_info->CreationTime = rsp->CreationTime;
+ file_info->LastAccessTime = rsp->LastAccessTime;
+ file_info->LastWriteTime = rsp->LastWriteTime;
+ file_info->ChangeTime = rsp->ChangeTime;
+ file_info->AllocationSize = rsp->AllocationSize;
+ file_info->EndOfFile = rsp->EndofFile;
+ file_info->Attributes = rsp->FileAttributes;
+ file_info->NumberOfLinks = cpu_to_le32(1);
+ file_info->DeletePending = 0;
}
rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch,
- oparms->fid->lease_key, oplock, buf, posix);
+ oparms->fid->lease_key, oplock, file_info, posix);
+
+ trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
+ oparms->create_options, oparms->desired_access);
creat_exit:
SMB2_open_free(&rqst);
free_rsp_buf(resp_buftype, rsp);
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 79e5e7764c3d9..2897fb6f5397e 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -122,7 +122,7 @@ extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses,
extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
__le16 *path, __u8 *oplock,
- struct smb2_file_all_info *buf,
+ struct cifs_open_info_data *buf,
struct create_posix_rsp *posix,
struct kvec *err_iov, int *resp_buftype);
extern int SMB2_open_init(struct cifs_tcon *tcon,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0168/1887] smb: client: close handle after create-context parsing failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0167/1887] smb/client: pass cifs_open_info_data to SMB2_open() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0169/1887] smb: client: close completed creates on compound wait errors Greg Kroah-Hartman
` (830 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit 566820af017e81497fb5e9d3ad6e7ffe2828bc8b ]
SMB2_open() accounts a successful CREATE response as a remote open before
parsing its create contexts. If smb2_parse_contexts() rejects malformed
context data, SMB2_open() returns without closing the handle, leaving the
server-side handle open and num_remote_opens elevated.
Close the handle after a post-CREATE context parsing failure so the error
path releases the remote resource and balances the open count.
Fixes: af1689a9b770 ("smb: client: fix potential OOBs in smb2_parse_contexts()")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 6a75d36bc5402..c50881cf4c8d7 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -3204,6 +3204,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch,
oparms->fid->lease_key, oplock, file_info, posix);
+ if (rc)
+ SMB2_close(xid, tcon, oparms->fid->persistent_fid,
+ oparms->fid->volatile_fid);
trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
oparms->create_options, oparms->desired_access);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0169/1887] smb: client: close completed creates on compound wait errors
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0168/1887] smb: client: close handle after create-context parsing failure Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0170/1887] xfs: fix cursor and pointer handling when recovering iunlink buckets Greg Kroah-Hartman
` (829 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit 6c5c547f037bc18f0b8d0b5db5a648f8f630ce85 ]
compound_send_recv() waits for responses in order. If a later wait is
interrupted, or if a later MID fails during response synchronization, an
earlier CREATE may already have opened a remote handle. The earlier mid
is then released without invoking handle_cancelled_mid(), leaving the
remote handle open because no FID was copied to the caller.
Mark completed earlier mids as cancelled when a compound wait or MID
synchronization aborts. Keep their response buffers attached while the
MIDs are synchronized, and transfer them only after synchronization of
the processed responses, so the release path can inspect successful
CREATE responses and queue SMB2_close() after a later failure. Account for
a remote open only after the close work is allocated and before it is
queued, since the caller has not yet updated num_remote_opens. Mark the
create+close compound used by smb2_unlink() so it is not closed again.
Non-CREATE responses and compounds that already include a close keep their
existing behavior.
Fixes: e0bba0b85481 ("cifs: add compound_send_recv()")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ replaced the upstream cancellation helper with inline loops using midQ and MID_WAIT_CANCELLED under server->mid_lock. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2misc.c | 9 +++--
fs/smb/client/transport.c | 69 ++++++++++++++++++++++++++++++---------
2 files changed, 59 insertions(+), 19 deletions(-)
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index cd00bf48c9a56..ecab56c00f627 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -818,7 +818,8 @@ smb2_cancelled_close_fid(struct work_struct *work)
*/
static int
__smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
- __u64 persistent_fid, __u64 volatile_fid)
+ __u64 persistent_fid, __u64 volatile_fid,
+ bool account_remote_open)
{
struct close_cancelled_open *cancelled;
@@ -832,6 +833,8 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
cancelled->cmd = cmd;
cancelled->mid = mid;
INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
+ if (account_remote_open)
+ atomic_inc(&tcon->num_remote_opens);
WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false);
return 0;
@@ -868,7 +871,7 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
spin_unlock(&cifs_tcp_ses_lock);
rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
- persistent_fid, volatile_fid);
+ persistent_fid, volatile_fid, false);
if (rc)
cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cancelled_close);
@@ -896,7 +899,7 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
le16_to_cpu(hdr->Command),
le64_to_cpu(hdr->MessageId),
rsp->PersistentFileId,
- rsp->VolatileFileId);
+ rsp->VolatileFileId, true);
if (rc)
cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cancelled_mid);
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 59063b26afe43..c5c81b4261985 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -1100,6 +1100,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
int *resp_buf_type, struct kvec *resp_iov)
{
int i, j, optype, rc = 0;
+ int num_processed = 0;
struct mid_q_entry *midQ[MAX_COMPOUND];
bool cancelled_mid[MAX_COMPOUND] = {false};
struct cifs_credits credits[MAX_COMPOUND] = {
@@ -1242,6 +1243,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
break;
}
if (rc != 0) {
+ /*
+ * A completed CREATE earlier in the compound chain may have
+ * opened a remote handle even though a later wait was
+ * interrupted. Mark it cancelled so __release_mid() invokes
+ * the existing unmatched-open cleanup.
+ */
+ spin_lock(&server->mid_lock);
+ for (j = 0; j < i; j++)
+ midQ[j]->mid_flags |= MID_WAIT_CANCELLED;
+ spin_unlock(&server->mid_lock);
+
for (; i < num_rqst; i++) {
cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
midQ[i]->mid, le16_to_cpu(midQ[i]->command));
@@ -1264,6 +1276,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
rc = cifs_sync_mid_result(midQ[i], server);
if (rc != 0) {
+ /*
+ * A previous CREATE may have completed before this
+ * response failed. Mark it cancelled so its remote
+ * handle is closed when the mid is released.
+ */
+ spin_lock(&server->mid_lock);
+ for (j = 0; j < i; j++)
+ midQ[j]->mid_flags |= MID_WAIT_CANCELLED;
+ spin_unlock(&server->mid_lock);
+ /* Keep their response buffers for cancelled-mid cleanup. */
+ num_processed = 0;
/* mark this mid as cancelled to not free it below */
cancelled_mid[i] = true;
goto out;
@@ -1273,9 +1296,26 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
midQ[i]->mid_state != MID_RESPONSE_READY) {
rc = -EIO;
cifs_dbg(FYI, "Bad MID state?\n");
+ spin_lock(&server->mid_lock);
+ for (j = 0; j < i; j++)
+ midQ[j]->mid_flags |= MID_WAIT_CANCELLED;
+ spin_unlock(&server->mid_lock);
+ num_processed = 0;
goto out;
}
+ rc = server->ops->check_receive(midQ[i], server,
+ flags & CIFS_LOG_ERROR);
+ num_processed = i + 1;
+ }
+
+out:
+ /*
+ * Delay moving response buffers out of their mids until response
+ * synchronization completes. This lets cancelled-mid cleanup inspect
+ * an earlier CREATE response if a later MID fails.
+ */
+ for (i = 0; i < num_processed; i++) {
buf = (char *)midQ[i]->resp_buf;
resp_iov[i].iov_base = buf;
resp_iov[i].iov_len = midQ[i]->resp_buf_size +
@@ -1286,33 +1326,30 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
else
resp_buf_type[i] = CIFS_SMALL_BUFFER;
- rc = server->ops->check_receive(midQ[i], server,
- flags & CIFS_LOG_ERROR);
-
/* mark it so buf will not be freed by delete_mid */
if ((flags & CIFS_NO_RSP_BUF) == 0)
midQ[i]->resp_buf = NULL;
-
}
/*
* Compounding is never used during session establish.
*/
- spin_lock(&ses->ses_lock);
- if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
- struct kvec iov = {
- .iov_base = resp_iov[0].iov_base,
- .iov_len = resp_iov[0].iov_len
- };
- spin_unlock(&ses->ses_lock);
- cifs_server_lock(server);
- smb311_update_preauth_hash(ses, server, &iov, 1);
- cifs_server_unlock(server);
+ if (num_processed == num_rqst) {
spin_lock(&ses->ses_lock);
+ if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
+ struct kvec iov = {
+ .iov_base = resp_iov[0].iov_base,
+ .iov_len = resp_iov[0].iov_len
+ };
+ spin_unlock(&ses->ses_lock);
+ cifs_server_lock(server);
+ smb311_update_preauth_hash(ses, server, &iov, 1);
+ cifs_server_unlock(server);
+ spin_lock(&ses->ses_lock);
+ }
+ spin_unlock(&ses->ses_lock);
}
- spin_unlock(&ses->ses_lock);
-out:
/*
* This will dequeue all mids. After this it is important that the
* demultiplex_thread will not process any of these mids any futher.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0170/1887] xfs: fix cursor and pointer handling when recovering iunlink buckets
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0169/1887] smb: client: close completed creates on compound wait errors Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0171/1887] ALSA: usb-audio: Apply IGNORE_CTL_ERROR quirk to all Audient devices Greg Kroah-Hartman
` (828 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 65f39d09d73718611cee40399179323b5d4ead00 ]
LOLLM pointed out a bug in xlog_recover_iunlink_bucket:
1. We don't null out prev_ip after releasing it, which can lead to UAF
problems if the inodegc flush call in the loop fails.
at which point I noticed even more bugs:
2. If the inodegc flush inside the loop fails, we also leak @ip.
3. We set prev_agino to agino having already advanced agino, which
results in inodes with i_prev_unlinked set to itself.
4. If we exit the bottom of the loop with prev_ip set, then prev_ip
aliases ip and we also set its i_prev_unlinked to itself.
Bugs 3 and 4 introduce loops into the unlinked list, though these loops
don't surface because we immediately flush each unlinked inode after
loading it.
Fix all of these issues.
Cc: stable@vger.kernel.org # v6.0
Fixes: 04755d2e5821b3 ("xfs: refactor xlog_recover_process_iunlinks()")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ Replaced unavailable xfs_agino_to_ino() with the existing XFS_AGINO_TO_INO() macro. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_log_recover.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index ffd52f5a4b897..bf510a6fb92e4 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2694,12 +2694,13 @@ xlog_recover_iunlink_bucket(
{
struct xfs_mount *mp = pag->pag_mount;
struct xfs_inode *prev_ip = NULL;
- struct xfs_inode *ip;
xfs_agino_t prev_agino, agino;
int error = 0;
agino = be32_to_cpu(agi->agi_unlinked[bucket]);
while (agino != NULLAGINO) {
+ struct xfs_inode *ip;
+
error = xfs_iget(mp, NULL,
XFS_AGINO_TO_INO(mp, pag->pag_agno, agino),
0, 0, &ip);
@@ -2709,11 +2710,11 @@ xlog_recover_iunlink_bucket(
ASSERT(VFS_I(ip)->i_nlink == 0);
ASSERT(VFS_I(ip)->i_mode != 0);
xfs_iflags_clear(ip, XFS_IRECOVERY);
- agino = ip->i_next_unlinked;
if (prev_ip) {
ip->i_prev_unlinked = prev_agino;
xfs_irele(prev_ip);
+ prev_ip = NULL;
/*
* Ensure the inode is removed from the unlinked list
@@ -2725,18 +2726,20 @@ xlog_recover_iunlink_bucket(
* complete.
*/
error = xfs_inodegc_flush(mp);
- if (error)
- break;
+ if (error) {
+ xfs_irele(ip);
+ return error;
+ }
}
prev_agino = agino;
+ agino = ip->i_next_unlinked;
prev_ip = ip;
}
if (prev_ip) {
int error2;
- ip->i_prev_unlinked = prev_agino;
xfs_irele(prev_ip);
error2 = xfs_inodegc_flush(mp);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0171/1887] ALSA: usb-audio: Apply IGNORE_CTL_ERROR quirk to all Audient devices
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0170/1887] xfs: fix cursor and pointer handling when recovering iunlink buckets Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0172/1887] audit: fix exe mark UAF in kill_rules() Greg Kroah-Hartman
` (827 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin,
Faaris Ansari
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit a154f7b9f197b3d5e41fa3ad62083f5aa93b1fe8 ]
Faaris reported a problem with Audient EVO4 device and it turned out
to be a regression by the recent fix commit 87a6f2fa6e6c ("ALSA:
usb-audio: Propagate write errors in generic mixer put callbacks").
It exhibited that the hardware gives errors at accessing the mixer
unit 10 on certain channels, and the change above made it a fatal
error.
We had already a quirk for Audient iD14 to work around such errors
from the mixer controls, and we can simply apply the same for EVO4.
OTOH, it's highly possible that other Audient devices suffer from the
same issue; they must be using similar firmware, after all.
So, in this patch, we apply the quirk generically to all devices with
the vendor ID Audient (2708), instead. Ignoring the control error
isn't usually less critical than overreaction to the firmware
misbehavior.
Fixes: 87a6f2fa6e6c ("ALSA: usb-audio: Propagate write errors in generic mixer put callbacks")
Reported-and-tested-by: Faaris Ansari <faarisansari@googlemail.com>
Closes: https://lore.kernel.org/CANBVYRCL=8QdLxGg4S6qrahrFtwJxhv-aSGpW7-1S=+iOe4ZGA@mail.gmail.com
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260929144132.1521617-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/quirks.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 22e69a6528dff..e2f37a09a8a80 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2263,8 +2263,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_SET_IFACE_FIRST),
DEVICE_FLG(0x262a, 0x9302, /* ddHiFi TC44C */
QUIRK_FLAG_DSD_RAW),
- DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
- QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
@@ -2330,6 +2328,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_DSD_RAW),
VENDOR_FLG(0x2622, /* IAG Limited devices */
QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x2708, /* Audient devices */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
VENDOR_FLG(0x278b, /* Rotel? */
QUIRK_FLAG_DSD_RAW),
VENDOR_FLG(0x292b, /* Gustard/Ess based devices */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0172/1887] audit: fix exe mark UAF in kill_rules()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0171/1887] ALSA: usb-audio: Apply IGNORE_CTL_ERROR quirk to all Audient devices Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0173/1887] kprobes: Skip disarmed probes when checking optkprobe overlap Greg Kroah-Hartman
` (826 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Ricardo Robaina, Bradley Morgan, Paul Moore
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
commit aa650d87a498844060eecb1d336f4d46f4d1b0b3 upstream.
kill_rules() removes mixed AUDIT_DIR and AUDIT_EXE rules when an audit
tree is pruned. It drops entry->rule.exe before removing the rule from
the RCU-visible filter lists.
After a rule has been installed with AUDIT_ADD_RULE, which requires
CAP_AUDIT_CONTROL, removing the watched directory can race with another
task that is still evaluating the rule. In that case, fsnotify can free
the executable mark before the reader reaches audit_mark_compare(),
causing a use-after-free.
KASAN reports:
BUG: KASAN: slab-use-after-free in audit_mark_compare+0x8d/0xa0
Unlink the published rules from the RCU-visible lists and retain them
on tree->rules for cleanup. If any rule has an executable mark, wait for
a single RCU grace period before removing the marks and scheduling the
entries for freeing. Otherwise, call_rcu() already provides the required
deferred freeing without a synchronous wait.
Cc: stable@vger.kernel.org
Fixes: 34d99af52ad4 ("audit: implement audit by executable")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Ricardo Robaina <rrobaina@redhat.com>
Tested-by: Ricardo Robaina <rrobaina@redhat.com>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/audit_tree.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -543,22 +543,38 @@ static void kill_rules(struct audit_cont
{
struct audit_krule *rule, *next;
struct audit_entry *entry;
+ bool need_sync = false;
list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
entry = container_of(rule, struct audit_entry, rule);
- list_del_init(&rule->rlist);
if (rule->tree) {
/* not a half-baked one */
audit_tree_log_remove_rule(context, rule);
- if (entry->rule.exe)
- audit_remove_mark(entry->rule.exe);
rule->tree = NULL;
list_del_rcu(&entry->list);
list_del(&entry->rule.list);
- call_rcu(&entry->rcu, audit_free_rule_rcu);
+ if (entry->rule.exe)
+ need_sync = true;
+ } else {
+ list_del_init(&rule->rlist);
}
}
+
+ if (list_empty(&tree->rules))
+ return;
+
+ if (need_sync)
+ synchronize_rcu();
+
+ list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
+ entry = container_of(rule, struct audit_entry, rule);
+
+ list_del_init(&rule->rlist);
+ if (entry->rule.exe)
+ audit_remove_mark(entry->rule.exe);
+ call_rcu(&entry->rcu, audit_free_rule_rcu);
+ }
}
/*
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0173/1887] kprobes: Skip disarmed probes when checking optkprobe overlap
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0172/1887] audit: fix exe mark UAF in kill_rules() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0174/1887] of/irq: Fix remaining refcount leaks in of_irq_init() Greg Kroah-Hartman
` (825 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Leon Hwang,
Masami Hiramatsu (Google)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Hwang <leon.hwang@linux.dev>
commit 7a39c732a22ec4a369af9e19fbe3d666ec83eec4 upstream.
On x86, an optkprobe at A replaces five bytes with a jump. If a disabled
probe B is at A+2, get_optimized_kprobe() stops at B when arming a new
probe C at A+4. It leaves A optimized:
A A+1 A+2 A+3 A+4
A's jump | e9 | d0 | d1 | d2 | d3 |
after C | e9 | d0 | d1 | d2 | cc |
The INT3 for C overwrites the last byte of A's jump displacement, so
execution can jump to the wrong address. B can have prepared optinsns
while disarmed, but has no jump to unoptimize.
Continue past disarmed and unprepared probes to find the active optimized
probe before arming a probe in its jump.
Link: https://lore.kernel.org/all/20260930053618.104498-1-leon.hwang@linux.dev/
Fixes: afd66255b9a4 ("kprobes: Introduce kprobes jump optimization")
Cc: stable@vger.kernel.org
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/kprobes.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -491,14 +491,16 @@ static bool kprobe_queued(struct kprobe
static struct kprobe *get_optimized_kprobe(kprobe_opcode_t *addr)
{
int i;
- struct kprobe *p = NULL;
+ struct kprobe *p;
struct optimized_kprobe *op;
/* Don't check i == 0, since that is a breakpoint case. */
- for (i = 1; !p && i < MAX_OPTIMIZED_LENGTH / sizeof(kprobe_opcode_t); i++)
+ for (i = 1; i < MAX_OPTIMIZED_LENGTH / sizeof(kprobe_opcode_t); i++) {
p = get_kprobe(addr - i);
+ /* A disabled probe can have prepared, but inactive, optinsns. */
+ if (!p || !kprobe_optready(p) || kprobe_disarmed(p))
+ continue;
- if (p && kprobe_optready(p)) {
op = container_of(p, struct optimized_kprobe, kp);
if (arch_within_optimized_kprobe(op, addr))
return p;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0174/1887] of/irq: Fix remaining refcount leaks in of_irq_init()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0173/1887] kprobes: Skip disarmed probes when checking optkprobe overlap Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0175/1887] of/overlay: put property on deadprops only after changeset add succeeds Greg Kroah-Hartman
` (824 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Rob Herring (Arm)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 30724547b221e0e670ddfef140fc7d816b2aaec6 upstream.
Successfully initialized controllers are moved to intc_parent_list,
but the final cleanup only frees the descriptors. The device node
references taken with of_node_get() and the interrupt parent
references are therefore leaked on the normal return path. Drop both
before kfree(), as the intc_desc_list cleanup already does.
Fixes: 8363ccb917c6 ("of/irq: add missing of_node_put")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917124247.2151674-1-vulab@iscas.ac.cn
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/of/irq.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -654,6 +654,8 @@ void __init of_irq_init(const struct of_
list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
list_del(&desc->list);
+ of_node_put(desc->interrupt_parent);
+ of_node_put(desc->dev);
kfree(desc);
}
err:
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0175/1887] of/overlay: put property on deadprops only after changeset add succeeds
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0174/1887] of/irq: Fix remaining refcount leaks in of_irq_init() Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0176/1887] of/overlay: only treat a positive changeset id as registered Greg Kroah-Hartman
` (823 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Abdurrahman Hussain,
Rob Herring (Arm)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
commit 814f2da6995772c07a7c9c2cc6028b6e3f3ecc9c upstream.
add_changeset_property() links a new property of a not-yet-live
target node into the node's deadprops list before handing it to
of_changeset_add_property(). If that fails, the error path frees the
property but leaves the freed pointer linked in deadprops, and
of_node_release() frees it a second time when the aborted overlay's
node is released.
Record the changeset entry first and link the property into deadprops
only on success. of_changeset_add_property() never looks at the
node's property lists, so the order of the two steps is otherwise
immaterial, and the error path frees a property that nothing
references.
Fixes: f96278810150 ("of: overlay: set node fields from properties when add new overlay node")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5 [Claude Code]
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Link: https://patch.msgid.link/20260831-nh-of-alias-overlay-v7-4-02754604805a@nexthop.ai
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/of/overlay.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -346,12 +346,13 @@ static int add_changeset_property(struct
return -ENOMEM;
if (!prop) {
- if (!target->in_livetree) {
+ ret = of_changeset_add_property(&ovcs->cset, target->np,
+ new_prop);
+ /* the detached node owns the property until the apply */
+ if (!ret && !target->in_livetree) {
new_prop->next = target->np->deadprops;
target->np->deadprops = new_prop;
}
- ret = of_changeset_add_property(&ovcs->cset, target->np,
- new_prop);
} else {
ret = of_changeset_update_property(&ovcs->cset, target->np,
new_prop);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0176/1887] of/overlay: only treat a positive changeset id as registered
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0175/1887] of/overlay: put property on deadprops only after changeset add succeeds Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0177/1887] netfilter: nft_flow_offload: drop flowtable reference on init error path Greg Kroah-Hartman
` (822 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geert Uytterhoeven,
Geert Uytterhoeven, Abdurrahman Hussain, Rob Herring (Arm)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
commit 44081d708b5b885487bac792db78324b7b4c267d upstream.
of_overlay_fdt_apply() stores the idr_alloc() return value in
ovcs->id before checking it. On failure the stored id is negative,
free_overlay_changeset()'s "if (ovcs->id)" check passes, idr_remove()
is called with a negative id and list_del() runs on ovcs->ovcs_list,
which is not initialized until after the id allocation. An allocation
failure at that point dereferences NULL.
Make free_overlay_changeset() treat only a strict-positive id as
registered. The rest of the function already copes with a
partially-initialized ovcs, so the error path stays a plain
goto err_free_ovcs.
Fixes: 61b4de4e0b38 ("of: overlay: minor restructuring")
Cc: stable@vger.kernel.org
Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Assisted-by: Claude:claude-fable-5 [Claude Code]
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Link: https://patch.msgid.link/20260831-nh-of-alias-overlay-v7-5-02754604805a@nexthop.ai
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/of/overlay.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -840,7 +840,8 @@ static void free_overlay_changeset(struc
if (ovcs->cset.entries.next)
of_changeset_destroy(&ovcs->cset);
- if (ovcs->id) {
+ /* a failed idr_alloc() leaves its negative error in ovcs->id */
+ if (ovcs->id > 0) {
idr_remove(&ovcs_idr, ovcs->id);
list_del(&ovcs->ovcs_list);
ovcs->id = 0;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0177/1887] netfilter: nft_flow_offload: drop flowtable reference on init error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0176/1887] of/overlay: only treat a positive changeset id as registered Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0178/1887] net/packet: prevent TX_RING byte count overflow Greg Kroah-Hartman
` (821 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Aohan Mei,
Pablo Neira Ayuso
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
commit 747928b5d4ff8c8de55138a54c13980e4bb88578 upstream.
nft_flow_offload_init() bumps the flowtable use count with
nft_use_inc() before calling nf_ct_netns_get(). When the latter
fails, the error is returned as-is and the reference is leaked.
The upper layers do not balance it either: nf_tables_newexpr()
clears expr->ops when the expression init callback fails, so the
nft_expr_more() iteration in nft_rule_expr_deactivate() and
nf_tables_rule_destroy() stops right before the failed expression
and its ->destroy callback, which would drop the reference, never
runs.
Each failed rule addition therefore leaks one flowtable reference
and the flowtable can no longer be removed: NFT_MSG_DELFLOWTABLE
keeps reporting -EBUSY even though no rule references it.
Save the nf_ct_netns_get() return value and undo the nft_use_inc()
when it fails, restoring the inc/dec pairing within
nft_flow_offload_init() itself.
Fixes: a3c90f7a2323 ("netfilter: nf_tables: flow offload expression")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/nft_flow_offload.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -416,6 +416,7 @@ static int nft_flow_offload_init(const s
struct nft_flow_offload *priv = nft_expr_priv(expr);
u8 genmask = nft_genmask_next(ctx->net);
struct nft_flowtable *flowtable;
+ int err;
if (!tb[NFTA_FLOW_TABLE_NAME])
return -EINVAL;
@@ -430,7 +431,11 @@ static int nft_flow_offload_init(const s
priv->flowtable = flowtable;
- return nf_ct_netns_get(ctx->net, ctx->family);
+ err = nf_ct_netns_get(ctx->net, ctx->family);
+ if (err < 0)
+ nft_use_dec(&flowtable->use);
+
+ return err;
}
static void nft_flow_offload_deactivate(const struct nft_ctx *ctx,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0178/1887] net/packet: prevent TX_RING byte count overflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0177/1887] netfilter: nft_flow_offload: drop flowtable reference on init error path Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0179/1887] rtc: spear: initialize IRQ state before requesting alarm IRQ Greg Kroah-Hartman
` (820 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ilkka Lappeteläinen,
Willem de Bruijn, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilkka Lappeteläinen <ilkka.lappetelainen@gmail.com>
commit 2cf81fc9505b148b1b70068303ea6ea4b1212403 upstream.
tpacket_snd() drains every SEND_REQUEST frame in a TX ring and adds
each valid packet length to the signed int len_sum. Userspace can
recycle completed frames concurrently, so a single blocking send call
is not bounded by the ring size.
After enough successful transmissions len_sum wraps into the negative
range. In particular, 65536 65535-byte frames followed by a 65007-byte
frame produce 0xfffffdef, or -EIOCBQUEUED. sock_sendmsg_nosec() treats
that as an impossible return and triggers a BUG. On systems configured
to panic on oops, a CAP_NET_RAW holder can panic the host kernel.
Stop before the next frame would make the byte count exceed INT_MAX.
The positive short count leaves that frame pending for a later send
call.
A two-thread TPACKET_V2 reproducer triggered the BUG on an arm64 build
of Linux 7.3-rc4. With this change, the same reproducer returned the
expected positive short count without an oops.
Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap")
Cc: stable@vger.kernel.org
Signed-off-by: Ilkka Lappeteläinen <ilkka.lappetelainen@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260925124829.6595-1-ilkka.lappetelainen@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2912,6 +2912,9 @@ static int tpacket_snd(struct packet_soc
vnet_hdr.hdr_len);
has_vnet_hdr = true;
}
+ /* Prevent the byte count from wrapping into a negative errno */
+ if (unlikely(tp_len > INT_MAX - len_sum))
+ break;
copylen = max_t(int, copylen, hard_header_len);
skb = sock_alloc_send_skb(&po->sk,
hlen + tlen + sizeof(struct sockaddr_ll) +
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0179/1887] rtc: spear: initialize IRQ state before requesting alarm IRQ
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0178/1887] net/packet: prevent TX_RING byte count overflow Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0180/1887] sctp: check RCV_SHUTDOWN after the sendmsg connect wait Greg Kroah-Hartman
` (819 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Alexandre Belloni
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 055ef5ce9f67a6a3a1363fa663007f8196cc0fb8 upstream.
devm_request_irq() enables the interrupt before it returns, so the handler
may run while probe is still initializing the device. Initialize the MMIO
address and spinlock before requesting the alarm IRQ.
Fixes: 0942a71e435f ("rtc: add support for spear rtc")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260902080318.3498434-1-runyu.xiao@seu.edu.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/rtc/rtc-spear.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -363,6 +363,12 @@ static int spear_rtc_probe(struct platfo
if (irq < 0)
return irq;
+ config->ioaddr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(config->ioaddr))
+ return PTR_ERR(config->ioaddr);
+
+ spin_lock_init(&config->lock);
+
status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name,
config);
if (status) {
@@ -371,10 +377,6 @@ static int spear_rtc_probe(struct platfo
return status;
}
- config->ioaddr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(config->ioaddr))
- return PTR_ERR(config->ioaddr);
-
config->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(config->clk))
return PTR_ERR(config->clk);
@@ -383,7 +385,6 @@ static int spear_rtc_probe(struct platfo
if (status < 0)
return status;
- spin_lock_init(&config->lock);
platform_set_drvdata(pdev, config);
config->rtc->ops = &spear_rtc_ops;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0180/1887] sctp: check RCV_SHUTDOWN after the sendmsg connect wait
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0179/1887] rtc: spear: initialize IRQ state before requesting alarm IRQ Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0181/1887] bpf: Fail bpf_timer_cancel when callback is being cancelled Greg Kroah-Hartman
` (818 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Jun Yang,
Xin Long, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jun Yang <junvyyang@tencent.com>
commit 4f1da630d13de0370e2f6361f961f1c8b384af1c upstream.
sctp_wait_for_connect() drops the socket lock while it sleeps. An
out-of-the-blue ABORT can then be processed from the socket backlog and
unlink the association. If a concurrent shutdown(fd, SHUT_RD) sets
RCV_SHUTDOWN, the waiter breaks with err == 0 before checking
asoc->base.dead. Its final sctp_association_put() can then free the
association, leaving sctp_sendmsg_to_asoc() to continue with a dangling
pointer.
Check RCV_SHUTDOWN along with the wait error in sctp_sendmsg_to_asoc()
before using the association again. The check only accesses the socket,
so it needs no additional association reference. Return the existing
-ESRCH so that sctp_sendmsg() skips freeing a new association that may
already have been destroyed.
Keep sctp_wait_for_connect() unchanged to preserve its behavior for the
connect() caller.
Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
Cc: stable@vger.kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260926095606.68601-1-juny24602@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sctp/socket.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1842,7 +1842,7 @@ static int sctp_sendmsg_to_asoc(struct s
if (asoc->ep->intl_enable) {
timeo = sock_sndtimeo(sk, 0);
err = sctp_wait_for_connect(asoc, &timeo);
- if (err) {
+ if (err || sk->sk_shutdown & RCV_SHUTDOWN) {
err = -ESRCH;
goto err;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0181/1887] bpf: Fail bpf_timer_cancel when callback is being cancelled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0180/1887] sctp: check RCV_SHUTDOWN after the sendmsg connect wait Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0182/1887] bpf: Defer work in bpf_timer_cancel_and_free Greg Kroah-Hartman
` (817 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dohyun Kim, Neel Natu,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Artem Dinaburg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit d4523831f07a267a943f0dde844bf8ead7495f13 ]
Given a schedule:
timer1 cb timer2 cb
bpf_timer_cancel(timer2); bpf_timer_cancel(timer1);
Both bpf_timer_cancel calls would wait for the other callback to finish
executing, introducing a lockup.
Add an atomic_t count named 'cancelling' in bpf_hrtimer. This keeps
track of all in-flight cancellation requests for a given BPF timer.
Whenever cancelling a BPF timer, we must check if we have outstanding
cancellation requests, and if so, we must fail the operation with an
error (-EDEADLK) since cancellation is synchronous and waits for the
callback to finish executing. This implies that we can enter a deadlock
situation involving two or more timer callbacks executing in parallel
and attempting to cancel one another.
Note that we avoid incrementing the cancelling counter for the target
timer (the one being cancelled) if bpf_timer_cancel is not invoked from
a callback, to avoid spurious errors. The whole point of detecting
cur->cancelling and returning -EDEADLK is to not enter a busy wait loop
(which may or may not lead to a lockup). This does not apply in case the
caller is in a non-callback context, the other side can continue to
cancel as it sees fit without running into errors.
Background on prior attempts:
Earlier versions of this patch used a bool 'cancelling' bit and used the
following pattern under timer->lock to publish cancellation status.
lock(t->lock);
t->cancelling = true;
mb();
if (cur->cancelling)
return -EDEADLK;
unlock(t->lock);
hrtimer_cancel(t->timer);
t->cancelling = false;
The store outside the critical section could overwrite a parallel
requests t->cancelling assignment to true, to ensure the parallely
executing callback observes its cancellation status.
It would be necessary to clear this cancelling bit once hrtimer_cancel
is done, but lack of serialization introduced races. Another option was
explored where bpf_timer_start would clear the bit when (re)starting the
timer under timer->lock. This would ensure serialized access to the
cancelling bit, but may allow it to be cleared before in-flight
hrtimer_cancel has finished executing, such that lockups can occur
again.
Thus, we choose an atomic counter to keep track of all outstanding
cancellation requests and use it to prevent lockups in case callbacks
attempt to cancel each other while executing in parallel.
[ Backport to 6.1.y: mapped the atomic cancellation guard directly onto
the pre-refactor bpf_hrtimer layout. ]
Reported-by: Dohyun Kim <dohyunkim@google.com>
Reported-by: Neel Natu <neelnatu@google.com>
Fixes: b00628b1c7d5 ("bpf: Introduce bpf timers.")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20240709185440.1104957-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/helpers.c | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 4cd7854932944..d5dcc172647c8 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1110,6 +1110,7 @@ const struct bpf_func_proto bpf_snprintf_proto = {
*/
struct bpf_hrtimer {
struct hrtimer timer;
+ atomic_t cancelling;
struct bpf_map *map;
struct bpf_prog *prog;
void __rcu *callback_fn;
@@ -1204,6 +1205,7 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map
t->map = map;
t->prog = NULL;
rcu_assign_pointer(t->callback_fn, NULL);
+ atomic_set(&t->cancelling, 0);
hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT);
t->timer.function = bpf_timer_cb;
WRITE_ONCE(timer->timer, t);
@@ -1331,7 +1333,8 @@ static void drop_prog_refcnt(struct bpf_hrtimer *t)
BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer)
{
- struct bpf_hrtimer *t;
+ struct bpf_hrtimer *t, *cur_t;
+ bool inc = false;
int ret = 0;
if (in_nmi())
@@ -1343,14 +1346,40 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer)
ret = -EINVAL;
goto out;
}
- if (this_cpu_read(hrtimer_running) == t) {
+ cur_t = this_cpu_read(hrtimer_running);
+ if (cur_t == t) {
/* If bpf callback_fn is trying to bpf_timer_cancel()
* its own timer the hrtimer_cancel() will deadlock
- * since it waits for callback_fn to finish
+ * since it waits for callback_fn to finish.
+ */
+ ret = -EDEADLK;
+ goto out;
+ }
+
+ /* Only account in-flight cancellations when invoked from a timer
+ * callback, since we want to avoid waiting only if other _callbacks_
+ * are waiting on us, to avoid introducing lockups. Non-callback paths
+ * are ok, since nobody would synchronously wait for their completion.
+ */
+ if (!cur_t)
+ goto drop;
+ atomic_inc(&t->cancelling);
+ /* Need full barrier after relaxed atomic_inc */
+ smp_mb__after_atomic();
+ inc = true;
+ if (atomic_read(&cur_t->cancelling)) {
+ /* We're cancelling timer t, while some other timer callback is
+ * attempting to cancel us. In such a case, it might be possible
+ * that timer t belongs to the other callback, or some other
+ * callback waiting upon it (creating transitive dependencies
+ * upon us), and we will enter a deadlock if we continue
+ * cancelling and waiting for it synchronously, since it might
+ * do the same. Bail!
*/
ret = -EDEADLK;
goto out;
}
+drop:
drop_prog_refcnt(t);
out:
__bpf_spin_unlock_irqrestore(&timer->lock);
@@ -1358,6 +1387,8 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer)
* if it was running.
*/
ret = ret ?: hrtimer_cancel(&t->timer);
+ if (inc)
+ atomic_dec(&t->cancelling);
rcu_read_unlock();
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0182/1887] bpf: Defer work in bpf_timer_cancel_and_free
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0181/1887] bpf: Fail bpf_timer_cancel when callback is being cancelled Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:37 ` [PATCH 6.1 0183/1887] ocfs2: Avoid touching renamed directory if parent does not change Greg Kroah-Hartman
` (816 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kumar Kartikeya Dwivedi,
Alexei Starovoitov, Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit a6fcd19d7eac1335eb76bc16b6a66b7f574d1d69 ]
Currently, the same case as previous patch (two timer callbacks trying
to cancel each other) can be invoked through bpf_map_update_elem as
well, or more precisely, freeing map elements containing timers. Since
this relies on hrtimer_cancel as well, it is prone to the same deadlock
situation as the previous patch.
It would be sufficient to use hrtimer_try_to_cancel to fix this problem,
as the timer cannot be enqueued after async_cancel_and_free. Once
async_cancel_and_free has been done, the timer must be reinitialized
before it can be armed again. The callback running in parallel trying to
arm the timer will fail, and freeing bpf_hrtimer without waiting is
sufficient (given kfree_rcu), and bpf_timer_cb will return
HRTIMER_NORESTART, preventing the timer from being rearmed again.
However, there exists a UAF scenario where the callback arms the timer
before entering this function, such that if cancellation fails (due to
timer callback invoking this routine, or the target timer callback
running concurrently). In such a case, if the timer expiration is
significantly far in the future, the RCU grace period expiration
happening before it will free the bpf_hrtimer state and along with it
the struct hrtimer, that is enqueued.
Hence, it is clear cancellation needs to occur after
async_cancel_and_free, and yet it cannot be done inline due to deadlock
issues. We thus modify bpf_timer_cancel_and_free to defer work to the
global workqueue, adding a work_struct alongside rcu_head (both used at
_different_ points of time, so can share space).
Update existing code comments to reflect the new state of affairs.
[ Backport to 6.1.y: mapped deferred cancellation onto the older pre-BPF-
workqueue timer object layout. ]
Fixes: b00628b1c7d5 ("bpf: Introduce bpf timers.")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20240709185440.1104957-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/helpers.c | 58 +++++++++++++++++++++++++++++++++++---------
1 file changed, 46 insertions(+), 12 deletions(-)
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index d5dcc172647c8..a5ab200c48663 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1115,7 +1115,10 @@ struct bpf_hrtimer {
struct bpf_prog *prog;
void __rcu *callback_fn;
void *value;
- struct rcu_head rcu;
+ union {
+ struct rcu_head rcu;
+ struct work_struct delete_work;
+ };
};
/* the actual struct hidden inside uapi struct bpf_timer */
@@ -1169,6 +1172,22 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
return HRTIMER_NORESTART;
}
+static void bpf_timer_delete_work(struct work_struct *work)
+{
+ struct bpf_hrtimer *t = container_of(work, struct bpf_hrtimer,
+ delete_work);
+
+ /* Cancel the timer and wait for callback to complete if it was running.
+ * If hrtimer_cancel() can be safely called it's safe to call
+ * kfree_rcu(t) right after for both preallocated and non-preallocated
+ * maps. The timer->timer = NULL was already done and no code path can see
+ * address 't' anymore. A timer armed before bpf_timer_cancel_and_free()
+ * will have been cancelled.
+ */
+ hrtimer_cancel(&t->timer);
+ kfree_rcu(t, rcu);
+}
+
BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map,
u64, flags)
{
@@ -1206,6 +1225,7 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map
t->prog = NULL;
rcu_assign_pointer(t->callback_fn, NULL);
atomic_set(&t->cancelling, 0);
+ INIT_WORK(&t->delete_work, bpf_timer_delete_work);
hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT);
t->timer.function = bpf_timer_cb;
WRITE_ONCE(timer->timer, t);
@@ -1426,14 +1446,8 @@ void bpf_timer_cancel_and_free(void *val)
__bpf_spin_unlock_irqrestore(&timer->lock);
if (!t)
return;
- /* Cancel the timer and wait for callback to complete if it was running.
- * If hrtimer_cancel() can be safely called it's safe to call kfree(t)
- * right after for both preallocated and non-preallocated maps.
- * The timer->timer = NULL was already done and no code path can
- * see address 't' anymore.
- *
- * Check that bpf_map_delete/update_elem() wasn't called from timer
- * callback_fn. In such case don't call hrtimer_cancel() (since it will
+ /* We check that bpf_map_delete/update_elem() was called from timer
+ * callback_fn. In such case we don't call hrtimer_cancel() (since it will
* deadlock) and don't call hrtimer_try_to_cancel() (since it will just
* return -1). Though callback_fn is still running on this cpu it's
* safe to do kfree(t) because bpf_timer_cb() read everything it needed
@@ -1441,10 +1455,30 @@ void bpf_timer_cancel_and_free(void *val)
* since timer->timer = NULL was already done. The timer will be
* effectively cancelled because bpf_timer_cb() will return
* HRTIMER_NORESTART.
+ *
+ * However, it is possible the timer callback_fn calling us armed the
+ * timer _before_ calling us, such that failing to cancel it here will
+ * cause it to possibly use struct hrtimer after freeing bpf_hrtimer.
+ * Therefore, we _need_ to cancel any outstanding timers before we do
+ * kfree_rcu, even though no more timers can be armed.
+ *
+ * Moreover, we need to schedule work even if timer does not belong to
+ * the calling callback_fn, as on two different CPUs, we can end up in a
+ * situation where both sides run in parallel, try to cancel one
+ * another, and we end up waiting on both sides in hrtimer_cancel
+ * without making forward progress, since timer1 depends on timer2
+ * callback to finish, and vice versa.
+ *
+ * CPU 1 (timer1_cb) CPU 2 (timer2_cb)
+ * bpf_timer_cancel_and_free(timer2) bpf_timer_cancel_and_free(timer1)
+ *
+ * To avoid these issues, punt to workqueue context when we are in a
+ * timer callback.
*/
- if (this_cpu_read(hrtimer_running) != t)
- hrtimer_cancel(&t->timer);
- kfree_rcu(t, rcu);
+ if (this_cpu_read(hrtimer_running))
+ queue_work(system_unbound_wq, &t->delete_work);
+ else
+ bpf_timer_delete_work(&t->delete_work);
}
BPF_CALL_2(bpf_kptr_xchg, void *, map_value, void *, ptr)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0183/1887] ocfs2: Avoid touching renamed directory if parent does not change
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0182/1887] bpf: Defer work in bpf_timer_cancel_and_free Greg Kroah-Hartman
@ 2026-10-28 16:37 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0184/1887] net/mlx5e: Fix netif state handling Greg Kroah-Hartman
` (815 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Kara, Al Viro, Artem Dinaburg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
[ Upstream commit 9d618d19b29c2943527e3a43da0a35aea91062fc ]
The VFS will not be locking moved directory if its parent does not
change. Change ocfs2 rename code to avoid touching renamed directory if
its parent does not change as without locking that can corrupt the
filesystem.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/namei.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 62f9d976c8fb3..60770904b243b 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1340,7 +1340,7 @@ static int ocfs2_rename(struct user_namespace *mnt_userns,
goto bail;
}
- if (S_ISDIR(old_inode->i_mode)) {
+ if (S_ISDIR(old_inode->i_mode) && new_dir != old_dir) {
u64 old_inode_parent;
update_dot_dot = 1;
@@ -1357,8 +1357,7 @@ static int ocfs2_rename(struct user_namespace *mnt_userns,
goto bail;
}
- if (!new_inode && new_dir != old_dir &&
- new_dir->i_nlink >= ocfs2_link_max(osb)) {
+ if (!new_inode && new_dir->i_nlink >= ocfs2_link_max(osb)) {
status = -EMLINK;
goto bail;
}
@@ -1601,6 +1600,9 @@ static int ocfs2_rename(struct user_namespace *mnt_userns,
if (update_dot_dot) {
status = ocfs2_update_entry(old_inode, handle,
&old_inode_dot_dot_res, new_dir);
+ }
+
+ if (S_ISDIR(old_inode->i_mode)) {
drop_nlink(old_dir);
if (new_inode) {
drop_nlink(new_inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0184/1887] net/mlx5e: Fix netif state handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-10-28 16:37 ` [PATCH 6.1 0183/1887] ocfs2: Avoid touching renamed directory if parent does not change Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0185/1887] net: ena: Add validation for completion descriptors consistency Greg Kroah-Hartman
` (814 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shay Drory, Tariq Toukan,
Simon Horman, Jakub Kicinski, Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <shayd@nvidia.com>
[ Upstream commit 3d5918477f94e4c2f064567875c475468e264644 ]
mlx5e_suspend cleans resources only if netif_device_present() returns
true. However, mlx5e_resume changes the state of netif, via
mlx5e_nic_enable, only if reg_state == NETREG_REGISTERED.
In the below case, the above leads to NULL-ptr Oops[1] and memory
leaks:
mlx5e_probe
_mlx5e_resume
mlx5e_attach_netdev
mlx5e_nic_enable <-- netdev not reg, not calling netif_device_attach()
register_netdev <-- failed for some reason.
ERROR_FLOW:
_mlx5e_suspend <-- netif_device_present return false, resources aren't freed :(
Hence, clean resources in this case as well.
[1]
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 0 P4D 0
Oops: 0010 [#1] SMP
CPU: 2 PID: 9345 Comm: test-ovs-ct-gen Not tainted 6.5.0_for_upstream_min_debug_2023_09_05_16_01 #1
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:0x0
Code: Unable to access opcode bytes at0xffffffffffffffd6.
RSP: 0018:ffff888178aaf758 EFLAGS: 00010246
Call Trace:
<TASK>
? __die+0x20/0x60
? page_fault_oops+0x14c/0x3c0
? exc_page_fault+0x75/0x140
? asm_exc_page_fault+0x22/0x30
notifier_call_chain+0x35/0xb0
blocking_notifier_call_chain+0x3d/0x60
mlx5_blocking_notifier_call_chain+0x22/0x30 [mlx5_core]
mlx5_core_uplink_netdev_event_replay+0x3e/0x60 [mlx5_core]
mlx5_mdev_netdev_track+0x53/0x60 [mlx5_ib]
mlx5_ib_roce_init+0xc3/0x340 [mlx5_ib]
__mlx5_ib_add+0x34/0xd0 [mlx5_ib]
mlx5r_probe+0xe1/0x210 [mlx5_ib]
? auxiliary_match_id+0x6a/0x90
auxiliary_bus_probe+0x38/0x80
? driver_sysfs_add+0x51/0x80
really_probe+0xc9/0x3e0
? driver_probe_device+0x90/0x90
__driver_probe_device+0x80/0x160
driver_probe_device+0x1e/0x90
__device_attach_driver+0x7d/0x100
bus_for_each_drv+0x80/0xd0
__device_attach+0xbc/0x1f0
bus_probe_device+0x86/0xa0
device_add+0x637/0x840
__auxiliary_device_add+0x3b/0xa0
add_adev+0xc9/0x140 [mlx5_core]
mlx5_rescan_drivers_locked+0x22a/0x310 [mlx5_core]
mlx5_register_device+0x53/0xa0 [mlx5_core]
mlx5_init_one_devl_locked+0x5c4/0x9c0 [mlx5_core]
mlx5_init_one+0x3b/0x60 [mlx5_core]
probe_one+0x44c/0x730 [mlx5_core]
local_pci_probe+0x3e/0x90
pci_device_probe+0xbf/0x210
? kernfs_create_link+0x5d/0xa0
? sysfs_do_create_link_sd+0x60/0xc0
really_probe+0xc9/0x3e0
? driver_probe_device+0x90/0x90
__driver_probe_device+0x80/0x160
driver_probe_device+0x1e/0x90
__device_attach_driver+0x7d/0x100
bus_for_each_drv+0x80/0xd0
__device_attach+0xbc/0x1f0
pci_bus_add_device+0x54/0x80
pci_iov_add_virtfn+0x2e6/0x320
sriov_enable+0x208/0x420
mlx5_core_sriov_configure+0x9e/0x200 [mlx5_core]
sriov_numvfs_store+0xae/0x1a0
kernfs_fop_write_iter+0x10c/0x1a0
vfs_write+0x291/0x3c0
ksys_write+0x5f/0xe0
do_syscall_64+0x3d/0x90
entry_SYSCALL_64_after_hwframe+0x46/0xb0
CR2: 0000000000000000
---[ end trace 0000000000000000 ]---
[ Backport to 6.1.y: added an internal suspend helper so probe unwind
cleans resources without changing the registered-device suspend path. ]
Fixes: 2c3b5beec46a ("net/mlx5e: More generic netdev management API")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240509112951.590184-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 2d0b57583ea35..d26c36479ee91 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5896,13 +5896,14 @@ static int mlx5e_resume(struct auxiliary_device *adev)
return 0;
}
-static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
+static int mlx5e_suspend_common(struct auxiliary_device *adev,
+ bool pre_netdev_reg)
{
struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev;
- if (!netif_device_present(netdev)) {
+ if (!pre_netdev_reg && !netif_device_present(netdev)) {
if (test_bit(MLX5E_STATE_DESTROYING, &priv->state))
mlx5e_destroy_mdev_resources(mdev);
return -ENODEV;
@@ -5913,6 +5914,11 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
return 0;
}
+static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
+{
+ return mlx5e_suspend_common(adev, false);
+}
+
static int mlx5e_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
@@ -5920,7 +5926,6 @@ static int mlx5e_probe(struct auxiliary_device *adev,
const struct mlx5e_profile *profile = &mlx5e_nic_profile;
struct mlx5_core_dev *mdev = edev->mdev;
struct net_device *netdev;
- pm_message_t state = {};
struct mlx5e_priv *priv;
int err;
@@ -5969,7 +5974,7 @@ static int mlx5e_probe(struct auxiliary_device *adev,
return 0;
err_resume:
- mlx5e_suspend(adev, state);
+ mlx5e_suspend_common(adev, true);
err_profile_cleanup:
profile->cleanup(priv);
err_devlink_cleanup:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0185/1887] net: ena: Add validation for completion descriptors consistency
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0184/1887] net/mlx5e: Fix netif state handling Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0186/1887] x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client Greg Kroah-Hartman
` (813 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shahar Itzko, David Arinzon,
Simon Horman, Jakub Kicinski, Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Arinzon <darinzon@amazon.com>
[ Upstream commit b37b98a3a0c1198bafe8c2d9ce0bc845b4e7a9a7 ]
Validate that `first` flag is set only for the first
descriptor in multi-buffer packets.
In case of an invalid descriptor, a reset will occur.
A new reset reason for RX data corruption has been added.
Signed-off-by: Shahar Itzko <itzko@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240512134637.25299-4-darinzon@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amazon/ena/ena_eth_com.c | 37 ++++++++++++++-----
drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +
.../net/ethernet/amazon/ena/ena_regs_defs.h | 1 +
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index 933e619b3a313..4c6e07aa4bbb5 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -229,30 +229,43 @@ static struct ena_eth_io_rx_cdesc_base *
idx * io_cq->cdesc_entry_size_in_bytes);
}
-static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
- u16 *first_cdesc_idx)
+static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+ u16 *first_cdesc_idx,
+ u16 *num_descs)
{
+ u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
struct ena_eth_io_rx_cdesc_base *cdesc;
- u16 count = 0, head_masked;
u32 last = 0;
do {
+ u32 status;
+
cdesc = ena_com_get_next_rx_cdesc(io_cq);
if (!cdesc)
break;
+ status = READ_ONCE(cdesc->status);
ena_com_cq_inc_head(io_cq);
+ if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
+ ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
+ struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);
+
+ netdev_err(dev->net_device,
+ "First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
+ count, io_cq->qid, cdesc->req_id);
+ return -EFAULT;
+ }
count++;
- last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
- ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
+ last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
+ ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
} while (!last);
if (last) {
*first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
- count += io_cq->cur_rx_pkt_cdesc_count;
head_masked = io_cq->head & (io_cq->q_depth - 1);
+ *num_descs = count;
io_cq->cur_rx_pkt_cdesc_count = 0;
io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
@@ -260,11 +273,11 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
"ENA q_id: %d packets were completed. first desc idx %u descs# %d\n",
io_cq->qid, *first_cdesc_idx, count);
} else {
- io_cq->cur_rx_pkt_cdesc_count += count;
- count = 0;
+ io_cq->cur_rx_pkt_cdesc_count = count;
+ *num_descs = 0;
}
- return count;
+ return 0;
}
static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
u16 cdesc_idx = 0;
u16 nb_hw_desc;
u16 i = 0;
+ int rc;
WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
- nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
+ rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
+ if (unlikely(rc != 0))
+ return -EFAULT;
+
if (nb_hw_desc == 0) {
ena_rx_ctx->descs = nb_hw_desc;
return 0;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 9e92ccf13419f..b46bf8bf06605 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -1853,6 +1853,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
if (rc == -ENOSPC) {
ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
+ } else if (rc == -EFAULT) {
+ ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
} else {
ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
&rx_ring->syncp);
diff --git a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
index 1e007a41a5256..23466d62fbc5c 100644
--- a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
@@ -21,6 +21,7 @@ enum ena_regs_reset_reason_types {
ENA_REGS_RESET_USER_TRIGGER = 12,
ENA_REGS_RESET_GENERIC = 13,
ENA_REGS_RESET_MISS_INTERRUPT = 14,
+ ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED = 16,
};
/* ena_registers offsets */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0186/1887] x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0185/1887] net: ena: Add validation for completion descriptors consistency Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0187/1887] wifi: cfg80211: avoid double free if updating BSS fails Greg Kroah-Hartman
` (812 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello,
Borislav Petkov (AMD), Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <mario.limonciello@amd.com>
[ Upstream commit a5ca1dc46a6b610dd4627d8b633d6c84f9724ef0 ]
A number of Zen4 client SoCs advertise the ability to use virtualized
VMLOAD/VMSAVE, but using these instructions is reported to be a cause
of a random host reboot.
These instructions aren't intended to be advertised on Zen4 client
so clear the capability.
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=219009
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/cpu/amd.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index a61606a614bd7..8d9c067992e5f 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1161,6 +1161,17 @@ static void init_amd_zen3(struct cpuinfo_x86 *c)
static void init_amd_zen4(struct cpuinfo_x86 *c)
{
init_amd_zen_common();
+
+ /*
+ * These Zen4 SoCs advertise support for virtualized VMLOAD/VMSAVE
+ * in some BIOS versions but they can lead to random host reboots.
+ */
+ switch (c->x86_model) {
+ case 0x18 ... 0x1f:
+ case 0x60 ... 0x7f:
+ clear_cpu_cap(c, X86_FEATURE_V_VMSAVE_VMLOAD);
+ break;
+ }
}
static void init_amd(struct cpuinfo_x86 *c)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0187/1887] wifi: cfg80211: avoid double free if updating BSS fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0186/1887] x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0188/1887] drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs Greg Kroah-Hartman
` (811 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Berg, Johannes Berg,
Miri Korenblit, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <benjamin.berg@intel.com>
[ Upstream commit acc44cbd7727115f9381c35c2898b1b5af665ec8 ]
cfg80211_update_known_bss will always consume the passed IEs. As such,
cfg80211_update_assoc_bss_entry also needs to always set the pointers to
NULL so that no double free can occur.
Note that hitting this would probably require being connected to a
hidden BSS which is then doing a channel switch while also switching to
be not hidden anymore at the same time.
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20231220133549.8891edb28d51.Id09c5145363e990ff5237decd58296302e2d53c8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/scan.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index ecf9021219380..a8901e07e96d6 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -2695,10 +2695,9 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
if (new) {
/* to save time, update IEs for transmitting bss only */
- if (cfg80211_update_known_bss(rdev, cbss, new, false)) {
- new->pub.proberesp_ies = NULL;
- new->pub.beacon_ies = NULL;
- }
+ cfg80211_update_known_bss(rdev, cbss, new, false);
+ new->pub.proberesp_ies = NULL;
+ new->pub.beacon_ies = NULL;
list_for_each_entry_safe(nontrans_bss, tmp,
&new->pub.nontrans_list,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0188/1887] drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0187/1887] wifi: cfg80211: avoid double free if updating BSS fails Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0189/1887] rds_tcp: close NULL deref window in rds_tcp_set_callbacks Greg Kroah-Hartman
` (810 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Konrad Dybcio, Rob Clark,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <konrad.dybcio@linaro.org>
[ Upstream commit 16007768551d5bfe53426645401435ca8d2ef54f ]
There are some cases, such as the one uncovered by Commit 46d4efcccc68
("drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails")
where
msm_gpu_cleanup() : platform_set_drvdata(gpu->pdev, NULL);
is called on gpu->pdev == NULL, as the GPU device has not been fully
initialized yet.
Turns out that there's more than just the aforementioned path that
causes this to happen (e.g. the case when there's speedbin data in the
catalog, but opp-supported-hw is missing in DT).
Assigning msm_gpu->pdev earlier seems like the least painful solution
to this, therefore do so.
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/602742/
Signed-off-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 ++
drivers/gpu/drm/msm/msm_gpu.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 396f12b550479..8ff98efb0e8d8 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -1052,6 +1052,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu->revn = adreno_gpu->info->revn;
adreno_gpu->rev = *rev;
+ gpu->pdev = pdev;
+
if (adreno_read_speedbin(dev, &speedbin) || !speedbin)
speedbin = 0xffff;
adreno_gpu->speedbin = (uint16_t) (0xffff & speedbin);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 3802495003258..9385419a78dbf 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -938,7 +938,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
gpu->cx_collapse = devm_reset_control_get_optional_exclusive(&pdev->dev,
"cx_collapse");
- gpu->pdev = pdev;
platform_set_drvdata(pdev, &gpu->adreno_smmu);
msm_devfreq_init(gpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0189/1887] rds_tcp: close NULL deref window in rds_tcp_set_callbacks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0188/1887] drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0190/1887] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
` (809 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Simon Horman, Maoyi Xie,
Allison Henderson, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maoyi Xie <maoyixie.tju@gmail.com>
commit d2bfdbb69cf87676981b1043010b6224d84c6d3a upstream.
rds_tcp_set_callbacks() links a new rds_tcp_connection onto
rds_tcp_tc_list under rds_tcp_tc_list_lock. It releases the
lock, then assigns tc->t_sock = sock outside the lock.
rds_tcp_tc_info() and rds6_tcp_tc_info() walk rds_tcp_tc_list
under the same lock. Both dereference tc->t_sock->sk without
a NULL check.
A reader can acquire rds_tcp_tc_list_lock between the writer's
spin_unlock and the t_sock store. It then sees a list entry
whose t_sock is NULL. The dereference of tc->t_sock->sk is a
NULL access.
Move tc->t_sock = sock inside rds_tcp_tc_list_lock, before
list_add_tail. A reader holding the lock then observes the
linkage and the t_sock store together.
The restore path is safe. rds_tcp_restore_callbacks() does
list_del_init inside the lock. The matching tc->t_sock = NULL
after unlink is harmless to readers holding the lock.
Fixes: 70041088e3b9 ("RDS: Add TCP transport to RDS")
Suggested-by: Simon Horman <horms@kernel.org>
Signed-off-by: Maoyi Xie <maoyi.xie@ntu.edu.sg>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260512142807.1855619-1-maoyi.xie@ntu.edu.sg
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ achender: resolved context conflict; tc->t_rtn initialization is not
present in this tree ]
Signed-off-by: Allison Henderson <achender@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/tcp.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 397953c3048dc..ef7cf0a6cb134 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -231,16 +231,19 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp)
rdsdebug("setting sock %p callbacks to tc %p\n", sock, tc);
write_lock_bh(&sock->sk->sk_callback_lock);
- /* done under the callback_lock to serialize with write_space */
+ /* done under the callback_lock to serialize with write_space.
+ * Set t_sock inside rds_tcp_tc_list_lock so readers walking
+ * rds_tcp_tc_list under the same lock cannot observe an
+ * entry whose t_sock is NULL.
+ */
spin_lock(&rds_tcp_tc_list_lock);
+ tc->t_sock = sock;
list_add_tail(&tc->t_list_item, &rds_tcp_tc_list);
spin_unlock(&rds_tcp_tc_list_lock);
/* accepted sockets need our listen data ready undone */
if (sock->sk->sk_data_ready == rds_tcp_listen_data_ready)
sock->sk->sk_data_ready = sock->sk->sk_user_data;
-
- tc->t_sock = sock;
tc->t_cpath = cp;
tc->t_orig_data_ready = sock->sk->sk_data_ready;
tc->t_orig_write_space = sock->sk->sk_write_space;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0190/1887] vxlan: use one headroom snapshot for neighbour replies
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0189/1887] rds_tcp: close NULL deref window in rds_tcp_set_callbacks Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0191/1887] drm/amd/display: Validate function returns Greg Kroah-Hartman
` (808 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sanghyun Park, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
[ Upstream commit 481506a756dcd828ef42391cb08f38d8d96d38fc ]
vxlan_na_create() samples LL_RESERVED_SPACE() to size the reply skb and then
samples it again to reserve headroom. A concurrent vxlan_changelink() can
update needed_headroom between the two reads, creating a TOCTOU race. The
second value can exceed the allocation and make the Ethernet header write out
of bounds.
The race is reproducible on the unpatched kernel. It occurred when
vxlan_na_create() generated a neighbour reply while vxlan_changelink() changed
the link headroom. KASAN caught a four-byte write two bytes beyond a 704-byte
skbuff_small_head allocation.
Snapshot the headroom once and use that value for both allocation and
reservation.
Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()")
Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
Link: https://patch.msgid.link/20260918032842.502409-2-sanghyun.park.cnu@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 591a2875dfe2f..c9f02da4c8af8 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -2000,13 +2000,15 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
struct ipv6hdr *pip6;
u8 *daddr;
int na_olen = 8; /* opt hdr + ETH_ALEN for target */
+ int headroom;
int ns_olen;
int i, len;
if (dev == NULL || !pskb_may_pull(request, request->len))
return NULL;
- len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) +
+ headroom = LL_RESERVED_SPACE(dev);
+ len = headroom + sizeof(struct ipv6hdr) +
sizeof(*na) + na_olen + dev->needed_tailroom;
reply = alloc_skb(len, GFP_ATOMIC);
if (reply == NULL)
@@ -2014,7 +2016,7 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
reply->protocol = htons(ETH_P_IPV6);
reply->dev = dev;
- skb_reserve(reply, LL_RESERVED_SPACE(request->dev));
+ skb_reserve(reply, headroom);
skb_push(reply, sizeof(struct ethhdr));
skb_reset_mac_header(reply);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0191/1887] drm/amd/display: Validate function returns
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0190/1887] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0192/1887] drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability Greg Kroah-Hartman
` (807 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harry Wentland, Alex Hung,
Daniel Wheeler, Alex Deucher, Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit 673f816b9e1e92d1f70e1bf5f21b531e0ff9ad6c ]
[WHAT & HOW]
Function return values must be checked before data can be used
in subsequent functions.
This fixes 4 CHECKED_RETURN issues reported by Coverity.
[ Backport to 6.1.y: adapted the visual-panel, watermark, and
link-detection checks to their older locations. The upstream DMUB
run-list/D3 path is absent; the older dc_dmub_srv_cmd_queue() already
checks and logs idle-wait failures but, unlike upstream, still retries
the queue once afterwards. No DMUB queue change is included. ]
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 3 +--
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 3 ++-
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 3 ++-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 82b747c0ed693..1d3d9a82c4637 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2808,8 +2808,7 @@ bool perform_link_training_with_retries(
if (status == LINK_TRAINING_ABORT) {
enum dc_connection_type type = dc_connection_none;
- dc_link_detect_sink(link, &type);
- if (type == dc_connection_none) {
+ if (dc_link_detect_sink(link, &type) && type == dc_connection_none) {
DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__);
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 31bb7e782c6b1..35e8f22d30204 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -396,7 +396,8 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi
enum dmub_status status;
unsigned int panel_inst = 0;
- dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst);
+ if (!dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst))
+ return;
memset(&cmd, 0, sizeof(cmd));
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index aacb1fb5c73eb..d2eebe39a55e3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -595,7 +595,8 @@ static bool hubbub2_program_watermarks(
hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false)
safe_to_lower = true;
- hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
+ if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
+ wm_pending = true;
REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0192/1887] drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0191/1887] drm/amd/display: Validate function returns Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0193/1887] drm/i915/hdcp: Add encoder check in hdcp2_get_capability Greg Kroah-Hartman
` (806 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Suraj Kandpal, Dnyaneshwar Bhadane,
Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Kandpal <suraj.kandpal@intel.com>
[ Upstream commit 31b42af516afa1e184d1a9f9dd4096c54044269a ]
Sometimes during hotplug scenario or suspend/resume scenario encoder is
not always initialized when intel_hdcp_get_capability add
a check to avoid kernel null pointer dereference.
[ Backport to 6.1.y: this tree uses the older intel_hdcp_capable()
helper name. Apply the same guard there; the code change is otherwise
unchanged. ]
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240722064451.3610512-2-suraj.kandpal@intel.com
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_hdcp.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index cb7f86de967a8..507721c94f2fd 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -182,11 +182,16 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port,
/* Is HDCP1.4 capable on Platform and Sink */
bool intel_hdcp_capable(struct intel_connector *connector)
{
- struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+ struct intel_digital_port *dig_port;
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
bool capable = false;
u8 bksv[5];
+ if (!intel_attached_encoder(connector))
+ return capable;
+
+ dig_port = intel_attached_dig_port(connector);
+
if (!shim)
return capable;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0193/1887] drm/i915/hdcp: Add encoder check in hdcp2_get_capability
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0192/1887] drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0194/1887] drm/mediatek: Fix potential NULL dereference in mtk_crtc_destroy() Greg Kroah-Hartman
` (805 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Suraj Kandpal, Dnyaneshwar Bhadane,
Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Kandpal <suraj.kandpal@intel.com>
[ Upstream commit d34f4f058edf1235c103ca9c921dc54820d14d40 ]
Add encoder check in intel_hdcp2_get_capability to avoid
null pointer error.
[ Backport to 6.1.y: upstream adds the check in the DP shim's
intel_dp_hdcp2_get_capability(), which does not exist here. This tree
predates the intel_connector conversion of the shims: its
intel_dp_hdcp2_capable() takes a digital port, and the
intel_attached_dig_port() lookup is still done in the common
intel_hdcp2_capable() helper. Put the same encoder guard there, before
that lookup, and return false through the bool API when no encoder is
attached. ]
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240722064451.3610512-3-suraj.kandpal@intel.com
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_hdcp.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 507721c94f2fd..d31c1f1f0e507 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -208,11 +208,16 @@ bool intel_hdcp_capable(struct intel_connector *connector)
/* Is HDCP2.2 capable on Platform and Sink */
bool intel_hdcp2_capable(struct intel_connector *connector)
{
- struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+ struct intel_digital_port *dig_port;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
bool capable = false;
+ if (!intel_attached_encoder(connector))
+ return capable;
+
+ dig_port = intel_attached_dig_port(connector);
+
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0194/1887] drm/mediatek: Fix potential NULL dereference in mtk_crtc_destroy()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0193/1887] drm/i915/hdcp: Add encoder check in hdcp2_get_capability Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0195/1887] kvm: s390: Reject memory region operations for ucontrol VMs Greg Kroah-Hartman
` (804 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter,
AngeloGioacchino Del Regno, CK Hu, Chun-Kuang Hu, Artem Dinaburg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@linaro.org>
[ Upstream commit 4018651ba5c409034149f297d3dd3328b91561fd ]
In mtk_crtc_create(), if the call to mbox_request_channel() fails then we
set the "mtk_crtc->cmdq_client.chan" pointer to NULL. In that situation,
we do not call cmdq_pkt_create().
During the cleanup, we need to check if the "mtk_crtc->cmdq_client.chan"
is NULL first before calling cmdq_pkt_destroy(). Calling
cmdq_pkt_destroy() is unnecessary if we didn't call cmdq_pkt_create() and
it will result in a NULL pointer dereference.
[ Backport to 6.1.y: used the older Mediatek CRTC file and helper names. ]
Fixes: 7627122fd1c0 ("drm/mediatek: Add cmdq_handle in mtk_crtc")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.kernel.org/project/dri-devel/patch/cc537bd6-837f-4c85-a37b-1a007e268310@stanley.mountain/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 59b310f7327c8..8e72b3bb51eb9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -161,9 +161,8 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
mtk_mutex_put(mtk_crtc->mutex);
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
-
if (mtk_crtc->cmdq_client.chan) {
+ mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
mbox_free_channel(mtk_crtc->cmdq_client.chan);
mtk_crtc->cmdq_client.chan = NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0195/1887] kvm: s390: Reject memory region operations for ucontrol VMs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0194/1887] drm/mediatek: Fix potential NULL dereference in mtk_crtc_destroy() Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0196/1887] media: av7110: fix a spectre vulnerability Greg Kroah-Hartman
` (803 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Schlameuss,
Claudio Imbrenda, Janosch Frank, Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Schlameuss <schlameuss@linux.ibm.com>
[ Upstream commit 7816e58967d0e6cadce05c8540b47ed027dc2499 ]
This change rejects the KVM_SET_USER_MEMORY_REGION and
KVM_SET_USER_MEMORY_REGION2 ioctls when called on a ucontrol VM.
This is necessary since ucontrol VMs have kvm->arch.gmap set to 0 and
would thus result in a null pointer dereference further in.
Memory management needs to be performed in userspace and using the
ioctls KVM_S390_UCAS_MAP and KVM_S390_UCAS_UNMAP.
Also improve s390 specific documentation for KVM_SET_USER_MEMORY_REGION
and KVM_SET_USER_MEMORY_REGION2.
[ Backport to 6.1.y: omitted KVM_SET_USER_MEMORY_REGION2 documentation
because that ioctl is absent from 6.1. ]
Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Fixes: 27e0393f15fc ("KVM: s390: ucontrol: per vcpu address spaces")
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Link: https://lore.kernel.org/r/20240624095902.29375-1-schlameuss@linux.ibm.com
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
[frankja@linux.ibm.com: commit message spelling fix, subject prefix fix]
Message-ID: <20240624095902.29375-1-schlameuss@linux.ibm.com>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/virt/kvm/api.rst | 6 ++++++
arch/s390/kvm/kvm-s390.c | 3 +++
2 files changed, 9 insertions(+)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 1bc61bf804f1f..1f0f84501e59c 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -1382,6 +1382,12 @@ The KVM_SET_MEMORY_REGION does not allow fine grained control over memory
allocation and is deprecated.
+S390:
+^^^^^
+
+Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set.
+Returns -EINVAL if called on a protected VM.
+
4.36 KVM_SET_TSS_ADDR
---------------------
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 9b9d8d37bcc41..0d4a05f3cdd93 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -5587,6 +5587,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
{
gpa_t size;
+ if (kvm_is_ucontrol(kvm))
+ return -EINVAL;
+
/* When we are protected, we should not change the memory slots */
if (kvm_s390_pv_get_handle(kvm))
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0196/1887] media: av7110: fix a spectre vulnerability
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0195/1887] kvm: s390: Reject memory region operations for ucontrol VMs Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0197/1887] ethtool: fail closed if we cant get max channel used in indirection tables Greg Kroah-Hartman
` (802 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mauro Carvalho Chehab,
Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
[ Upstream commit 458ea1c0be991573ec436aa0afa23baacfae101a ]
As warned by smatch:
drivers/staging/media/av7110/av7110_ca.c:270 dvb_ca_ioctl() warn: potential spectre issue 'av7110->ci_slot' [w] (local cap)
There is a spectre-related vulnerability at the code. Fix it.
[ Backport to 6.1.y: added the explicit linux/nospec.h include required
by the older source. ]
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../media/deprecated/saa7146/av7110/av7110.h | 4 ++-
.../deprecated/saa7146/av7110/av7110_ca.c | 26 +++++++++++++------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110.h
index 9fde69b38f1ce..c2956c23d9c1e 100644
--- a/drivers/staging/media/deprecated/saa7146/av7110/av7110.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110.h
@@ -86,6 +86,8 @@ struct infrared {
u32 ir_config;
};
+#define MAX_CI_SLOTS 2
+
/* place to store all the necessary device information */
struct av7110 {
@@ -166,7 +168,7 @@ struct av7110 {
/* CA */
- struct ca_slot_info ci_slot[2];
+ struct ca_slot_info ci_slot[MAX_CI_SLOTS];
enum av7110_video_mode vidmode;
struct dmxdev dmxdev;
diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c
index c1338e074a3dc..642af03fbac81 100644
--- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c
@@ -12,6 +12,7 @@
*/
#include <linux/kernel.h>
+#include <linux/nospec.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/fs.h>
@@ -26,23 +27,28 @@
void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
{
+ unsigned slot_num;
+
dprintk(8, "av7110:%p\n",av7110);
if (len < 3)
return;
switch (data[0]) {
case CI_MSG_CI_INFO:
- if (data[2] != 1 && data[2] != 2)
+ if (data[2] != 1 && data[2] != MAX_CI_SLOTS)
break;
+
+ slot_num = array_index_nospec(data[2] - 1, MAX_CI_SLOTS);
+
switch (data[1]) {
case 0:
- av7110->ci_slot[data[2] - 1].flags = 0;
+ av7110->ci_slot[slot_num].flags = 0;
break;
case 1:
- av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT;
+ av7110->ci_slot[slot_num].flags |= CA_CI_MODULE_PRESENT;
break;
case 2:
- av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY;
+ av7110->ci_slot[slot_num].flags |= CA_CI_MODULE_READY;
break;
}
break;
@@ -264,15 +270,19 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
case CA_GET_SLOT_INFO:
{
struct ca_slot_info *info=(struct ca_slot_info *)parg;
+ unsigned int slot_num;
if (info->num < 0 || info->num > 1) {
mutex_unlock(&av7110->ioctl_mutex);
return -EINVAL;
}
- av7110->ci_slot[info->num].num = info->num;
- av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
- CA_CI_LINK : CA_CI;
- memcpy(info, &av7110->ci_slot[info->num], sizeof(struct ca_slot_info));
+ slot_num = array_index_nospec(info->num, MAX_CI_SLOTS);
+
+ av7110->ci_slot[slot_num].num = info->num;
+ av7110->ci_slot[slot_num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
+ CA_CI_LINK : CA_CI;
+ memcpy(info, &av7110->ci_slot[slot_num],
+ sizeof(struct ca_slot_info));
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0197/1887] ethtool: fail closed if we cant get max channel used in indirection tables
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0196/1887] media: av7110: fix a spectre vulnerability Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0198/1887] nvme-fabrics: use reserved tag for reg read/write command Greg Kroah-Hartman
` (801 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jacob Keller, Jakub Kicinski,
Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 2899d58462ba868287d6ff3acad3675e7adf934f ]
Commit 0d1b7d6c9274 ("bnxt: fix crashes when reducing ring count with
active RSS contexts") proves that allowing indirection table to contain
channels with out of bounds IDs may lead to crashes. Currently the
max channel check in the core gets skipped if driver can't fetch
the indirection table or when we can't allocate memory.
Both of those conditions should be extremely rare but if they do
happen we should try to be safe and fail the channel change.
[ Backport to 6.1.y: kept the older int-returning
ethtool_get_max_rxfh_channel() and propagated its errors at both
channel-change call sites instead of the upstream u32/U32_MAX
conversion. A failure now returns the helper's errno (-ENOMEM or the
driver's get_rxfh() error) rather than -EINVAL, and -EOPNOTSUPP also
fails closed; on 6.1 IFF_RXFH_CONFIGURED can only be set via set_rxfh
paths that require a non-zero indirection table size. ]
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20240710174043.754664-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ethtool/channels.c | 9 ++++++---
net/ethtool/ioctl.c | 11 +++++++----
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/ethtool/channels.c b/net/ethtool/channels.c
index 4031588620115..05f3068ec0fe3 100644
--- a/net/ethtool/channels.c
+++ b/net/ethtool/channels.c
@@ -191,9 +191,12 @@ int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info)
/* ensure the new Rx count fits within the configured Rx flow
* indirection table settings
*/
- if (netif_is_rxfh_configured(dev) &&
- !ethtool_get_max_rxfh_channel(dev, &max_rx_in_use) &&
- (channels.combined_count + channels.rx_count) <= max_rx_in_use) {
+ if (netif_is_rxfh_configured(dev)) {
+ ret = ethtool_get_max_rxfh_channel(dev, &max_rx_in_use);
+ if (ret)
+ goto out_ops;
+ }
+ if (channels.combined_count + channels.rx_count <= max_rx_in_use) {
ret = -EINVAL;
GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing indirection table settings");
goto out_ops;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 1f64ff5f3f21c..439871dd1ca83 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1832,10 +1832,13 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
/* ensure the new Rx count fits within the configured Rx flow
* indirection table settings */
- if (netif_is_rxfh_configured(dev) &&
- !ethtool_get_max_rxfh_channel(dev, &max_rx_in_use) &&
- (channels.combined_count + channels.rx_count) <= max_rx_in_use)
- return -EINVAL;
+ if (netif_is_rxfh_configured(dev)) {
+ ret = ethtool_get_max_rxfh_channel(dev, &max_rx_in_use);
+ if (ret)
+ return ret;
+ }
+ if (channels.combined_count + channels.rx_count <= max_rx_in_use)
+ return -EINVAL;
/* Disabling channels, query zero-copy AF_XDP sockets */
from_channel = channels.combined_count +
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0198/1887] nvme-fabrics: use reserved tag for reg read/write command
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0197/1887] ethtool: fail closed if we cant get max channel used in indirection tables Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0199/1887] of/irq: add missing of_node_put() for interrupt parent node Greg Kroah-Hartman
` (800 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chunguang Xu, Sagi Grimberg,
Chaitanya Kulkarni, Christoph Hellwig, Keith Busch,
Artem Dinaburg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunguang Xu <chunguang.xu@shopee.com>
[ Upstream commit 7dc3bfcb4c9cc58970fff6aaa48172cb224d85aa ]
In some scenarios, if too many commands are issued by nvme command in
the same time by user tasks, this may exhaust all tags of admin_q. If
a reset (nvme reset or IO timeout) occurs before these commands finish,
reconnect routine may fail to update nvme regs due to insufficient tags,
which will cause kernel hang forever. In order to workaround this issue,
maybe we can let reg_read32()/reg_read64()/reg_write32() use reserved
tags. This maybe safe for nvmf:
1. For the disable ctrl path, we will not issue connect command
2. For the enable ctrl / fw activate path, since connect and reg_xx()
are called serially.
So the reserved tags may still be enough while reg_xx() use reserved tags.
Signed-off-by: Chunguang Xu <chunguang.xu@shopee.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Backport to 6.1.y: used the older BLK_MQ_REQ_RESERVED request flag. ]
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/fabrics.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index eed78e6f2cdf6..c4d58e5f3ea7b 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -153,7 +153,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
cmd.prop_get.offset = cpu_to_le32(off);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
- NVME_QID_ANY, 0, 0);
+ NVME_QID_ANY, 0, BLK_MQ_REQ_RESERVED);
if (ret >= 0)
*val = le64_to_cpu(res.u64);
@@ -199,7 +199,7 @@ int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
cmd.prop_get.offset = cpu_to_le32(off);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, &res, NULL, 0,
- NVME_QID_ANY, 0, 0);
+ NVME_QID_ANY, 0, BLK_MQ_REQ_RESERVED);
if (ret >= 0)
*val = le64_to_cpu(res.u64);
@@ -244,7 +244,7 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
cmd.prop_set.value = cpu_to_le64(val);
ret = __nvme_submit_sync_cmd(ctrl->fabrics_q, &cmd, NULL, NULL, 0,
- NVME_QID_ANY, 0, 0);
+ NVME_QID_ANY, 0, BLK_MQ_REQ_RESERVED);
if (unlikely(ret))
dev_err(ctrl->device,
"Property Set error: %d, offset %#x\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0199/1887] of/irq: add missing of_node_put() for interrupt parent node
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0198/1887] nvme-fabrics: use reserved tag for reg read/write command Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0200/1887] vt: skip screen update for DEC alignment test on backgroup consoles Greg Kroah-Hartman
` (799 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Clément Léger, Rob Herring,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Clément Léger <clement.leger@bootlin.com>
[ Upstream commit eb2b4ecf7299ee39ee9cecc4d3f2633aeb10cefb ]
After calling of_irq_parse_one(), the node provided in the of_phandle_args
has a refcount increment by one. Add missing of_node_put in of_irq_get()
to decrement the refcount once used.
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
Link: https://lore.kernel.org/r/20230117144929.423089-1-clement.leger@bootlin.com
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/of/irq.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index f066d48ca3d48..1e093400bd1a9 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -467,10 +467,16 @@ int of_irq_get(struct device_node *dev, int index)
return rc;
domain = irq_find_host(oirq.np);
- if (!domain)
- return -EPROBE_DEFER;
+ if (!domain) {
+ rc = -EPROBE_DEFER;
+ goto out;
+ }
+
+ rc = irq_create_of_mapping(&oirq);
+out:
+ of_node_put(oirq.np);
- return irq_create_of_mapping(&oirq);
+ return rc;
}
EXPORT_SYMBOL_GPL(of_irq_get);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0200/1887] vt: skip screen update for DEC alignment test on backgroup consoles
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0199/1887] of/irq: add missing of_node_put() for interrupt parent node Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0201/1887] ALSA: caiaq: unregister the input device when probe fails Greg Kroah-Hartman
` (798 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Zizhi Wo
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zizhi Wo <wozizhi@huawei.com>
commit 0928ed9bd7946baee911efa401088697836e3b1e upstream.
[BUG]
Recently, we encountered a KASAN warning as follows:
BUG: KASAN: slab-out-of-bounds in fb_pad_aligned_buffer+0x11f/0x140
Read of size 1 at addr ff1100015fd9f6a4 by task tty_fbcon_oob/1239
CPU: 7 UID: 0 PID: 1239 Comm: tty_fbcon_oob Not tainted 7.3.0-rc1 #100 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014
Call Trace:
<TASK>
...
kasan_report+0xf0/0x120
fb_pad_aligned_buffer+0x11f/0x140
ccw_putcs+0x86c/0xa80
fbcon_putcs+0x338/0x410
do_update_region+0x21d/0x450
do_con_write+0x1e0e/0x4880
con_write+0x13/0x80
n_tty_write+0x374/0x1010
file_tty_write.isra.0+0x404/0x7a0
...
reproduce:
1) open /dev/tty0, set a KDFONTOP ioctl with op.op = KD_FONT_OP_SET,
op.width = 8 and op.height = 16 (visible VC1)
2) open /dev/tty1, set a KDFONTOP ioctl with op.op = KD_FONT_OP_SET,
op.width = 28 and op.height = 24 (invisible VC2)
3) echo 3 > /sys/devices/virtual/graphics/fbcon/rotate_all
4) write EShash8(esc hash8) to tty1
[CAUSE]
All VCs render to the framebuffer. setfont only modifies the target VC's
font without resizing the framebuffer backing buffer (par->rotated.buf);
the buffer is only resized for the visible VC
(fbcon_do_set_font -> ... -> vc_do_resize -> update_screen). This relies on
the con_should_update() check performed before every update_region().
However, the ESC # 8 path (do_con_trol -> do_update_region) omits the
con_should_update() check. After changing the font size of an invisible VC,
do_update_region() fills using the new font size against a buffer that was
never resized, causing an out-of-bounds access.
[FIX]
Only push the update when the console is visible and not blanked, add
the con_should_update() check in the do_con_trol() like every other call
site of do_update_region() (update_region(), invert_screen(), ...).
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@kernel.org>
Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
Link: https://patch.msgid.link/20260905064337.3083103-1-wozizhi@huaweicloud.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/vt/vt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2543,7 +2543,8 @@ static void do_con_trol(struct tty_struc
csi_J(vc, 2);
vc->vc_video_erase_char =
(vc->vc_video_erase_char & 0xff00) | ' ';
- do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+ if (con_should_update(vc))
+ do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
}
return;
case ESsetG0:
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0201/1887] ALSA: caiaq: unregister the input device when probe fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0200/1887] vt: skip screen update for DEC alignment test on backgroup consoles Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0202/1887] ALSA: line6: reject oversized playback packets Greg Kroah-Hartman
` (797 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2a123f6269da57ffefaa,
Nguyen Ngoc Thang, Takashi Iwai
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
commit 0b7bd20f6379bc5e431fd74d866390f5b5b63f3c upstream.
setup_card() registers the input device, whose name and phys point into
struct snd_usb_caiaqdev, and then goes on to snd_card_register() and
snd_usb_caiaq_control_init(). If either fails, snd_probe() calls
snd_card_free(), which frees the device state but leaves the input
device registered: card_free() only clears the pointer, and the input
device is unregistered from snd_disconnect() alone. Reading its "uevent"
attribute afterwards dereferences freed memory:
BUG: KASAN: slab-use-after-free in string+0x4a9/0x4f0
Read of size 1 at addr ffff8880208f5043 by task caiaq/4967
add_uevent_var+0x183/0x3a0
input_dev_uevent+0x162/0x900
dev_uevent+0x2f1/0x870
uevent_show+0x1ca/0x3a0
...
Unregister the input device on the probe error path, as
snd_disconnect() does. snd_usb_caiaq_input_disconnect() is a no-op when
no input device was registered.
Reproduced with a raw-gadget Audio Kontrol 1 and a temporary hack that
makes snd_usb_caiaq_control_init() fail.
Fixes: 28abd224db4a ("ALSA: caiaq: Handle probe errors properly")
Cc: stable@vger.kernel.org
Reported-by: syzbot+2a123f6269da57ffefaa@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2a123f6269da57ffefaa
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Link: https://patch.msgid.link/20260925170717.22462-1-ngocthang2710.1999@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/caiaq/device.c | 3 +++
1 file changed, 3 insertions(+)
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -562,6 +562,9 @@ static int snd_probe(struct usb_interfac
ret = init_card(caiaqdev(card));
if (ret < 0) {
dev_err(&usb_dev->dev, "unable to init card! (ret=%d)\n", ret);
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+ snd_usb_caiaq_input_disconnect(caiaqdev(card));
+#endif
snd_card_free(card);
return ret;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0202/1887] ALSA: line6: reject oversized playback packets
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0201/1887] ALSA: caiaq: unregister the input device when probe fails Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0203/1887] mm/secretmem: properly account locked pages Greg Kroah-Hartman
` (796 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+be8fa7ea6f77fdce, Xiang Mei,
Takashi Iwai
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <xmei5@asu.edu>
commit 61b0a5a114fa4552892da5c0ff2f42e63bf08c6b upstream.
Each playback URB is handed a slice of out.buffer that is exactly
LINE6_ISO_PACKETS * max_packet_size_out bytes, sized from the OUT
endpoint, but the number of bytes written into that slice is never
compared against it.
submit_audio_out_urb() takes the frame count from prev_fsize, which
audio_in_callback() derived from the *IN* endpoint's received packet
length, and rescales it with the playback frame size; when prev_fsize is
still zero it synthesizes a length from the sample rate instead. On a
device declaring a large IN wMaxPacketSize and a small OUT
wMaxPacketSize, the resulting memcpy(), or the memset() when the
playback stream is idle, runs past its slice and, as the reproducer
below shows, beyond the allocation.
usb_submit_urb() is not a backstop. max_packet_size_out comes from
usb_maxpacket(), which returns only the low 11 bits of wMaxPacketSize,
while USB core validates a high-speed isochronous length against that
base scaled by usb_endpoint_maxp_mult(). A length of up to three times
the allocated slice is therefore accepted, and even a rejected URB is
only rejected after the write.
Reject a packet that does not fit the slice the driver allocated for it.
Clamping it instead would silently shorten the capture-derived rate
feedback and desynchronize the two streams.
BUG: KASAN: slab-out-of-bounds in submit_audio_out_urb (sound/usb/line6/playback.c:229)
Write of size 1024 at addr ffff888100bbd400 by task kworker/1:2/5002
Workqueue: events line6_startup_work
Call Trace:
__asan_memcpy (mm/kasan/shadow.c:106)
submit_audio_out_urb (sound/usb/line6/playback.c:229)
line6_submit_audio_out_all_urbs (sound/usb/line6/playback.c:291)
line6_stream_start (sound/usb/line6/pcm.c:194)
line6_pcm_acquire (sound/usb/line6/pcm.c:337)
line6_startup_work (sound/usb/line6/driver.c:728)
process_one_work (kernel/workqueue.c:3396)
worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:158)
ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
The buggy address belongs to the object at ffff888100bbd400
which belongs to the cache kmalloc-256 of size 256
The buggy address is located 0 bytes inside of
allocated 256-byte region [ffff888100bbd400, ffff888100bbd500)
Cc: stable@vger.kernel.org
Fixes: 7a0f55aeeb8f ("ALSA: line6: Support assymetrical in/out configurations")
Reported-by: <co+be8fa7ea6f77fdce@bugs.sh>
Assisted-by: LLM
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260918234014.1318325-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/line6/playback.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -182,6 +182,13 @@ static int submit_audio_out_urb(struct s
fsize *= bytes_per_frame;
+ if (fsize > line6pcm->max_packet_size_out) {
+ dev_err(line6pcm->line6->ifcdev,
+ "playback packet too large: %d > %d\n",
+ fsize, line6pcm->max_packet_size_out);
+ return -EMSGSIZE;
+ }
+
fout->offset = urb_size;
fout->length = fsize;
urb_size += fsize;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0203/1887] mm/secretmem: properly account locked pages
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0202/1887] ALSA: line6: reject oversized playback packets Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0204/1887] perf/core: Fix WARN in perf_sigtrap() Greg Kroah-Hartman
` (795 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Daehyeon Ko,
Mike Rapoport (Microsoft), David Hildenbrand (Arm),
Alexei Starovoitov, David S. Miller, Hagen Paul Pfeifer,
Jakub Kacinski, James Bottomley, Jesper Dangaard Brouer,
John Fastabend, Liam R. Howlett, Michal Hocko, Stanislav Fomichev,
Suren Baghdasaryan, Vlastimil Babka, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 97d34aa65c29cca85e3e9050f4c936389b38a054 ]
secretmem accounts folios by treating memory as if it were mlock()'d and
thus limited by the RLIMIT_MEMLOCK limit.
However the folios are unevictable and remain so until the inode is
evicted, eliminating usual mlock() semantics - mapping folios then
unmapping them does not clear their unevictable state, since it depends on
AS_UNEVICTABLE, not PG_mlocked.
A user can therefore easily work around the RLIMIT_MEMLOCK limit - simply
map then unmap and VmLck no longer counts the secretmem range. Worse,
folios are not accounted in the process's RSS, meaning the OOM killer
won't know to kill the process.
Repeatedly mapping/unmapping (or forking) can then result in the
consumption of all available system memory with unevictable folios and
cause system instability.
A secretmem fd can be passed between processes and over fork so a
per-process limit simply does not make sense, so follow the precedent set
by io_uring, perf, skbuff, iommufd and xdp by tracking the number of
locked pages in user_struct->locked_vm.
Since the scope tracked is actually inode lifetime, the RLIMIT_MEMLOCK
applies per-user not per-process, so it doesn't make sense to bypass for
users with CAP_IPC_LOCK, therefore remove this bypass.
There is simply no reason to carry on marking the mapping as mlock()'d
since it's misleading and the lifecycle is now correctly handled, so
remove this too.
Note that secretmem does not support any form of truncation (including
hole punching) and the folios are unreclaimable, so the folios need only
be accounted on fault and unaccounted on inode destruction.
__secretmem_account_pages() is more or less a duplicate of the code that
io_uring etc. use, but since this is a bug fix that needs backporting,
defer any de-duplication efforts to a follow-up.
test_mlock_limit() asserts mlock_future_ok() on mmap(), however this has
been removed, so remove the test altogether for the fix. A new test will
be sent separately for upstream.
Link: https://lore.kernel.org/20260826-secretmem-accounting-v3-1-94cb04399510@kernel.org
Fixes: 1507f51255c9 ("mm: introduce memfd_secret system call to create "secret" memory areas")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: Daehyeon Ko <4ncienth@gmail.com>
Closes: https://lore.kernel.org/linux-mm/20260813225328.2010303-1-4ncienth@gmail.com/
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Tested-by: Daehyeon Ko <4ncienth@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Hagen Paul Pfeifer <hagen@jauu.net>
Cc: Jakub Kacinski <kuba@kernel.org>
Cc: James Bottomley <james.bottomley@HansenPartnership.com>
Cc: Jesper Dangaard Brouer <hawk@kernel.org>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Stanislav Fomichev <sdf@fomichev.me>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ adapted folio-based fault handling to Linux 6.1’s page-based APIs using page_folio(page) ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/sched/user.h | 3 +-
mm/secretmem.c | 119 ++++++++++++++++++++--
tools/testing/selftests/vm/memfd_secret.c | 30 +-----
3 files changed, 112 insertions(+), 40 deletions(-)
diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index 4cc52698e214e..8d7e5521f7cdd 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -25,7 +25,8 @@ struct user_struct {
#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) || \
defined(CONFIG_NET) || defined(CONFIG_IO_URING) || \
- defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD)
+ defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD) || \
+ defined(CONFIG_SECRETMEM)
atomic_long_t locked_vm;
#endif
#ifdef CONFIG_WATCH_QUEUE
diff --git a/mm/secretmem.c b/mm/secretmem.c
index b570a6e25b6be..84d10092ecb03 100644
--- a/mm/secretmem.c
+++ b/mm/secretmem.c
@@ -18,6 +18,9 @@
#include <linux/secretmem.h>
#include <linux/set_memory.h>
#include <linux/sched/signal.h>
+#include <linux/sched/user.h>
+#include <linux/cred.h>
+#include <linux/slab.h>
#include <uapi/linux/magic.h>
@@ -47,10 +50,69 @@ bool secretmem_active(void)
return !!atomic_read(&secretmem_users);
}
+struct secretmem_inode_state {
+ struct user_struct *user;
+ atomic_long_t nr_pages_accounted;
+};
+
+static bool __secretmem_account_pages(struct user_struct *user,
+ unsigned long nr_pages)
+{
+ unsigned long page_limit, cur_pages, new_pages;
+
+ if (!nr_pages)
+ return true;
+
+ page_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+ cur_pages = atomic_long_read(&user->locked_vm);
+ do {
+ new_pages = cur_pages + nr_pages;
+ if (new_pages > page_limit)
+ return false;
+ } while (!atomic_long_try_cmpxchg(&user->locked_vm,
+ &cur_pages, new_pages));
+ return true;
+}
+
+static bool secretmem_account_folio(struct secretmem_inode_state *state,
+ struct folio *folio)
+{
+ const unsigned long nr_pages = folio_nr_pages(folio);
+
+ if (!__secretmem_account_pages(state->user, nr_pages))
+ return false;
+
+ atomic_long_add(nr_pages, &state->nr_pages_accounted);
+ return true;
+}
+
+static void __secretmem_unaccount_pages(struct secretmem_inode_state *state,
+ unsigned long nr_pages)
+{
+ atomic_long_sub(nr_pages, &state->user->locked_vm);
+ atomic_long_sub(nr_pages, &state->nr_pages_accounted);
+}
+
+static void secretmem_unaccount_folio(struct secretmem_inode_state *state,
+ struct folio *folio)
+{
+ __secretmem_unaccount_pages(state, folio_nr_pages(folio));
+}
+
+static void secretmem_unaccount_all_folios(struct secretmem_inode_state *state)
+{
+ const unsigned long nr_pages_accounted =
+ atomic_long_read(&state->nr_pages_accounted);
+
+ __secretmem_unaccount_pages(state, nr_pages_accounted);
+}
+
static vm_fault_t secretmem_fault(struct vm_fault *vmf)
{
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
struct inode *inode = file_inode(vmf->vma->vm_file);
+ struct secretmem_inode_state *state = inode->i_private;
pgoff_t offset = vmf->pgoff;
gfp_t gfp = vmf->gfp_mask;
unsigned long addr;
@@ -72,8 +134,15 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf)
goto out;
}
+ if (!secretmem_account_folio(state, page_folio(page))) {
+ put_page(page);
+ ret = VM_FAULT_SIGBUS;
+ goto out;
+ }
+
err = set_direct_map_invalid_noflush(page);
if (err) {
+ secretmem_unaccount_folio(state, page_folio(page));
put_page(page);
ret = vmf_error(err);
goto out;
@@ -82,6 +151,7 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf)
__SetPageUptodate(page);
err = add_to_page_cache_lru(page, mapping, offset, gfp);
if (unlikely(err)) {
+ secretmem_unaccount_folio(state, page_folio(page));
/*
* If a split of large page was required, it
* already happened when we marked the page invalid
@@ -112,23 +182,30 @@ static const struct vm_operations_struct secretmem_vm_ops = {
.fault = secretmem_fault,
};
+static void secretmem_destroy_inode_priv(struct inode *inode)
+{
+ struct secretmem_inode_state *state = inode->i_private;
+
+ secretmem_unaccount_all_folios(state);
+ free_uid(state->user);
+ kfree(state);
+ inode->i_private = NULL;
+}
+
static int secretmem_release(struct inode *inode, struct file *file)
{
atomic_dec(&secretmem_users);
+ secretmem_destroy_inode_priv(inode);
+
return 0;
}
static int secretmem_mmap(struct file *file, struct vm_area_struct *vma)
{
- unsigned long len = vma->vm_end - vma->vm_start;
-
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
- if (mlock_future_check(vma->vm_mm, vma->vm_flags | VM_LOCKED, len))
- return -EAGAIN;
-
- vma->vm_flags |= VM_LOCKED | VM_DONTDUMP;
+ vma->vm_flags |= VM_DONTDUMP;
vma->vm_ops = &secretmem_vm_ops;
return 0;
@@ -188,19 +265,40 @@ static const struct inode_operations secretmem_iops = {
static struct vfsmount *secretmem_mnt;
+static int secretmem_init_inode_priv(struct inode *inode)
+{
+ struct secretmem_inode_state *state;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+
+ state->user = get_uid(current_user());
+ inode->i_private = state;
+ return 0;
+}
+
static struct file *secretmem_file_create(unsigned long flags)
{
struct file *file = ERR_PTR(-ENOMEM);
struct inode *inode;
const char *anon_name = "[secretmem]";
+ int err;
inode = anon_inode_make_secure_inode(secretmem_mnt->mnt_sb, anon_name, NULL);
if (IS_ERR(inode))
return ERR_CAST(inode);
+
+ err = secretmem_init_inode_priv(inode);
+ if (err)
+ goto err_free_inode;
+
file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem",
O_RDWR, &secretmem_fops);
- if (IS_ERR(file))
- goto err_free_inode;
+ if (IS_ERR(file)) {
+ err = PTR_ERR(file);
+ goto err_free_priv;
+ }
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
mapping_set_unevictable(inode->i_mapping);
@@ -213,10 +311,11 @@ static struct file *secretmem_file_create(unsigned long flags)
inode->i_size = 0;
return file;
-
+err_free_priv:
+ secretmem_destroy_inode_priv(inode);
err_free_inode:
iput(inode);
- return file;
+ return ERR_PTR(err);
}
SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
diff --git a/tools/testing/selftests/vm/memfd_secret.c b/tools/testing/selftests/vm/memfd_secret.c
index 9b298f6a04b37..348cc976726bb 100644
--- a/tools/testing/selftests/vm/memfd_secret.c
+++ b/tools/testing/selftests/vm/memfd_secret.c
@@ -56,33 +56,6 @@ static void test_file_apis(int fd)
pass("file IO is blocked as expected\n");
}
-static void test_mlock_limit(int fd)
-{
- size_t len;
- char *mem;
-
- len = mlock_limit_cur;
- if (len % page_size != 0)
- len = (len/page_size) * page_size;
-
- mem = mmap(NULL, len, prot, mode, fd, 0);
- if (mem == MAP_FAILED) {
- fail("unable to mmap secret memory\n");
- return;
- }
- munmap(mem, len);
-
- len = mlock_limit_max * 2;
- mem = mmap(NULL, len, prot, mode, fd, 0);
- if (mem != MAP_FAILED) {
- fail("unexpected mlock limit violation\n");
- munmap(mem, len);
- return;
- }
-
- pass("mlock limit is respected\n");
-}
-
static void try_process_vm_read(int fd, int pipefd[2])
{
struct iovec liov, riov;
@@ -258,7 +231,7 @@ static void prepare(void)
strerror(errno));
}
-#define NUM_TESTS 4
+#define NUM_TESTS 3
int main(int argc, char *argv[])
{
@@ -278,7 +251,6 @@ int main(int argc, char *argv[])
strerror(errno));
}
- test_mlock_limit(fd);
test_file_apis(fd);
test_process_vm_read(fd);
test_ptrace(fd);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0204/1887] perf/core: Fix WARN in perf_sigtrap()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0203/1887] mm/secretmem: properly account locked pages Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0205/1887] watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger Greg Kroah-Hartman
` (794 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot, Tetsuo Handa,
Peter Zijlstra (Intel), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[ Upstream commit 3da6bb419750f3ad834786d6ba7c9d5d062c770b ]
Since exit_task_work() runs after perf_event_exit_task_context() updated
ctx->task to TASK_TOMBSTONE, perf_sigtrap() from perf_pending_task() might
observe event->ctx->task == TASK_TOMBSTONE.
Swap the early exit tests in order not to hit WARN_ON_ONCE().
Closes: https://syzkaller.appspot.com/bug?extid=2fe61cb2a86066be6985
Reported-by: syzbot <syzbot+2fe61cb2a86066be6985@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/b1c224bd-97f9-462c-a3e3-125d5e19c983@I-love.SAKURA.ne.jp
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/core.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index a0bb33854c4a9..e5c79c55ce48e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6595,18 +6595,18 @@ void perf_event_wakeup(struct perf_event *event)
static void perf_sigtrap(struct perf_event *event)
{
/*
- * We'd expect this to only occur if the irq_work is delayed and either
- * ctx->task or current has changed in the meantime. This can be the
- * case on architectures that do not implement arch_irq_work_raise().
+ * Both perf_pending_task() and perf_pending_irq() can race with the
+ * task exiting.
*/
- if (WARN_ON_ONCE(event->ctx->task != current))
+ if (current->flags & PF_EXITING)
return;
/*
- * Both perf_pending_task() and perf_pending_irq() can race with the
- * task exiting.
+ * We'd expect this to only occur if the irq_work is delayed and either
+ * ctx->task or current has changed in the meantime. This can be the
+ * case on architectures that do not implement arch_irq_work_raise().
*/
- if (current->flags & PF_EXITING)
+ if (WARN_ON_ONCE(event->ctx->task != current))
return;
send_sig_perf((void __user *)event->pending_addr,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0205/1887] watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0204/1887] perf/core: Fix WARN in perf_sigtrap() Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0206/1887] wifi: ath11k: add srng->lock for ath11k_hal_srng_* in monitor mode Greg Kroah-Hartman
` (793 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Duoming Zhou, Guenter Roeck,
Wim Van Sebroeck, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <duoming@zju.edu.cn>
[ Upstream commit 573601521277119f2e2ba5f28ae6e87fc594f4d4 ]
When the cpu5wdt module is removing, the origin code uses del_timer() to
de-activate the timer. If the timer handler is running, del_timer() could
not stop it and will return directly. If the port region is released by
release_region() and then the timer handler cpu5wdt_trigger() calls outb()
to write into the region that is released, the use-after-free bug will
happen.
Change del_timer() to timer_shutdown_sync() in order that the timer handler
could be finished before the port region is released.
Fixes: e09d9c3e9f85 ("watchdog: cpu5wdt.c: add missing del_timer call")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20240324140444.119584-1-duoming@zju.edu.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/cpu5wdt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 688b112e712ba..9f279c0e13a66 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -252,7 +252,7 @@ static void cpu5wdt_exit(void)
if (cpu5wdt_device.queue) {
cpu5wdt_device.queue = 0;
wait_for_completion(&cpu5wdt_device.stop);
- del_timer(&cpu5wdt_device.timer);
+ timer_shutdown_sync(&cpu5wdt_device.timer);
}
misc_deregister(&cpu5wdt_misc);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0206/1887] wifi: ath11k: add srng->lock for ath11k_hal_srng_* in monitor mode
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0205/1887] watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0207/1887] hsr: Remove WARN_ONCE() in hsr_addr_is_self() Greg Kroah-Hartman
` (792 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kang Yang, Jeff Johnson,
Jeff Johnson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kang Yang <quic_kangyang@quicinc.com>
[ Upstream commit 63b7af49496d0e32f7a748b6af3361ec138b1bd3 ]
ath11k_hal_srng_* should be used with srng->lock to protect srng data.
For ath11k_dp_rx_mon_dest_process() and ath11k_dp_full_mon_process_rx(),
they use ath11k_hal_srng_* for many times but never call srng->lock.
So when running (full) monitor mode, warning will occur:
RIP: 0010:ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k]
Call Trace:
? ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k]
ath11k_dp_rx_process_mon_status+0xc45/0x1190 [ath11k]
? idr_alloc_u32+0x97/0xd0
ath11k_dp_rx_process_mon_rings+0x32a/0x550 [ath11k]
ath11k_dp_service_srng+0x289/0x5a0 [ath11k]
ath11k_pcic_ext_grp_napi_poll+0x30/0xd0 [ath11k]
__napi_poll+0x30/0x1f0
net_rx_action+0x198/0x320
__do_softirq+0xdd/0x319
So add srng->lock for them to avoid such warnings.
Inorder to fetch the srng->lock, should change srng's definition from
'void' to 'struct hal_srng'. And initialize them elsewhere to prevent
one line of code from being too long. This is consistent with other ring
process functions, such as ath11k_dp_process_rx().
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Link: https://patch.msgid.link/20241219110531.2096-3-quic_kangyang@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/dp_rx.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 7e59260a30b89..413b24275a848 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -5123,7 +5123,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
const struct ath11k_hw_hal_params *hal_params;
void *ring_entry;
- void *mon_dst_srng;
+ struct hal_srng *mon_dst_srng;
u32 ppdu_id;
u32 rx_bufs_used;
u32 ring_id;
@@ -5147,6 +5147,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
spin_lock_bh(&pmon->mon_lock);
+ spin_lock_bh(&mon_dst_srng->lock);
ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
ppdu_id = pmon->mon_ppdu_info.ppdu_id;
@@ -5205,6 +5206,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
mon_dst_srng);
}
ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);
+ spin_unlock_bh(&mon_dst_srng->lock);
spin_unlock_bh(&pmon->mon_lock);
@@ -5594,7 +5596,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
struct hal_sw_mon_ring_entries *sw_mon_entries;
struct ath11k_pdev_mon_stats *rx_mon_stats;
struct sk_buff *head_msdu, *tail_msdu;
- void *mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id];
+ struct hal_srng *mon_dst_srng;
void *ring_entry;
u32 rx_bufs_used = 0, mpdu_rx_bufs_used;
int quota = 0, ret;
@@ -5610,6 +5612,9 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
goto reap_status_ring;
}
+ mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id];
+ spin_lock_bh(&mon_dst_srng->lock);
+
ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) {
head_msdu = NULL;
@@ -5653,6 +5658,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
}
ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);
+ spin_unlock_bh(&mon_dst_srng->lock);
spin_unlock_bh(&pmon->mon_lock);
if (rx_bufs_used) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0207/1887] hsr: Remove WARN_ONCE() in hsr_addr_is_self().
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0206/1887] wifi: ath11k: add srng->lock for ath11k_hal_srng_* in monitor mode Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0208/1887] perf/x86/amd/lbr: Fix kernel address leakage Greg Kroah-Hartman
` (791 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+652670cf249077eb498b,
Kuniyuki Iwashima, Fernando Fernandez Mancera, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit afd0f17ca46258cec3a5cc48b8df9327fe772490 ]
syzbot reported the warning [0] in hsr_addr_is_self(),
whose assumption is simply wrong.
hsr->self_node is cleared in hsr_del_self_node(), which
is called from hsr_dellink().
Since dev->rtnl_link_ops->dellink() is called before
unregister_netdevice_many(), there is a window when
user can find the device but without hsr->self_node.
Let's remove WARN_ONCE() in hsr_addr_is_self().
[0]:
HSR: No self node
WARNING: net/hsr/hsr_framereg.c:39 at hsr_addr_is_self+0x211/0x3f0 net/hsr/hsr_framereg.c:39, CPU#0: syz.4.16848/17220
Modules linked in:
CPU: 0 UID: 0 PID: 17220 Comm: syz.4.16848 Tainted: G L syzkaller #0 PREEMPT_{RT,(full)}
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
RIP: 0010:hsr_addr_is_self+0x211/0x3f0 net/hsr/hsr_framereg.c:39
Code: 33 2f 41 0f b7 dd 89 ee 09 de 31 ff e8 c8 b4 c6 f6 09 dd 74 54 e8 0f b0 c6 f6 31 ed eb 53 e8 06 b0 c6 f6 48 8d 3d 2f 50 9c 04 <67> 48 0f b9 3a 31 ed eb 42 e8 c1 13 1f 00 89 c5 31 ff 89 c6 e8 96
RSP: 0018:ffffc900041c70e0 EFLAGS: 00010283
RAX: ffffffff8afdc6ca RBX: ffffffff8afdc4e6 RCX: 0000000000080000
RDX: ffffc90010493000 RSI: 0000000000000948 RDI: ffffffff8f9a1700
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc900041c71e8 R11: fffff52000838e3f R12: dffffc0000000000
R13: ffff888041f9e3c0 R14: ffff888086ee3802 R15: 0000000000000000
FS: 00007f6fe985d6c0(0000) GS:ffff888126176000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f80bd437dac CR3: 0000000025096000 CR4: 00000000003526f0
DR0: ffffffffffffffff DR1: 00000000000001f8 DR2: 0000000000000002
DR3: ffffffffefffff15 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
check_local_dest net/hsr/hsr_forward.c:592 [inline]
fill_frame_info net/hsr/hsr_forward.c:728 [inline]
hsr_forward_skb+0xa11/0x2a80 net/hsr/hsr_forward.c:739
hsr_dev_xmit+0x253/0x370 net/hsr/hsr_device.c:236
__netdev_start_xmit include/linux/netdevice.h:5368 [inline]
netdev_start_xmit include/linux/netdevice.h:5377 [inline]
xmit_one net/core/dev.c:3888 [inline]
dev_hard_start_xmit+0x2df/0x860 net/core/dev.c:3904
__dev_queue_xmit+0x1428/0x3900 net/core/dev.c:4870
neigh_output include/net/neighbour.h:556 [inline]
ip_finish_output2+0xcec/0x10b0 net/ipv4/ip_output.c:237
ip_send_skb net/ipv4/ip_output.c:1510 [inline]
ip_push_pending_frames+0x8b/0x110 net/ipv4/ip_output.c:1530
raw_sendmsg+0x1547/0x1a50 net/ipv4/raw.c:659
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x7da/0x9c0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1c3/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f6feb62ce59
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f6fe985d028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007f6feb8a6090 RCX: 00007f6feb62ce59
RDX: 0000000000000000 RSI: 0000200000000000 RDI: 0000000000000004
RBP: 00007f6feb6c2d6f R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f6feb8a6128 R14: 00007f6feb8a6090 R15: 00007ffcf01cc488
</TASK>
Fixes: f266a683a480 ("net/hsr: Better frame dispatch")
Reported-by: syzbot+652670cf249077eb498b@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a1a861e.b111c304.35cd64.0016.GAE@google.com/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Link: https://patch.msgid.link/20260530064300.340793-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/hsr/hsr_framereg.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index 60eab82ca5a0a..35c2fae8d1f79 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -43,10 +43,8 @@ bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
rcu_read_lock();
sn = rcu_dereference(hsr->self_node);
- if (!sn) {
- WARN_ONCE(1, "HSR: No self node\n");
+ if (!sn)
goto out;
- }
if (ether_addr_equal(addr, sn->macaddress_A) ||
ether_addr_equal(addr, sn->macaddress_B))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0208/1887] perf/x86/amd/lbr: Fix kernel address leakage
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0207/1887] hsr: Remove WARN_ONCE() in hsr_addr_is_self() Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0209/1887] drm/tegra: gr2d/gr3d: Initialize address register map before HOST1X client is registered Greg Kroah-Hartman
` (790 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ian Rogers, Sandipan Das,
Ingo Molnar, Peter Zijlstra, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sandipan Das <sandipan.das@amd.com>
[ Upstream commit 2a892294b83f541115c94b0bb637f39bef187657 ]
A user-only branch stack can contain branches that originate from
the kernel. As a result, kernel addresses are exposed to user space
even when PERF_SAMPLE_BRANCH_USER is requested. On AMD processors
supporting X86_FEATURE_AMD_LBR_V2, perf can still report SYSRET/ERET
entries for which the branch-from addresses are in the kernel.
E.g.
$ perf record -e cycles -o - -j any,save_type,u -- \
perf bench syscall basic --loop 1000 | \
perf script -i - -F brstack|tr ' ' '\n'| \
grep -E '0x[89a-f][0-9a-f]{15}'
...
0xffffffff81001268/0x717a90a38f1a/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a90a39157/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a90a2c628/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a90a41b60/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a90a260db/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a90a260db/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a8bef1c30/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
0xffffffff81001268/0x717a8e4d3c90/M/-/-/0/ERET/NON_SPEC_CORRECT_PATH
...
The reason is that the hardware filter only considers the privilege
level applicable to the branch target. Extend software filtering to
also validate the branch-from addresses against br_sel, so that any
branch record whose branch-from address is in the kernel is dropped
when PERF_SAMPLE_BRANCH_USER is requested.
Fixes: f4f925dae741 ("perf/x86/amd/lbr: Add LbrExtV2 hardware branch filter support")
Reported-by: Ian Rogers <irogers@google.com>
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://patch.msgid.link/a898a29725f6b2f30518354cdc2e432db66c43cf.1783680119.git.sandipan.das@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/amd/lbr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/lbr.c b/arch/x86/events/amd/lbr.c
index 48f4095f500d4..6096fb6925f66 100644
--- a/arch/x86/events/amd/lbr.c
+++ b/arch/x86/events/amd/lbr.c
@@ -124,7 +124,8 @@ static void amd_pmu_lbr_filter(void)
}
/* If type does not correspond, then discard */
- if (type == X86_BR_NONE || (br_sel & type) != type) {
+ if (type == X86_BR_NONE || (br_sel & type) != type ||
+ (!(br_sel & X86_BR_KERNEL) && kernel_ip(cpuc->lbr_entries[i].from))) {
cpuc->lbr_entries[i].from = 0; /* mark invalid */
compress = true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0209/1887] drm/tegra: gr2d/gr3d: Initialize address register map before HOST1X client is registered
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0208/1887] perf/x86/amd/lbr: Fix kernel address leakage Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0210/1887] scsi: qla2xxx: Initialize NVMe abort_work once at submission Greg Kroah-Hartman
` (789 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikko Perttunen, Svyatoslav Ryhel,
Thierry Reding, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Svyatoslav Ryhel <clamor95@gmail.com>
[ Upstream commit c4ef5ba1131346159e31f4ef858525cf377380a6 ]
The host1x_client_register() function is called just prior to register map
initialization loop, making the device available to userspace. This may
result in userspace attempting to submits a job before the register map is
initialized. Address this by moving register initialization before host1x
client registration.
Acked-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260517091450.46728-2-clamor95@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/tegra/gr2d.c | 8 ++++----
drivers/gpu/drm/tegra/gr3d.c | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index e3bb4c99ed39f..9deed8345d76d 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -282,16 +282,16 @@ static int gr2d_probe(struct platform_device *pdev)
if (err)
return err;
+ /* initialize address register map */
+ for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++)
+ set_bit(gr2d_addr_regs[i], gr2d->addr_regs);
+
err = host1x_client_register(&gr2d->client.base);
if (err < 0) {
dev_err(dev, "failed to register host1x client: %d\n", err);
return err;
}
- /* initialize address register map */
- for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++)
- set_bit(gr2d_addr_regs[i], gr2d->addr_regs);
-
return 0;
}
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index a1fd3113ea96e..98dc2ed35915d 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -536,6 +536,10 @@ static int gr3d_probe(struct platform_device *pdev)
if (err)
return err;
+ /* initialize address register map */
+ for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++)
+ set_bit(gr3d_addr_regs[i], gr3d->addr_regs);
+
err = host1x_client_register(&gr3d->client.base);
if (err < 0) {
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
@@ -543,10 +547,6 @@ static int gr3d_probe(struct platform_device *pdev)
return err;
}
- /* initialize address register map */
- for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++)
- set_bit(gr3d_addr_regs[i], gr3d->addr_regs);
-
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0210/1887] scsi: qla2xxx: Initialize NVMe abort_work once at submission
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0209/1887] drm/tegra: gr2d/gr3d: Initialize address register map before HOST1X client is registered Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0211/1887] scsi: qla2xxx: Fix NVMe abort reference leak on repeated abort Greg Kroah-Hartman
` (788 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 7e85f6dbc85616de2172bce8eaf84b387a723cd1 ]
qla_nvme_fcp_abort() and qla_nvme_ls_abort() ran INIT_WORK() on
priv->abort_work immediately before schedule_work(). INIT_WORK()
reinitializes the work_struct, resetting its list head and clearing the
pending bit. If an abort is issued more than once for the same command
(for example, concurrent transport teardown and a timeout-driven abort),
the second INIT_WORK() reinitializes a work item that is already queued,
which can corrupt the workqueue list and lead to crashes or a looping
worker.
Initialize priv->abort_work once at command submission, next to the
existing per-command spin_lock_init(&priv->cmd_lock), and leave only
schedule_work() in the abort paths. schedule_work() already does nothing
when the work item is still pending, so a repeated abort no longer
disturbs an in-flight work item. The command is not returned to the
transport until the final kref_put()/release callback runs after
abort_work has completed, so the work item is idle before priv is reused
and the single submission-time INIT_WORK() is safe.
Fixes: e473b3074104 ("scsi: qla2xxx: Add FC-NVMe abort processing")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-52-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_nvme.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 622b11660b67c..2c1b17a594206 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -309,7 +309,6 @@ static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
}
spin_unlock_irqrestore(&priv->cmd_lock, flags);
- INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
schedule_work(&priv->abort_work);
}
@@ -347,6 +346,7 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
priv->sp = sp;
kref_init(&sp->cmd_kref);
spin_lock_init(&priv->cmd_lock);
+ INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
nvme = &sp->u.iocb_cmd;
priv->fd = fd;
nvme->u.nvme.desc = fd;
@@ -391,7 +391,6 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
}
spin_unlock_irqrestore(&priv->cmd_lock, flags);
- INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
schedule_work(&priv->abort_work);
}
@@ -657,6 +656,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
kref_init(&sp->cmd_kref);
spin_lock_init(&priv->cmd_lock);
+ INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
sp->priv = priv;
priv->sp = sp;
sp->type = SRB_NVME_CMD;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0211/1887] scsi: qla2xxx: Fix NVMe abort reference leak on repeated abort
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0210/1887] scsi: qla2xxx: Initialize NVMe abort_work once at submission Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0212/1887] mm/damon/core: dont skip damos_adjust_quota() while esz is not zero Greg Kroah-Hartman
` (787 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 06b5b2a5d499323f1c3256ead35798e8e3d15e60 ]
qla_nvme_ls_abort() and qla_nvme_fcp_abort() take a command reference with
kref_get_unless_zero() and then call schedule_work() on priv->abort_work,
ignoring its return value. qla_nvme_abort_work() runs once and drops
exactly one reference via kref_put(&sp->cmd_kref, sp->put_fn).
Since the per-abort INIT_WORK() was moved to submission time,
schedule_work() now returns false when the work is already pending, for
example on a concurrent transport teardown and timeout-driven abort of
the same command. In that case the reference taken for the second abort
is never released because the work still executes only once, leaking a
reference. The command is then never returned to the NVMe-FC transport,
which can hang the port.
Drop the reference when schedule_work() returns false, so each
kref_get_unless_zero() is balanced regardless of whether the work was
newly queued. The held reference keeps priv->sp valid for the put.
Fixes: 7e85f6dbc856 ("scsi: qla2xxx: Initialize NVMe abort_work once at submission")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-25-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_nvme.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 2c1b17a594206..20a904142810c 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -309,7 +309,8 @@ static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
}
spin_unlock_irqrestore(&priv->cmd_lock, flags);
- schedule_work(&priv->abort_work);
+ if (!schedule_work(&priv->abort_work))
+ kref_put(&priv->sp->cmd_kref, priv->sp->put_fn);
}
static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
@@ -391,7 +392,8 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
}
spin_unlock_irqrestore(&priv->cmd_lock, flags);
- schedule_work(&priv->abort_work);
+ if (!schedule_work(&priv->abort_work))
+ kref_put(&priv->sp->cmd_kref, priv->sp->put_fn);
}
static inline int qla2x00_start_nvme_mq(srb_t *sp)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0212/1887] mm/damon/core: dont skip damos_adjust_quota() while esz is not zero
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0211/1887] scsi: qla2xxx: Fix NVMe abort reference leak on repeated abort Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0213/1887] mtd: use refcount to prevent corruption Greg Kroah-Hartman
` (786 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Kunwu Chan,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit 52ae167ce16609c7e6fffef588b3c2c26de2db19 ]
DAMOS could unexpectedly stop working when a user disables quota using the
online parameters commit feature. Fix it by correcting a wrong quota
unset check in damos_adjust_quota().
DAMON users could disable all quotas by unsetting time and size quotas,
and removing all quota goals. The intention of disabling quotas would be
making DAMOS run at full speed. When such quota disabled setup is
detected, damos_adjust_quota() skips all its work. The skipped works
include effective size quota (damos_quota->esz) updates and charged quota
amount (damos_quota->charged_sz) resets. The intention is to avoid doing
unnecessary work when quotas are disabled.
However, users could do the setup while effective size quota is non-zero,
by doing the disabling with the online DAMON parameters commit feature.
In this case, because the effective size quota exists, DAMOS will keep
working with the quota until it is fully charged. After the effective
quota is fully charged, the charged quota amount (damos_quota->charged_sz)
cannot be reset because damos_adjust_quota() skips it. Then, DAMOS stops
working until the quota is newly set or DAMON is entirely restarted.
The problem happens because damos_adjust_quota() assumes the user setup
for disabling quota immediately disabled it. In reality, the quota is
still working until the effective size quota is also updated to zero.
Other logic for catching that uses damos_quota_is_set(), which understands
the fact and therefore checks the effective size quota in addition to the
user setup. Fix the issue by using damos_quota_is_set() in
damos_adjust_quota() to determine if its works should be skipped.
The user impact is a non-deterministic and unexpected DAMOS stop behavior.
That is, users would disable quotas using the online parameters commit
feature, expecting DAMOS will run at full speed. However, depending on
the timing, the setup can be updated while the effective size quota is
non-zero. Due to the above mentioned internal mechanism, DAMOS stops
working instead of running at full speed. It is unexpected behavior. It
is also non-deterministic because sometimes the setup is done when the
effective size quota is zero, depending on the timing. It doesn't cause
critical issues like crashes or leaks. Users can simply set a reasonable
quota again, or restart DAMON. But definitely it is an unexpected and
non-deterministic behavior that makes it difficult to reliably use. Also
investigating the root cause of the behavior would be quite difficult.
Link: https://lore.kernel.org/20260916135020.86483-1-sj@kernel.org
Fixes: da87878010e5 ("mm/damon/sysfs: support online inputs update")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>
Cc: <stable@vger.kernel.org> # 5.19.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 7afbc20833ea4..568f24da26e6e 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -869,7 +869,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
if (!s->wmarks.activated)
continue;
- if (!quota->ms && !quota->sz)
+ if (!quota->esz && !quota->ms && !quota->sz)
continue;
/* New charge window starts */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0213/1887] mtd: use refcount to prevent corruption
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0212/1887] mm/damon/core: dont skip damos_adjust_quota() while esz is not zero Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0214/1887] mtd: call external _get and _put in right order Greg Kroah-Hartman
` (785 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tomas Winkler, Alexander Usyskin,
Miquel Raynal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Winkler <tomas.winkler@intel.com>
[ Upstream commit 19bfa9ebebb5ec0695def57eb1d80de7e9cab369 ]
When underlying device is removed mtd core will crash
in case user space is holding open handle.
Need to use proper refcounting so device is release
only when has no users.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230620131905.648089-2-alexander.usyskin@intel.com
Stable-dep-of: 12b31d1acd20 ("mtd: core: call _get_device() with the master MTD")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/mtdcore.c | 72 ++++++++++++++++++++++-------------------
drivers/mtd/mtdcore.h | 1 +
drivers/mtd/mtdpart.c | 14 ++++----
include/linux/mtd/mtd.h | 2 +-
4 files changed, 49 insertions(+), 40 deletions(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index ad527bdbd4632..565b948c99dda 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -92,10 +92,33 @@ static void mtd_release(struct device *dev)
struct mtd_info *mtd = dev_get_drvdata(dev);
dev_t index = MTD_DEVT(mtd->index);
+ if (mtd_is_partition(mtd))
+ release_mtd_partition(mtd);
+
/* remove /dev/mtdXro node */
device_destroy(&mtd_class, index + 1);
}
+static void mtd_device_release(struct kref *kref)
+{
+ struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+
+ debugfs_remove_recursive(mtd->dbg.dfs_dir);
+
+ /* Try to remove the NVMEM provider */
+ nvmem_unregister(mtd->nvmem);
+
+ device_unregister(&mtd->dev);
+
+ /* Clear dev so mtd can be safely re-registered later if desired */
+ memset(&mtd->dev, 0, sizeof(mtd->dev));
+
+ idr_remove(&mtd_idr, mtd->index);
+ of_node_put(mtd_get_of_node(mtd));
+
+ module_put(THIS_MODULE);
+}
+
#define MTD_DEVICE_ATTR_RO(name) \
static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL)
@@ -674,7 +697,7 @@ int add_mtd_device(struct mtd_info *mtd)
}
mtd->index = i;
- mtd->usecount = 0;
+ kref_init(&mtd->refcnt);
/* default value if not set by driver */
if (mtd->bitflip_threshold == 0)
@@ -776,7 +799,6 @@ int del_mtd_device(struct mtd_info *mtd)
{
int ret;
struct mtd_notifier *not;
- struct device_node *mtd_of_node;
mutex_lock(&mtd_table_mutex);
@@ -790,28 +812,8 @@ int del_mtd_device(struct mtd_info *mtd)
list_for_each_entry(not, &mtd_notifiers, list)
not->remove(mtd);
- if (mtd->usecount) {
- printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
- mtd->index, mtd->name, mtd->usecount);
- ret = -EBUSY;
- } else {
- mtd_of_node = mtd_get_of_node(mtd);
- debugfs_remove_recursive(mtd->dbg.dfs_dir);
-
- /* Try to remove the NVMEM provider */
- nvmem_unregister(mtd->nvmem);
-
- device_unregister(&mtd->dev);
-
- /* Clear dev so mtd can be safely re-registered later if desired */
- memset(&mtd->dev, 0, sizeof(mtd->dev));
-
- idr_remove(&mtd_idr, mtd->index);
- of_node_put(mtd_of_node);
-
- module_put(THIS_MODULE);
- ret = 0;
- }
+ kref_put(&mtd->refcnt, mtd_device_release);
+ ret = 0;
out_error:
mutex_unlock(&mtd_table_mutex);
@@ -1210,19 +1212,21 @@ int __get_mtd_device(struct mtd_info *mtd)
if (!try_module_get(master->owner))
return -ENODEV;
+ kref_get(&mtd->refcnt);
+
if (master->_get_device) {
err = master->_get_device(mtd);
if (err) {
+ kref_put(&mtd->refcnt, mtd_device_release);
module_put(master->owner);
return err;
}
}
- master->usecount++;
-
while (mtd->parent) {
- mtd->usecount++;
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd->parent != master)
+ kref_get(&mtd->parent->refcnt);
mtd = mtd->parent;
}
@@ -1309,18 +1313,20 @@ void __put_mtd_device(struct mtd_info *mtd)
{
struct mtd_info *master = mtd_get_master(mtd);
- while (mtd->parent) {
- --mtd->usecount;
- BUG_ON(mtd->usecount < 0);
- mtd = mtd->parent;
- }
+ while (mtd != master) {
+ struct mtd_info *parent = mtd->parent;
- master->usecount--;
+ kref_put(&mtd->refcnt, mtd_device_release);
+ mtd = parent;
+ }
if (master->_put_device)
master->_put_device(master);
module_put(master->owner);
+
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+ kref_put(&master->refcnt, mtd_device_release);
}
EXPORT_SYMBOL_GPL(__put_mtd_device);
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h
index b5eefeabf310d..b014861a06a6f 100644
--- a/drivers/mtd/mtdcore.h
+++ b/drivers/mtd/mtdcore.h
@@ -12,6 +12,7 @@ int __must_check add_mtd_device(struct mtd_info *mtd);
int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+void release_mtd_partition(struct mtd_info *mtd);
struct mtd_partitions;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index f4419fdf36a0b..f9cb2d9720404 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -32,6 +32,12 @@ static inline void free_partition(struct mtd_info *mtd)
kfree(mtd);
}
+void release_mtd_partition(struct mtd_info *mtd)
+{
+ WARN_ON(!list_empty(&mtd->part.node));
+ free_partition(mtd);
+}
+
static struct mtd_info *allocate_partition(struct mtd_info *parent,
const struct mtd_partition *part,
int partno, uint64_t cur_offset)
@@ -310,13 +316,11 @@ static int __mtd_del_partition(struct mtd_info *mtd)
sysfs_remove_files(&mtd->dev.kobj, mtd_partition_attrs);
+ list_del_init(&mtd->part.node);
err = del_mtd_device(mtd);
if (err)
return err;
- list_del(&mtd->part.node);
- free_partition(mtd);
-
return 0;
}
@@ -335,6 +339,7 @@ static int __del_mtd_partitions(struct mtd_info *mtd)
__del_mtd_partitions(child);
pr_info("Deleting %s MTD partition\n", child->name);
+ list_del_init(&child->part.node);
ret = del_mtd_device(child);
if (ret < 0) {
pr_err("Error when deleting partition \"%s\" (%d)\n",
@@ -342,9 +347,6 @@ static int __del_mtd_partitions(struct mtd_info *mtd)
err = ret;
continue;
}
-
- list_del(&child->part.node);
- free_partition(child);
}
return err;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 7c58c44662b87..914a9f974baaa 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -379,7 +379,7 @@ struct mtd_info {
struct module *owner;
struct device dev;
- int usecount;
+ struct kref refcnt;
struct mtd_debug_info dbg;
struct nvmem_device *nvmem;
struct nvmem_device *otp_user_nvmem;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0214/1887] mtd: call external _get and _put in right order
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0213/1887] mtd: use refcount to prevent corruption Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0215/1887] mtd: core: call _get_device() with the master MTD Greg Kroah-Hartman
` (784 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Usyskin, Miquel Raynal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Usyskin <alexander.usyskin@intel.com>
[ Upstream commit 79c4a56250216991f1d965ee26dcd273376e4e91 ]
MTD provider provides mtd_info object to mtd subsystem.
With kref patch the mtd_info object can be alive after
provider released mtd device.
Fix calling order in _get and _put functions to allow
mtd provider to safely alloc and release mtd object.
Execute:
1) call external _get
2) get_module
3) add internal kref
in the get function and opposite order in the put one.
The _put_device callback should be the last in put
as the master struct memory may be freed in this callback.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230620131905.648089-3-alexander.usyskin@intel.com
Stable-dep-of: 12b31d1acd20 ("mtd: core: call _get_device() with the master MTD")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/mtdcore.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 565b948c99dda..ebe53a4f5d580 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1209,21 +1209,20 @@ int __get_mtd_device(struct mtd_info *mtd)
struct mtd_info *master = mtd_get_master(mtd);
int err;
- if (!try_module_get(master->owner))
- return -ENODEV;
-
- kref_get(&mtd->refcnt);
-
if (master->_get_device) {
err = master->_get_device(mtd);
-
- if (err) {
- kref_put(&mtd->refcnt, mtd_device_release);
- module_put(master->owner);
+ if (err)
return err;
- }
}
+ if (!try_module_get(master->owner)) {
+ if (master->_put_device)
+ master->_put_device(master);
+ return -ENODEV;
+ }
+
+ kref_get(&mtd->refcnt);
+
while (mtd->parent) {
if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd->parent != master)
kref_get(&mtd->parent->refcnt);
@@ -1320,13 +1319,14 @@ void __put_mtd_device(struct mtd_info *mtd)
mtd = parent;
}
- if (master->_put_device)
- master->_put_device(master);
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+ kref_put(&master->refcnt, mtd_device_release);
module_put(master->owner);
- if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
- kref_put(&master->refcnt, mtd_device_release);
+ /* must be the last as master can be freed in the _put_device */
+ if (master->_put_device)
+ master->_put_device(master);
}
EXPORT_SYMBOL_GPL(__put_mtd_device);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0215/1887] mtd: core: call _get_device() with the master MTD
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0214/1887] mtd: call external _get and _put in right order Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0216/1887] nvmet: preserve device path on allocation failure Greg Kroah-Hartman
` (783 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Miquel Raynal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 12b31d1acd20b3185bb5f0748db0cf6874c8e9d1 ]
__get_mtd_device() calls the master's _get_device() callback with mtd,
which may be a partition. __put_mtd_device() passes the master.
This breaks gluebi partitions because gluebi_get_device() uses
container_of() and therefore requires the master MTD. Pass the master
to _get_device(), matching _put_device().
Fixes: 46b5889cc2c5 ("mtd: implement proper partition handling")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/mtdcore.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index ebe53a4f5d580..649c79f755e69 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1210,7 +1210,7 @@ int __get_mtd_device(struct mtd_info *mtd)
int err;
if (master->_get_device) {
- err = master->_get_device(mtd);
+ err = master->_get_device(master);
if (err)
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0216/1887] nvmet: preserve device path on allocation failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0215/1887] mtd: core: call _get_device() with the master MTD Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0217/1887] of/overlay: dont leak fragment references when changeset init fails Greg Kroah-Hartman
` (782 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Sun, Christoph Hellwig,
Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <sunjunchao@bytedance.com>
[ Upstream commit 2f271b812170d4cad578bae1f91db72f3c2e36e7 ]
nvmet_ns_device_path_store() frees the old path before allocating its
replacement, losing the existing configuration if allocation fails.
Allocate the new path before freeing the old one.
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/configfs.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 2e87718aa194d..88e6adc54dcbc 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -345,6 +345,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
struct nvmet_subsys *subsys = ns->subsys;
size_t len;
int ret;
+ char *new_path = NULL;
mutex_lock(&subsys->lock);
ret = -EBUSY;
@@ -356,12 +357,14 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
if (!len)
goto out_unlock;
- kfree(ns->device_path);
ret = -ENOMEM;
- ns->device_path = kmemdup_nul(page, len, GFP_KERNEL);
- if (!ns->device_path)
+ new_path = kmemdup_nul(page, len, GFP_KERNEL);
+ if (!new_path)
goto out_unlock;
+ kfree(ns->device_path);
+ ns->device_path = new_path;
+
mutex_unlock(&subsys->lock);
return count;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0217/1887] of/overlay: dont leak fragment references when changeset init fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0216/1887] nvmet: preserve device path on allocation failure Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0218/1887] of/overlay: dont create "//" paths for fragments targeting the root Greg Kroah-Hartman
` (781 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI, Abdurrahman Hussain,
Rob Herring (Arm), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
[ Upstream commit 1d62f0f2bc7edb12ed09f71203df0e47fa4efca4 ]
init_overlay_changeset() stores the number of initialized fragments
in ovcs->count only on full success. When find_target() or the
__symbols__ lookup fails partway through, the target and overlay
references taken for the fragments initialized so far are never
dropped: free_overlay_changeset() bounds its cleanup loop by
ovcs->count, which is still 0.
Store the running count on the error path so free_overlay_changeset()
puts whatever was set up. The store is guarded by ovcs->fragments
because on the allocation-failure path cnt still holds the counting
pass total while there is no fragments array; everywhere else cnt
only counts fully-initialized fragments.
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/20260805204009.CF3891F000E9@smtp.kernel.org
Fixes: 61b4de4e0b38 ("of: overlay: minor restructuring")
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Link: https://patch.msgid.link/20260831-nh-of-alias-overlay-v7-6-02754604805a@nexthop.ai
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/of/overlay.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index a869c5d9d8a31..ebd712dcf34fc 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -830,6 +830,10 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs)
err_out:
pr_err("%s() failed, ret = %d\n", __func__, ret);
+ /* let free_overlay_changeset() put the fragments set up so far */
+ if (ovcs->fragments)
+ ovcs->count = cnt;
+
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0218/1887] of/overlay: dont create "//" paths for fragments targeting the root
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0217/1887] of/overlay: dont leak fragment references when changeset init fails Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0219/1887] ASoC: wm8903: Move the DRC QR threshold to the register that holds it Greg Kroah-Hartman
` (780 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Abdurrahman Hussain,
Rob Herring (Arm), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
[ Upstream commit 21c89ff1fc86ffa517f3a9ca1ba5c48e9e37c1ba ]
dup_and_fixup_symbol_prop() rewrites a symbol value by replacing its
"/fragment/__overlay__" prefix with the fragment's target path. When
the fragment targets the root node the target path is "/" and the
result starts with "//", which __of_find_node_by_full_path() cannot
resolve: symbols pointing into such fragments silently stop
resolving.
Drop the target path when it is the root and the tail is non-empty. A
value naming the fragment root itself (empty tail) keeps the "/".
Fixes: d1651b03c2df ("of: overlay: add overlay symbols to live device tree")
Assisted-by: Claude:claude-fable-5 [Claude Code]
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Link: https://patch.msgid.link/20260831-nh-of-alias-overlay-v7-7-02754604805a@nexthop.ai
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/of/overlay.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index ebd712dcf34fc..7d8205b7e5631 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -241,6 +241,9 @@ static struct property *dup_and_fixup_symbol_prop(
if (!target_path)
return NULL;
target_path_len = strlen(target_path);
+ /* a root target renders as "/"; drop it to avoid "//" results */
+ if (target_path_len == 1 && target_path[0] == '/' && path_tail_len)
+ target_path_len = 0;
new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
if (!new_prop)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0219/1887] ASoC: wm8903: Move the DRC QR threshold to the register that holds it
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0218/1887] of/overlay: dont create "//" paths for fragments targeting the root Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0220/1887] wifi: wfx: validate MIB read length before copying to caller Greg Kroah-Hartman
` (779 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, HyeongJun An, Charles Keepax,
Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit e31ae4aeb049983fe3be0cf1e12c8074811a7685 ]
The DRC_THRESH_QR field is bits 7 and 6 of DRC_1, but the control sits on
DRC_0. Its shift and max are right for the field, only the register is
wrong.
Those bits of DRC_0 belong to DRC_STARTUP_GAIN, which "DRC Startup
Volume" claims as bits 10 to 6. So the two controls share bits 7 and 6.
Writing either one moves the other, and the quick release threshold is
never reached at all.
The six fields of DRC_1 tile it exactly, so there is nowhere else the
threshold could live. Point the control at DRC_1.
Found by a sweep for two controls claiming the same bits of one
register. No board with this codec was to hand, the register map is
the driver's own wm8903.h.
Fixes: f1c0a02f32f8 ("ALSA: ASoC: Add WM8903 CODEC driver")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260920135327.3628704-1-sammiee5311@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/wm8903.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 41346e5ec5ad4..aebe47e9dc0d3 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -678,7 +678,7 @@ SOC_ENUM("DRC Decay Rate", drc_decay),
SOC_ENUM("DRC FF Delay", drc_ff_delay),
SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
-SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
+SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_1, 6, 3, 0, drc_tlv_max),
SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0220/1887] wifi: wfx: validate MIB read length before copying to caller
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0219/1887] ASoC: wm8903: Move the DRC QR threshold to the register that holds it Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0221/1887] ASoC: tegra: Fix ASRC Stream6 input threshold control Greg Kroah-Hartman
` (778 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <elb12345@hotmail.co.uk>
[ Upstream commit ce67ebe9d8629776ce38e6995ae72fb903c828db ]
wfx_hif_read_mib() copies reply->length bytes from the firmware
response into the caller-provided buffer without checking that
reply->length does not exceed val_len. A firmware response with
a length field larger than expected overruns the caller buffer and
reads past the end of the reply allocation.
Replace the dead -ENOMEM check with an active validation that
reply->length fits within val_len before the memcpy.
Fixes: f95a29d40782 ("staging: wfx: add HIF commands helpers")
Assisted-by: LLM
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Link: https://patch.msgid.link/AS8P251MB000155034FC391A2A54B9803C8BD2@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/silabs/wfx/hif_tx.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/silabs/wfx/hif_tx.c b/drivers/net/wireless/silabs/wfx/hif_tx.c
index 9402503fbde3c..852406fc7f3c6 100644
--- a/drivers/net/wireless/silabs/wfx/hif_tx.c
+++ b/drivers/net/wireless/silabs/wfx/hif_tx.c
@@ -189,9 +189,11 @@ int wfx_hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, si
dev_warn(wdev->dev, "%s: confirmation mismatch request\n", __func__);
ret = -EIO;
}
- if (ret == -ENOMEM)
+ if (!ret && le16_to_cpu(reply->length) > val_len) {
dev_err(wdev->dev, "buffer is too small to receive %s (%zu < %d)\n",
wfx_get_mib_name(mib_id), val_len, le16_to_cpu(reply->length));
+ ret = -EIO;
+ }
if (!ret)
memcpy(val, &reply->mib_data, le16_to_cpu(reply->length));
else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0221/1887] ASoC: tegra: Fix ASRC Stream6 input threshold control
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0220/1887] wifi: wfx: validate MIB read length before copying to caller Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0222/1887] wifi: ath11k: reset ar->num_stations on hardware start Greg Kroah-Hartman
` (777 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sheetal, Thierry Reding, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sheetal <sheetal@nvidia.com>
[ Upstream commit 75fc8a3ee5aee72f2fea3b6436170fae175f7f19 ]
The Stream6 Input Threshold control points at stream index 4, which is
already used by Stream5. The threshold get and put callbacks derive the
lane ID from the register offset, so the duplicate index makes Stream6
operate on lane 4 and leaves lane 5 inaccessible from userspace.
Use stream index 5 for Stream6.
Fixes: a2df8c2d5b36 ("ASoC: tegra: Add Tegra186 based ASRC driver")
Signed-off-by: Sheetal <sheetal@nvidia.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260921085704.1248920-2-sheetal@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/tegra/tegra186_asrc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/tegra/tegra186_asrc.c b/sound/soc/tegra/tegra186_asrc.c
index 9f12faaa609dd..df25f696efed4 100644
--- a/sound/soc/tegra/tegra186_asrc.c
+++ b/sound/soc/tegra/tegra186_asrc.c
@@ -831,7 +831,7 @@ static const struct snd_kcontrol_new tegra186_asrc_controls[] = {
tegra186_asrc_put_input_threshold),
SOC_SINGLE_EXT("Stream6 Input Threshold",
- ASRC_STREAM_REG(TEGRA186_ASRC_RX_THRESHOLD, 4), 0, 3, 0,
+ ASRC_STREAM_REG(TEGRA186_ASRC_RX_THRESHOLD, 5), 0, 3, 0,
tegra186_asrc_get_input_threshold,
tegra186_asrc_put_input_threshold),
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0222/1887] wifi: ath11k: reset ar->num_stations on hardware start
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0221/1887] ASoC: tegra: Fix ASRC Stream6 input threshold control Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0223/1887] rtc: dev: zero-initialize struct rtc_wkalrm to prevent information leak Greg Kroah-Hartman
` (776 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolas Escande,
Rameshkumar Sundaram, Baochen Qiang, Jeff Johnson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Escande <nico.escande@gmail.com>
[ Upstream commit 7e0ad05ebc72fffba2bdf2400400902d94ed7272 ]
When (multiple) hw restart occurs, we end up in a situation where we
cannot accept new stations / mesh peers. This seems to be the
'num_stations' in 'struct ath11k' that did not get reset properly in
this case. In ath11k_mac_op_start(), it was indeed the only accounting var
that did not get reset so let's clear it too.
This avoids problems like those:
[1248828.088023] WARNING: CPU: 0 PID: 12281 at net/mac80211/util.c:1682 ieee80211_reconfig_stations+0x98/0xc0
[1248828.088115] Call trace:
[1248828.088116] ieee80211_reconfig_stations+0x98/0xc0 (P)
[1248828.088119] ieee80211_reconfig+0x774/0x1438
[1248828.088123] ieee80211_restart_work+0x10c/0x178
[1248828.088127] process_one_work+0x178/0x3c0
[1248828.088130] worker_thread+0x280/0x440
[1248828.088133] kthread+0xe0/0xf8
[1248828.088137] ret_from_fork+0x10/0x20
[1248828.088141] ---[ end trace 0000000000000000 ]---
[1248836.686604] ath11k_pci 0000:04:00.0: refusing to associate station: too many connected already (128)
[1248836.686609] ath11k_pci 0000:04:00.0: Failed to add station: xx:xx:xx:xx:xx:xx for VDEV: 1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260812-num-station-v3-1-871d20e043f6@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/mac.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 2ef03ad1c9051..8565a7031fae4 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5879,6 +5879,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
ar->num_started_vdevs = 0;
ar->num_created_vdevs = 0;
ar->num_peers = 0;
+ ar->num_stations = 0;
ar->allocated_vdev_map = 0;
/* Configure monitor status ring with default rx_filter to get rx status
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0223/1887] rtc: dev: zero-initialize struct rtc_wkalrm to prevent information leak
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0222/1887] wifi: ath11k: reset ar->num_stations on hardware start Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0224/1887] rtc: mpfs: fix unchecked devm_clk_get() error pointer in probe() Greg Kroah-Hartman
` (775 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liu Dalin, Alexandre Belloni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Dalin <liudalin@kylinsec.com.cn>
[ Upstream commit 0ee5c5d804d592a8328a425b9274487d393d3a05 ]
The struct rtc_wkalrm has padding holes after the 'pending' member.
When returned to userspace via the RTC_WKALRM_RD ioctl, uninitialized
kernel stack data residing in these holes may be leaked.
Zero-initialize the struct at declaration to eliminate this information
leak risk.
Fixes smatch warnings:
- drivers/rtc/dev.c:392 rtc_dev_ioctl() warn: check that 'alarm' doesn't
leak information (struct has a hole after 'pending')
Fixes: 36e14f5fdfdf ("rtc: rename core files")
Assisted-by: smatch:2.0 [static analysis]
Signed-off-by: Liu Dalin <liudalin@kylinsec.com.cn>
Link: https://patch.msgid.link/B28B7DE18F3A9447+20260827015444.3314227-1-liudalin@kylinsec.com.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/rtc/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c
index 4aad9bb998683..8ff910017b105 100644
--- a/drivers/rtc/dev.c
+++ b/drivers/rtc/dev.c
@@ -207,7 +207,7 @@ static long rtc_dev_ioctl(struct file *file,
struct rtc_device *rtc = file->private_data;
const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
- struct rtc_wkalrm alarm;
+ struct rtc_wkalrm alarm = { 0 };
struct rtc_param param;
void __user *uarg = (void __user *)arg;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0224/1887] rtc: mpfs: fix unchecked devm_clk_get() error pointer in probe()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0223/1887] rtc: dev: zero-initialize struct rtc_wkalrm to prevent information leak Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0225/1887] wifi: cfg80211: preserve hidden-group beacon IE ownership Greg Kroah-Hartman
` (774 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manush Prajwal, Conor Dooley,
Alexandre Belloni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manush Prajwal <manushprajwal555@gmail.com>
[ Upstream commit ac41b05d15db3134e839148290d67415ee0bdb58 ]
devm_clk_get(&pdev->dev, "rtcref")'s return value was passed straight
into clk_get_rate() without checking it for an error first, unlike the
"rtc" clock a few lines above which is correctly checked with
IS_ERR(). clk_get_rate() only guards against a NULL clk, not an error
pointer:
if (!clk)
return 0;
...
rate = clk_core_get_rate_recalc(clk->core);
so if devm_clk_get() ever returns an error pointer here (for example
ERR_PTR(-EPROBE_DEFER), which is the normal, expected outcome if the
clkcfg clock-provider this RTC depends on has not registered its
clocks yet by the time this driver probes), clk_get_rate() dereferences
that error pointer instead of returning 0, crashing instead of letting
probe defer.
Capture the clock in the existing 'clk' local and check it with
IS_ERR() before calling clk_get_rate(), matching the handling already
used for the "rtc" clock in this same function.
Signed-off-by: Manush Prajwal <manushprajwal555@gmail.com>
Fixes: 0b31d703598d ("rtc: Add driver for Microchip PolarFire SoC")
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://patch.msgid.link/6a9d4b02.7d74b517.206c4c.75f8@mx.google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/rtc/rtc-mpfs.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-mpfs.c b/drivers/rtc/rtc-mpfs.c
index d329e0eb66c44..e530b7868f999 100644
--- a/drivers/rtc/rtc-mpfs.c
+++ b/drivers/rtc/rtc-mpfs.c
@@ -256,8 +256,12 @@ static int mpfs_rtc_probe(struct platform_device *pdev)
return ret;
}
+ clk = devm_clk_get(&pdev->dev, "rtcref");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
/* prescaler hardware adds 1 to reg value */
- prescaler = clk_get_rate(devm_clk_get(&pdev->dev, "rtcref")) - 1;
+ prescaler = clk_get_rate(clk) - 1;
if (prescaler > MAX_PRESCALER_COUNT) {
dev_dbg(&pdev->dev, "invalid prescaler %lu\n", prescaler);
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0225/1887] wifi: cfg80211: preserve hidden-group beacon IE ownership
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0224/1887] rtc: mpfs: fix unchecked devm_clk_get() error pointer in probe() Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0226/1887] ASoC: codecs: rt286: Revert delay value for jack setup Greg Kroah-Hartman
` (773 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yilin Zhang, Zhao Li, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
[ Upstream commit cc45f313d85533d647ce619326302aad6f797c14 ]
A hidden-group probe-response entry borrows its beacon IEs from the
group's beacon entry. cfg80211_update_assoc_bss_entry() can pass such
an entry to cfg80211_update_known_bss() when merging scan entries
after a channel switch.
Copying the borrowed beacon_ies into the associated entry gives the
same allocation two owners. Releasing the group's beacon entry can
then leave the associated entry pointing to freed IEs, which are
freed again when that entry is released.
Skip beacon IE replacement when the source entry belongs to a hidden
group. Preserve probe-response processing, the subsequent metadata
updates, and the existing rejection path for conflicting hidden
beacon updates.
Fixes: 0afd425b1b64 ("cfg80211: fix duplicated scan entries after channel switch")
Reported-by: Yilin Zhang <yilinzhang@moonshot.ai>
Closes: https://lore.kernel.org/linux-wireless/20260901080427.1983015-1-yilinzhang@moonshot.ai/
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/scan.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index a8901e07e96d6..d6bd95857abf2 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1784,20 +1784,22 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
return false;
}
- old = rcu_access_pointer(known->pub.beacon_ies);
+ if (!new->pub.hidden_beacon_bss) {
+ old = rcu_access_pointer(known->pub.beacon_ies);
- rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
+ rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
- /* Override IEs if they were from a beacon before */
- if (old == rcu_access_pointer(known->pub.ies))
- rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+ /* Override IEs if they were from a beacon before */
+ if (old == rcu_access_pointer(known->pub.ies))
+ rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
- cfg80211_update_hidden_bsses(known,
- rcu_access_pointer(new->pub.beacon_ies),
- old);
+ cfg80211_update_hidden_bsses(known,
+ rcu_access_pointer(new->pub.beacon_ies),
+ old);
- if (old)
- kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+ if (old)
+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+ }
}
known->pub.beacon_interval = new->pub.beacon_interval;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0226/1887] ASoC: codecs: rt286: Revert delay value for jack setup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0225/1887] wifi: cfg80211: preserve hidden-group beacon IE ownership Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0227/1887] ASoC: codecs: rt274: Fix format setting for 44100 rate Greg Kroah-Hartman
` (772 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cezary Rojewski, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit d30fba93ebfc11e4604a7fcc73fdf28684191dde ]
Fat fingered the change when reorganizing the jack-detect
initialization. Equivalent changes for rt274 and rt298:
Commit a43b4394bb35 ("ASoC: codecs: rt274: Always init jack_detect_work")
Commit 1eb73102da28 ("ASoC: codecs: rt298: Reorganize jack detect handling")
carry no update to the delay value.
>From user perspective, no difference has been observed between 1250 and
50 values on Intel's SkyLake, KabyLake and AmberLake configurations.
Fixes: 3082afe097cc ("ASoC: codecs: rt286: Reorganize jack detect handling")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260918111745.3589393-1-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/rt286.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index ceb56647e369e..42ed864c062f9 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -951,7 +951,7 @@ static int rt286_probe(struct snd_soc_component *component)
if (rt286->i2c->irq)
schedule_delayed_work(&rt286->jack_detect_work,
- msecs_to_jiffies(50));
+ msecs_to_jiffies(1250));
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0227/1887] ASoC: codecs: rt274: Fix format setting for 44100 rate
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0226/1887] ASoC: codecs: rt286: Revert delay value for jack setup Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0228/1887] Bluetooth: hci_core: free the HCI ID if naming fails Greg Kroah-Hartman
` (771 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amadeusz Sławiński,
Cezary Rojewski, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit 6eda8938a790f65bd24fcfaae7b40ad4613fb7a2 ]
As per specification, Sample Base Rate (bit 14)
shall be set to 1 for 44.1 kHz.
Fixes: c7e79b2b2d2d ("ASoC: rt274: add rt274 codec driver")
Signed-off-by: Amadeusz Sławiński <amade@asmblr.net>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260918111745.3589393-2-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/rt274.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c
index 4667bf7561b13..f664a6e139239 100644
--- a/sound/soc/codecs/rt274.c
+++ b/sound/soc/codecs/rt274.c
@@ -619,9 +619,11 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
unsigned int val = 0;
int d_len_code = 0, c_len_code = 0;
+ /* bit 14 Sample Rate Base, 0: 48kHz 1: 44.1kHz */
switch (params_rate(params)) {
- /* bit 14 0:48K 1:44.1K */
case 44100:
+ val |= BIT(14);
+ break;
case 48000:
break;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0228/1887] Bluetooth: hci_core: free the HCI ID if naming fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0227/1887] ASoC: codecs: rt274: Fix format setting for 44100 rate Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0229/1887] Bluetooth: btintel: validate DDC record lengths Greg Kroah-Hartman
` (770 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit d1ac915fb4184faad1b62148be50f317de7c24b5 ]
hci_register_dev() allocates an ID before calling dev_set_name().
If naming fails, it returns without releasing that ID. The device has
not been registered and hdev->id has not been assigned, so the normal
unregister path cannot release it.
Free the allocated ID before returning the naming error.
Fixes: dcda165706b9 ("Bluetooth: hci_core: Fix build warnings")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reported-by: Changyul Lee <lcy8047@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 056de77b4adc4..b9175d7453666 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2596,8 +2596,10 @@ int hci_register_dev(struct hci_dev *hdev)
return id;
error = dev_set_name(&hdev->dev, "hci%u", id);
- if (error)
+ if (error) {
+ ida_free(&hci_index_ida, id);
return error;
+ }
hdev->name = dev_name(&hdev->dev);
hdev->id = id;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0229/1887] Bluetooth: btintel: validate DDC record lengths
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0228/1887] Bluetooth: hci_core: free the HCI ID if naming fails Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0230/1887] net/mctp: publish the mctp_dev only after it is initialised Greg Kroah-Hartman
` (769 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sai Teja Aluvala,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
[ Upstream commit c9c15d4d8956df8c564f7c210e4dc5b9b820d97a ]
Parse DDC record lengths in unsigned storage so 0xFF does not wrap.
Reject records smaller than the mandatory three-byte header, records
exceeding U8_MAX, and records exceeding remaining firmware bytes before
issuing Intel_Write_DDC.
This issue was reported by Claude Mythos.
Fixes: 145f2368c5fd ("Bluetooth: btintel: Add Device Configuration support")
Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 1cba08e9403a4..91162384835d9 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -363,8 +363,16 @@ int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
/* DDC file contains one or more DDC structure which has
* Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2).
*/
- while (fw->size > fw_ptr - fw->data) {
- u8 cmd_plen = fw_ptr[0] + sizeof(u8);
+ while (fw->size > (size_t)(fw_ptr - fw->data)) {
+ size_t remaining = fw->size - (fw_ptr - fw->data);
+ unsigned int cmd_plen = fw_ptr[0] + 1U;
+
+ if (cmd_plen < 3 || cmd_plen > U8_MAX || cmd_plen > remaining) {
+ bt_dev_err(hdev, "Malformed DDC record (plen=%u, remaining=%zu)",
+ cmd_plen, remaining);
+ release_firmware(fw);
+ return -EINVAL;
+ }
skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
HCI_INIT_TIMEOUT);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0230/1887] net/mctp: publish the mctp_dev only after it is initialised
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0229/1887] Bluetooth: btintel: validate DDC record lengths Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0231/1887] net/sched: cls_api: reclaim an empty proto on the error path Greg Kroah-Hartman
` (768 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Binbin Deng, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Binbin Deng <18983559317@163.com>
[ Upstream commit aadf655e8ea9a8ffa24bb8d69f504572e8d18181 ]
mctp_add_dev() links the new mctp_dev into dev->mctp_ptr before mdev->dev
is assigned, so a reader that picks the device up in that window
dereferences a net_device pointer that is still NULL:
KASAN: null-ptr-deref in range [0x00000000000000b0-0x00000000000000b7]
Call Trace:
<TASK>
? __pfx_mctp_sendmsg (./include/linux/sockptr.h:49)
? __pfx_mctp_dst_output (net/mctp/route.c:41)
? selinux_socket_sendmsg (security/selinux/hooks.c:5278)
____sys_sendmsg (net/socket.c:775 (discriminator 1) net/socket.c:790
(discriminator 1) net/socket.c:2684 (discriminator 1))
? __pfx_____sys_sendmsg (net/socket.c:1131)
? __pfx_copy_msghdr_from_user (net/socket.c:2590)
? update_cfs_rq_load_avg (kernel/sched/fair.c:5478)
___sys_sendmsg (net/socket.c:2738)
? __pfx____sys_sendmsg (net/socket.c:2625)
? perf_event_task_tick (./include/linux/rcupdate.h:838)
? sched_tick (kernel/sched/core.c:5818)
? clockevents_program_event (kernel/time/clockevents.c:372)
? fdget (./include/linux/rcupdate.h:873 fs/file.c:1100)
__sys_sendmsg (net/socket.c:2770)
? __pfx___sys_sendmsg (net/socket.c:2751)
do_syscall_64 (arch/x86/entry/syscall_64.c:63)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Fix by publishing only once the object is fully initialised:
__mctp_dev_get() runs under rcu_read_lock() only and hands
this object to readers as soon as mctp_ptr is assigned, so
they must never observe mdev->dev == NULL.
Fixes: 583be982d934 ("mctp: Add device handling and netlink interface")
Signed-off-by: Binbin Deng <18983559317@163.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/729830b8.130.1a0c945579d.Coremail.18983559317@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mctp/device.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/mctp/device.c b/net/mctp/device.c
index fd368249246df..47407c07afc27 100644
--- a/net/mctp/device.c
+++ b/net/mctp/device.c
@@ -352,13 +352,13 @@ static struct mctp_dev *mctp_add_dev(struct net_device *dev)
mdev->net = mctp_default_net(dev_net(dev));
- /* associate to net_device */
refcount_set(&mdev->refs, 1);
- rcu_assign_pointer(dev->mctp_ptr, mdev);
-
dev_hold(dev);
mdev->dev = dev;
+ /* Associate to net_device, publish the mdev. */
+ rcu_assign_pointer(dev->mctp_ptr, mdev);
+
return mdev;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0231/1887] net/sched: cls_api: reclaim an empty proto on the error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0230/1887] net/mctp: publish the mctp_dev only after it is initialised Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0232/1887] netfilter: ipset: do not update comments from kernel-side adds Greg Kroah-Hartman
` (767 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (nipa), Jamal Hadi Salim,
Simon Horman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 0bb8eab29b55045281a4963d4557f2776cdf8cfa ]
Two racing tc filter add requests on the same chain/prio of an
unlocked classifier both run change() on the shared proto and both
can fail: the winner's tcf_chain_tp_delete_empty() attempt gives up
because the loser's handle is still in the idr, and the loser's
error path drops only its own reference without a second reclamation
attempt. The empty proto stays linked in the chain, holding the
chain reference, a block reference and the classifier module
reference until the chain or block is torn down.
Reclaim the proto on the error path of any failed request that holds
a proto reference. The reclamation is emptiness-gated:
tcf_chain_tp_delete_empty() unlinks the proto only when
delete_empty() admits it is empty, so a live shared proto is never
unlinked. A proto the request created is reclaimed unconditionally -
it is the only owner, so marking it for deletion is safe even without
a delete_empty callback. Classifiers without one (the check marks the
proto unconditionally) are rtnl-serialized, so the raced window this
guard closes cannot arise for them.
This is a follow-up to commit d4e359b3608a ("net/sched: cls_api: fix
teardown of an adopted proto on insert-race loss"), which stopped the
loser of the insert race from unlinking the winner's live proto but
left the empty-proto residual in place.
Conditions to recreate:
- CONFIG_NET_CLS_FLOWER=y; veth pair
- tc qdisc add dev veth0 ingress
- two concurrent `tc filter add dev veth0 ingress protocol ip pref 1
flower skip_sw ... action drop` (both fail in fl_hw_replace_filter
after publishing their handle in the idr); repeat in a loop
- an empty flower tp stays linked after both requests fail; visible
as a bare `filter protocol ip pref 1 flower chain 0` header in
`tc filter show` with no filter entries
- CAP_NET_ADMIN (namespace-local via unshare -Urn suffices)
Fixes: 8b64678e0af8 ("net: sched: refactor tp insert/delete for concurrent execution")
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260805134049.927864-1-victor@mojatatu.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-JCOT.v1.20260910090924@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_api.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 341128a00420c..dbaf6e72aa2da 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -2211,7 +2211,20 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
}
errout:
- if (err && tp_state == TP_CREATED)
+ if (err && !IS_ERR_OR_NULL(tp) &&
+ (tp_state == TP_CREATED || tp->ops->delete_empty))
+ /*
+ * The request is dropping its reference to tp. If it was
+ * the last user (the idr is empty now), reclaim the proto.
+ * A tp this request created is reclaimed unconditionally:
+ * it is the only owner, so marking it for deletion is
+ * safe. Otherwise only classifiers with a delete_empty
+ * callback are reclaimed -- the callback admits an empty
+ * proto only, so a live shared proto is never unlinked.
+ * Classifiers without one (deleting is set
+ * unconditionally) are rtnl-serialized, so the raced
+ * window this guard closes cannot arise for them.
+ */
tcf_chain_tp_delete_empty(chain, tp, rtnl_held, NULL);
errout_tp:
if (chain) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0232/1887] netfilter: ipset: do not update comments from kernel-side adds
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0231/1887] net/sched: cls_api: reclaim an empty proto on the error path Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0233/1887] Bluetooth: hci_sync: dont drain cmd_sync backlog on unregister Greg Kroah-Hartman
` (766 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Florian Westphal, Pablo Neira Ayuso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit a442c8a89fb9c531f9d6ab86120c31decd778d51 ]
'Fixes' commit stopped calling ip_set_init_comment() for hash types
from kernel-side-adds (xtables .. -j SET). ip_set_init_comment() says:
"The kadt functions don't use the comment extensions in any way."
But bitmap set type calls the function from kadt cb too.
While this appears to be safe (serialized via the set spinlock), it seems
better to not call the init function either, least of all to keep
behaviour consistent.
ip_set_list calls ip_set_init_comment() only from uadt cb, it can be
kept as-is.
This was triggered by yet another LLM review, hinting that the existing
rcu_dereference_protected() cannot be downgraded to only check if the
nfnl mutex is held.
Fixes: f30415929be8 ("netfilter: ipset: do not update comments from kernel-side hash adds")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
index 605d54d2bd7e6..3dc2ebbe4800c 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -157,7 +157,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
if (SET_WITH_COUNTER(set))
ip_set_init_counter(ext_counter(x, set), ext);
- if (SET_WITH_COMMENT(set))
+ if (SET_WITH_COMMENT(set) && !ext->target)
ip_set_init_comment(set, ext_comment(x, set), ext);
if (SET_WITH_SKBINFO(set))
ip_set_init_skbinfo(ext_skbinfo(x, set), ext);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0233/1887] Bluetooth: hci_sync: dont drain cmd_sync backlog on unregister
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0232/1887] netfilter: ipset: do not update comments from kernel-side adds Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0234/1887] net: systemport: Fix RUNT MIB counter register offset calculation Greg Kroah-Hartman
` (765 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+217e3f1283cafe80586e,
Nguyen Ngoc Thang, Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
[ Upstream commit b1f24c1ab52345e810c42a1a81286cb5a7c92252 ]
hci_unregister_dev() disables cmd_work and cmd_timer, then calls
hci_cmd_sync_clear(), whose cancel_work_sync() waits for
hci_cmd_sync_work() to return. That worker dequeues and runs every
entry on cmd_sync_work_list. With cmd_work disabled nothing reaches
the controller, so each queued HCI command waits the full
HCI_CMD_TIMEOUT (2s).
The backlog has no bound. Userspace can keep queuing MGMT commands
such as MGMT_OP_GET_CLOCK_INFO against a controller that doesn't
answer. Closing /dev/vhci then blocks in vhci_release() for
backlog * 2s:
INFO: task syz-executor:5749 blocked for more than 143 seconds.
cancel_work_sync
hci_cmd_sync_clear
hci_unregister_dev
vhci_release
In a local reproduction the backlog held more than 5000 entries,
which comes to hours of hang.
Stop the worker from taking new entries once HCI_UNREGISTER is set,
and wake any request still waiting with -ENODEV before cancelling
the work. The entries left over are destroyed with -ECANCELED by the
existing sweep in hci_cmd_sync_clear(). They stay on the list until
the work has stopped, so hci_cmd_sync_dequeue() and friends still see
them. A callback already running may still issue another command,
which delays unregister by at most one timeout per remaining command,
not by the whole backlog.
Fixes: 008ee9eb8a11 ("Bluetooth: hci_sync: Fix not processing all entries on cmd_sync_work")
Reported-by: syzbot+217e3f1283cafe80586e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=217e3f1283cafe80586e
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_sync.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 5825ab89eb22a..4e4eae12ee3fb 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -308,6 +308,10 @@ static void hci_cmd_sync_work(struct work_struct *work)
while (1) {
struct hci_cmd_sync_work_entry *entry;
+ /* Leave the backlog to hci_cmd_sync_clear() */
+ if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
+ break;
+
mutex_lock(&hdev->cmd_sync_work_lock);
entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
struct hci_cmd_sync_work_entry,
@@ -677,6 +681,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
{
struct hci_cmd_sync_work_entry *entry, *tmp;
+ /* cmd_work is disabled, the pending request can only time out */
+ hci_cmd_sync_cancel_sync(hdev, ENODEV);
cancel_work_sync(&hdev->cmd_sync_work);
cancel_work_sync(&hdev->reenable_adv_work);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0234/1887] net: systemport: Fix RUNT MIB counter register offset calculation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0233/1887] Bluetooth: hci_sync: dont drain cmd_sync backlog on unregister Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0235/1887] octeontx2-af: mcs: Fix SC resource cleanup loop Greg Kroah-Hartman
` (764 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit 242935adfeb096f09b29fb2cfcf12f9eb2911fc6 ]
In UniMAC hardware, there is a 0xC byte gap between the RX MIB counters
and the TX MIB counters, and a second 0xC byte gap between the TX MIB
counters and the RX RUNT MIB counters.
In bcm_sysport_update_mib_counters(), 'offset' was only set to
UMAC_MIB_STAT_OFFSET (0xC) for all non-RX counters, omitting the second
0xC gap for BCM_SYSPORT_STAT_RUNT counters. As a result, all 4 RUNT MIB
counters were read from unmapped gap register space.
Fix this by setting offset to 2 * UMAC_MIB_STAT_OFFSET (0x18) when
reading BCM_SYSPORT_STAT_RUNT counters.
Fixes: 80105befdb4b ("net: systemport: add Broadcom SYSTEMPORT Ethernet MAC driver")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260922232440.598918-6-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bcmsysport.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index e53ab9b5482e1..c9e6a3583f2aa 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -422,8 +422,10 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
if (priv->is_lite)
continue;
- if (s->type != BCM_SYSPORT_STAT_MIB_RX)
+ if (s->type == BCM_SYSPORT_STAT_MIB_TX)
offset = UMAC_MIB_STAT_OFFSET;
+ else if (s->type == BCM_SYSPORT_STAT_RUNT)
+ offset = 2 * UMAC_MIB_STAT_OFFSET;
val = umac_readl(priv, UMAC_MIB_START + j + offset);
break;
case BCM_SYSPORT_STAT_RXCHK:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0235/1887] octeontx2-af: mcs: Fix SC resource cleanup loop
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0234/1887] net: systemport: Fix RUNT MIB counter register offset calculation Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0236/1887] tipc: prevent GCM nonce reuse on peer key changes Greg Kroah-Hartman
` (763 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baha Mesleh, Subrat Pandey,
Simon Horman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baha Mesleh <baha.mesleh@nokia.com>
[ Upstream commit cdef07f3002f708a345392ee28d0d9bfac8383a1 ]
The SC resource cleanup and statistics loops were incorrectly
iterating over secy.max instead of sc.max, so the highest SC id
could be left allocated across teardown or FLR. Use sc.max as
the loop bound.
Fixes: cfc14181d497 ("octeontx2-af: cn10k: mcs: Manage the MCS block hardware resources")
Signed-off-by: Baha Mesleh <baha.mesleh@nokia.com>
Signed-off-by: Subrat Pandey <subratp@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260922102149.2078168-3-subratp@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/marvell/octeontx2/af/mcs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
index 211c10aa5880f..30c672d526a0c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
@@ -314,7 +314,7 @@ int mcs_clear_all_stats(struct mcs *mcs, u16 pcifunc, int dir)
}
/* Clear SC stats */
- for (id = 0; id < map->secy.max; id++) {
+ for (id = 0; id < map->sc.max; id++) {
if (map->sc2pf_map[id] != pcifunc)
continue;
mcs_clear_stats(mcs, MCS_SC_STATS, id, dir);
@@ -738,7 +738,7 @@ int mcs_free_all_rsrc(struct mcs *mcs, int dir, u16 pcifunc)
}
/* free sc entries */
- for (id = 0; id < map->secy.max; id++) {
+ for (id = 0; id < map->sc.max; id++) {
if (map->sc2pf_map[id] != pcifunc)
continue;
mcs_free_rsrc(&map->sc, map->sc2pf_map, id, pcifunc);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0236/1887] tipc: prevent GCM nonce reuse on peer key changes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0235/1887] octeontx2-af: mcs: Fix SC resource cleanup loop Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0237/1887] net/sched: fq_codel: match the no-drop threshold to the packet size Greg Kroah-Hartman
` (762 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean, Tung Nguyen,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
[ Upstream commit 512ccd3d0e91e791fb37442aa0a2599aca19783d ]
TIPC can encrypt traffic between nodes using a different transmit key
for each node. In this mode, the AES-GCM nonce for a packet sent to a
known peer consists of a 32-bit prefix (a per-key salt XOR the peer's
address) followed by a 64-bit counter. That counter is stored in the
peer's RX crypto object. When the peer reports a change in which key
it uses to receive packets, TIPC resets this counter. The sender can
still be using the same TX key and salt, so subsequent packets reuse
earlier nonces. This nonce reuse breaks confidentiality and exposes
GCM's authentication key. This makes forgeries trivial: an attacker
can exploit CTR malleability to alter captured ciphertexts and use the
recovered authentication key to compute a valid tag for the modified
ciphertext, under the same key and nonce.
Use the TX key's existing aead->seqno counter instead. All encryptions
using that key object share the same atomic counter, so concurrent
encryptions get distinct nonce counter values. The counter survives
key activation and peer reconnection, and peer key-status reports
cannot reset it. This prevents those transitions from causing nonce
reuse while the same TX key remains installed.
The nonce format is unchanged, and receivers do not require consecutive
counter values, so sharing the counter across peers remains compatible
with existing receivers. A pre-existing check still invokes key
revocation in the unlikely event that the counter wraps to zero.
Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20260924202105.3722778-1-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/tipc/crypto.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
index d86b3a8f7078b..dc2239b2cf852 100644
--- a/net/tipc/crypto.c
+++ b/net/tipc/crypto.c
@@ -144,7 +144,7 @@ struct tipc_tfm {
* @rcu: struct rcu_head
* @key: the aead key
* @gen: the key's generation
- * @seqno: the key seqno (cluster scope)
+ * @seqno: the per-key TX nonce counter
* @refcnt: the key reference counter
*/
struct tipc_aead {
@@ -190,7 +190,6 @@ struct tipc_crypto_stats {
* @rekeying_intv: rekeying interval (in minutes)
* @stats: the crypto statistics
* @name: the crypto name
- * @sndnxt: the per-peer sndnxt (TX)
* @timer1: general timer 1 (jiffies)
* @timer2: general timer 2 (jiffies)
* @working: the crypto is working or not
@@ -219,7 +218,6 @@ struct tipc_crypto {
struct tipc_crypto_stats __percpu *stats;
char name[48];
- atomic64_t sndnxt ____cacheline_aligned;
unsigned long timer1;
unsigned long timer2;
union {
@@ -1060,14 +1058,11 @@ static int tipc_ehdr_build(struct net *net, struct tipc_aead *aead,
WARN_ON(skb_headroom(skb) < ehsz);
ehdr = (struct tipc_ehdr *)skb_push(skb, ehsz);
- /* Obtain a seqno first:
- * Use the key seqno (= cluster wise) if dest is unknown or we're in
- * cluster key mode, otherwise it's better for a per-peer seqno!
+ /*
+ * Keep the nonce unique for the lifetime of the TX key,
+ * including key state changes and peer reconnection.
*/
- if (!__rx || aead->mode == CLUSTER_KEY)
- seqno = atomic64_inc_return(&aead->seqno);
- else
- seqno = atomic64_inc_return(&__rx->sndnxt);
+ seqno = atomic64_inc_return(&aead->seqno);
/* Revoke the key if seqno is wrapped around */
if (unlikely(!seqno))
@@ -1246,7 +1241,6 @@ void tipc_crypto_key_flush(struct tipc_crypto *c)
tipc_crypto_key_set_state(c, 0, 0, 0);
for (k = KEY_MIN; k <= KEY_MAX; k++)
tipc_crypto_key_detach(c->aead[k], &c->lock);
- atomic64_set(&c->sndnxt, 0);
spin_unlock_bh(&c->lock);
}
@@ -1393,8 +1387,6 @@ static struct tipc_aead *tipc_crypto_key_pick_tx(struct tipc_crypto *tx,
* It also considers if peer has no key, then we need to make own master key
* (if any) taking over i.e. starting grace period and also trigger key
* distributing process.
- *
- * The "per-peer" sndnxt is also reset when the peer key has switched.
*/
static void tipc_crypto_key_synch(struct tipc_crypto *rx, struct sk_buff *skb)
{
@@ -1445,7 +1437,6 @@ static void tipc_crypto_key_synch(struct tipc_crypto *rx, struct sk_buff *skb)
if (cur)
tipc_aead_users_dec(tx->aead[cur], 0);
- atomic64_set(&rx->sndnxt, 0);
/* Mark the point TX key users changed */
tx->timer1 = jiffies;
@@ -1510,7 +1501,6 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,
tipc_crypto_key_set_state(c, 0, 0, 0);
atomic_set(&c->key_distr, 0);
atomic_set(&c->peer_rx_active, 0);
- atomic64_set(&c->sndnxt, 0);
c->timer1 = jiffies;
c->timer2 = jiffies;
c->rekeying_intv = TIPC_REKEYING_INTV_DEF;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0237/1887] net/sched: fq_codel: match the no-drop threshold to the packet size
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0236/1887] tipc: prevent GCM nonce reuse on peer key changes Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0238/1887] net/sched: sch_codel: " Greg Kroah-Hartman
` (761 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (nipa), Jamal Hadi Salim,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit d031465acc362866f27e4f8f79cfecf1037fe2e5 ]
commit d9ebd8f9aa8b ("net/sched: fq_codel: clamp default quantum and mtu")
clamped both q->quantum and q->cparams.mtu to [256, FQ_CODEL_QUANTUM_MAX].
The two fields mean different things: quantum is a DRR credit that wants
the 256 floor, but cparams.mtu is the CoDel no-drop threshold
(codel_impl.h "*backlog <= params->mtu"). On a link whose maximum
transmitted packet size is below 256, the floor extends CoDel's
minimum-backlog exemption beyond one packet and delays drop or mark
eligibility by several small packets.
Split the clamp. quantum keeps [256, FQ_CODEL_QUANTUM_MAX]; cparams.mtu
tracks psched_mtu() (the device MTU plus its hard-header length) with
only the upper bound that guards the original overflow (psched_mtu()
wrapping to ~2 GiB on a huge-MTU device).
Conditions to recreate the bug: attach an fq_codel qdisc on a link
whose MTU plus hard_header_len is below 256 (e.g. a CAN interface). At
that MTU the no-drop threshold must equal the device MTU plus its
hard-header length; before this patch it was forced to 256.
Basic Testing done: with dev->mtu=100 and hard_header_len=14, a
return probe on fq_codel_init() observed cparams.mtu change from 256 to 114
Fixes: d9ebd8f9aa8b ("net/sched: fq_codel: clamp default quantum and mtu")
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260819143136.57350-1-jhs@mojatatu.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-34MS.v1.20260925165535@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_fq_codel.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index ac2f643dd8427..08cb94bf5950b 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -503,8 +503,8 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
q->flows_cnt = 1024;
q->memory_limit = 32 << 20; /* 32 MBytes */
q->drop_batch_size = 64;
- mtu = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 256, FQ_CODEL_QUANTUM_MAX);
- q->quantum = mtu;
+ mtu = min_t(u32, psched_mtu(qdisc_dev(sch)), FQ_CODEL_QUANTUM_MAX);
+ q->quantum = clamp_t(u32, mtu, 256, FQ_CODEL_QUANTUM_MAX);
INIT_LIST_HEAD(&q->new_flows);
INIT_LIST_HEAD(&q->old_flows);
codel_params_init(&q->cparams);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0238/1887] net/sched: sch_codel: match the no-drop threshold to the packet size
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0237/1887] net/sched: fq_codel: match the no-drop threshold to the packet size Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0239/1887] net: bcmgenet: fix NULL dereference in set_coalesce before first open Greg Kroah-Hartman
` (760 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (nipa), Jamal Hadi Salim,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 54518e0e827f4ca9229ae657022c60bf60f5c1bf ]
commit 6439461f1618 ("net/sched: sch_codel: clamp default mtu to avoid
disabling CoDel") clamped q->params.mtu to [256, 1 << 20]. The value is
the CoDel no-drop threshold (codel_impl.h "*backlog <= params->mtu"), so
on a link whose maximum transmitted packet size is below 256 the floor
extends CoDel's minimum-backlog exemption beyond one packet and delays
drop or mark eligibility by several small packets.
Keep the upper bound that guards the original overflow (psched_mtu()
wrapping to ~2 GiB on a huge-MTU device) but drop the 256 floor, so the
threshold tracks the real device packet size.
Conditions to recreate the bug: attach a codel qdisc on a link whose
MTU plus hard_header_len is below 256 (e.g. a CAN interface). At that
MTU the no-drop threshold must equal the device MTU plus its
hard-header length; before this patch it was forced to 256.
Requires CAP_NET_ADMIN in a user namespace.
Fixes: 6439461f1618 ("net/sched: sch_codel: clamp default mtu to avoid disabling CoDel")
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260819143136.57350-1-jhs@mojatatu.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-34MS.v1.20260925165535@mojatatu.com.2
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_codel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
index c05be1eeea566..1f30dc76d20c7 100644
--- a/net/sched/sch_codel.c
+++ b/net/sched/sch_codel.c
@@ -228,7 +228,7 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt,
codel_params_init(&q->params);
codel_vars_init(&q->vars);
codel_stats_init(&q->stats);
- q->params.mtu = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 256, 1 << 20);
+ q->params.mtu = min_t(u32, psched_mtu(qdisc_dev(sch)), 1 << 20);
if (opt) {
int err = codel_change(sch, opt, extack);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0239/1887] net: bcmgenet: fix NULL dereference in set_coalesce before first open
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0238/1887] net/sched: sch_codel: " Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0240/1887] tcp: refresh TS.Recent for accepted old ACKs Greg Kroah-Hartman
` (759 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolai Buchwitz <nb@tipi-net.de>
[ Upstream commit 19419faf58dfe5bcc8a9e60e622976c5f8e3ddc1 ]
The Rx ring priv and index are only set in bcmgenet_init_rx_ring(),
which runs at open. Setting the Rx coalescing parameters on an interface
that was never opened, e.g. "ethtool -C eth0 rx-usecs 50", dereferences
a NULL ring->priv. The oops happens with RTNL held, so networking
stays stuck until a reboot:
Unable to handle kernel paging request at virtual address 0000000000002788
pc : bcmgenet_set_rx_coalesce.isra.0+0x10/0x88
lr : bcmgenet_set_coalesce+0xe8/0x180
Call trace:
bcmgenet_set_rx_coalesce.isra.0+0x10/0x88 (P)
__ethnl_set_coalesce.isra.0+0x490/0x570
ethnl_set_coalesce+0x48/0xc0
ethnl_default_set_doit+0xf4/0x230
genl_family_rcv_msg_doit+0xe8/0x160
genl_rcv_msg+0x220/0x2a0
netlink_rcv_skb+0x68/0x140
genl_rcv+0x40/0x60
netlink_unicast+0x338/0x3c0
netlink_sendmsg+0x19c/0x3f8
__sock_sendmsg+0x64/0xc0
__sys_sendto+0x124/0x198
__arm64_sys_sendto+0x30/0x48
Set priv and index at probe. Writing the registers while the interface
is down is harmless because open resets the MAC and
bcmgenet_init_rx_coalesce() reapplies the stored values.
It was observed on a Raspberry Pi CM4, but should apply to all other
genet devices.
Fixes: 9f4ca05827a2 ("net: bcmgenet: Add support for adaptive RX coalescing")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260928105642.856210-1-nb@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index c729da84a19bb..9753b48cfac47 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -4079,8 +4079,11 @@ static int bcmgenet_probe(struct platform_device *pdev)
netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1);
/* Set default coalescing parameters */
- for (i = 0; i <= priv->hw_params->rx_queues; i++)
+ for (i = 0; i <= priv->hw_params->rx_queues; i++) {
+ priv->rx_rings[i].priv = priv;
+ priv->rx_rings[i].index = i;
priv->rx_rings[i].rx_max_coalesced_frames = 1;
+ }
/* Initialize u64 stats seq counter for 32bit machines */
for (i = 0; i <= GENET_MAX_MQ_CNT; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0240/1887] tcp: refresh TS.Recent for accepted old ACKs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0239/1887] net: bcmgenet: fix NULL dereference in set_coalesce before first open Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0241/1887] ipvs: fix missing counter decrement in lblc Greg Kroah-Hartman
` (758 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jeff Jo, Eric Dumazet,
David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Jo <jeffjo@openai.com>
[ Upstream commit 1b92780ae4fc3be64f05d97ed8833c445e73b0cf ]
A TCP packet can carry new data while acknowledging traffic in the
opposite direction. With overlapping traffic in both directions, a
delayed packet's acknowledgment can be older than one Linux has already
accepted, even when that packet fills a gap in the received data.
Linux accepts the data, but tcp_ack() takes the old_ack path and skips
updating TS.Recent, the timestamp saved for outgoing acknowledgments.
The reply therefore echoes an older timestamp. If the sender uses this
echo to measure round-trip time after a long idle period, its estimate
includes the idle time and can reduce its sending rate.
Update TS.Recent in old_ack using tcp_replace_ts_recent(), before SACK
processing can trigger a transmission. This reuses the existing timestamp
and sequence checks, including PAWS protection against old duplicate
packets. ACK validation already rejects old ACKs in SYN_RECV before this
path, so no additional state check is needed.
Echoing the timestamp of the packet that fills the receive gap follows
RFC 7323 section 4.3. In a socket reproduction with 300 seconds idle,
controlled reordering and retransmission to exercise timestamp-based RTT
sampling, the sender's smoothed round-trip time was 37.5 seconds without
the fix and 15.5 ms with it.
Fixes: 12fb3dd9dc3c ("tcp: call tcp_replace_ts_recent() from tcp_ack()")
Assisted-by: LLM sparse
Signed-off-by: Jeff Jo <jeffjo@openai.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/tcp_input.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 4ab6222ff180c..488b1926a2eb2 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4024,6 +4024,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
return 1;
old_ack:
+ /* An old ACK can carry new data. Update TS.Recent before SACK
+ * processing can trigger a retransmission.
+ */
+ if (flag & FLAG_UPDATE_TS_RECENT)
+ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
/* If data was SACKed, tag it and see if we should send more data.
* If data was DSACKed, see if we can undo a cwnd reduction.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0241/1887] ipvs: fix missing counter decrement in lblc
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0240/1887] tcp: refresh TS.Recent for accepted old ACKs Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0242/1887] ipvs: do not create invisible templates Greg Kroah-Hartman
` (757 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Anastasov, Pablo Neira Ayuso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <ja@ssi.bg>
[ Upstream commit bdac17779f46817f60103baf09f0370546c3f023 ]
LBLC may delete cache entries for destinations that are
removed or overloaded and replace them with available ones.
But ip_vs_lblc_new() forgets to decrement the tbl->entries
counter after calling ip_vs_lblc_del(). This can lead to
increased shrinking of the cache with every new garbage
collection.
Fixes: 2f3d771a35fe ("ipvs: do not use dest after ip_vs_dest_put in LBLC")
Link: https://sashiko.dev/#/patchset/0bdd5abe9968ded7ca2b9cb6844ba83d94cc8d53.1787318053.git.zhilinz%40nebusec.ai
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_lblc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index e2480f33a1963..9b0832f56f14e 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -205,6 +205,7 @@ ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, const union nf_inet_addr *daddr,
if (en->dest == dest)
return en;
ip_vs_lblc_del(en);
+ atomic_dec(&tbl->entries);
}
en = kmalloc(sizeof(*en), GFP_ATOMIC);
if (!en)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0242/1887] ipvs: do not create invisible templates
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0241/1887] ipvs: fix missing counter decrement in lblc Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:38 ` [PATCH 6.1 0243/1887] ipvs: filter some flags received in the backup server Greg Kroah-Hartman
` (756 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Anastasov, Pablo Neira Ayuso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <ja@ssi.bg>
[ Upstream commit 616cf5c06934364ab1002b420ebe975850b4b208 ]
The IP_VS_CONN_F_ONE_PACKET flag was implemented for normal
connections. When conn template inherits this flag from
dest->conn_flags it will not be hashed. As result, we will
create new template for every new normal connection.
Fix it to allow one template to be used by many normal
connections.
Fixes: 26ec037f9841 ("IPVS: one-packet scheduling")
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260916231652.127456-1-pablo%40netfilter.org
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_conn.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 44ebc7b1c8134..50a768bf83bc2 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -591,6 +591,9 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
if (cp->protocol != IPPROTO_UDP)
conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
flags = cp->flags;
+ /* Only visible templates can control multiple connections */
+ if (flags & IP_VS_CONN_F_TEMPLATE)
+ conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
/* Bind with the destination and its corresponding transmitter */
if (flags & IP_VS_CONN_F_SYNC) {
/* Synced conns are hashed, so they can not get this flag */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0243/1887] ipvs: filter some flags received in the backup server
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0242/1887] ipvs: do not create invisible templates Greg Kroah-Hartman
@ 2026-10-28 16:38 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0244/1887] netfilter: bpf: reject invalid NAT manipulation types Greg Kroah-Hartman
` (755 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Anastasov, Pablo Neira Ayuso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <ja@ssi.bg>
[ Upstream commit f96e91748f6304668fe647e686d199d7207d36f1 ]
While the IPVS SYNC protocol is not secure by design
we can still protect the backup server from messages that
can wreak havoc.
This commit addresses problems from received connection flags
or their combinations. We now drop messages as follows:
1. the NO_CPORT+TEMPLATE combination allows lookups for normal
connections to hit template which can break in many ways.
While the master does not sync connections with NO_CPORT flag,
i.e. before they are established, we still accept NO_CPORT
without TEMPLATE.
2. ONE_PACKET: it is not sent by master, so we do not
expect it in backup. Before now it was ignored by
IP_VS_CONN_F_BACKUP_MASK for protocol v1 while protocol
v0 created connections that are not hashed and dropped
immediately. Better to apply the IP_VS_CONN_F_BACKUP_MASK
also to the flags from v0 messages for consistency with v1.
Fixes: 87375ab47cd0 ("[IPVS]: ip_vs_ftp breaks connections using persistence")
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_sync.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 56e371b18fc2f..deac3c1715da3 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -950,6 +950,21 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa
ip_vs_conn_put(cp);
}
+/* Check for incompatible flags */
+static bool ip_vs_sync_validate_flags(u32 flags)
+{
+ /* We do not expect NO_CPORT, especially to allow lookups
+ * to hit templates
+ */
+ if (flags & IP_VS_CONN_F_NO_CPORT) {
+ if (flags & IP_VS_CONN_F_TEMPLATE)
+ return false;
+ }
+ if (flags & IP_VS_CONN_F_ONE_PACKET)
+ return false;
+ return true;
+}
+
/*
* Process received multicast message for Version 0
*/
@@ -973,8 +988,7 @@ static void ip_vs_process_message_v0(struct netns_ipvs *ipvs, const char *buffer
return;
}
s = (struct ip_vs_sync_conn_v0 *) p;
- flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
- flags &= ~IP_VS_CONN_F_HASHED;
+ flags = ntohs(s->flags);
if (flags & IP_VS_CONN_F_SEQ_MASK) {
opt = (struct ip_vs_sync_conn_options *)&s[1];
p += FULL_CONN_SIZE;
@@ -987,6 +1001,13 @@ static void ip_vs_process_message_v0(struct netns_ipvs *ipvs, const char *buffer
p += SIMPLE_CONN_SIZE;
}
+ if (!ip_vs_sync_validate_flags(flags)) {
+ IP_VS_DBG(2, "BACKUP v0, Invalid flags 0x%X\n", flags);
+ continue;
+ }
+ flags &= IP_VS_CONN_F_BACKUP_MASK;
+ flags |= IP_VS_CONN_F_SYNC;
+
state = ntohs(s->state);
if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
pp = ip_vs_proto_get(s->protocol);
@@ -1142,7 +1163,13 @@ static inline int ip_vs_proc_sync_conn(struct netns_ipvs *ipvs, __u8 *p, __u8 *m
}
/* Get flags and Mask off unsupported */
- flags = ntohl(s->v4.flags) & IP_VS_CONN_F_BACKUP_MASK;
+ flags = ntohl(s->v4.flags);
+ if (!ip_vs_sync_validate_flags(flags)) {
+ IP_VS_DBG(3, "BACKUP, Invalid flags 0x%X\n", flags);
+ retc = 25;
+ goto out;
+ }
+ flags &= IP_VS_CONN_F_BACKUP_MASK;
flags |= IP_VS_CONN_F_SYNC;
state = ntohs(s->v4.state);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0244/1887] netfilter: bpf: reject invalid NAT manipulation types
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-10-28 16:38 ` [PATCH 6.1 0243/1887] ipvs: filter some flags received in the backup server Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0245/1887] net: sparx5: make ports inherit the switch base mac address type Greg Kroah-Hartman
` (754 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, VEGA, Fernando Fernandez Mancera,
Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <fmancera@suse.de>
[ Upstream commit 16d464013ec2267b00a83f4bfbb97b3ecc63bfa7 ]
As bpf_ct_set_nat_info() is not validating the NAT manipulation type a
wrong value can be passed directly to nf_nat_setup_info(). This triggers
the WARN_ON() at nf_nat_setup_info() and if panic_on_warn isn't set,
then IPS_SRC_NAT_DONE is set without adding nat_bysource and conntrack
cleanup tries to unlink an uninitialized hlist node.
Fix this by checking that NAT manipulation type is correct before
calling nf_nat_setup_info(). In addition, if the WARN_ON is hit, return
NF_DROP instead of continuing with the processing to avoid similar
situations in the future.
Reported-by: VEGA <vega@nebusec.ai>
Fixes: 0fabd2aa199f ("net: netfilter: add bpf_ct_set_nat_info kfunc helper")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_nat_bpf.c | 3 +++
net/netfilter/nf_nat_core.c | 5 +++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_nat_bpf.c b/net/netfilter/nf_nat_bpf.c
index 0fa5a0bbb0ffe..1d89cce3f7cab 100644
--- a/net/netfilter/nf_nat_bpf.c
+++ b/net/netfilter/nf_nat_bpf.c
@@ -41,6 +41,9 @@ int bpf_ct_set_nat_info(struct nf_conn___init *nfct,
if (proto != NFPROTO_IPV4 && proto != NFPROTO_IPV6)
return -EINVAL;
+ if (manip != NF_NAT_MANIP_SRC && manip != NF_NAT_MANIP_DST)
+ return -EINVAL;
+
memset(&range, 0, sizeof(struct nf_nat_range2));
range.flags = NF_NAT_RANGE_MAP_IPS;
range.min_addr = *addr;
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 310449731a021..6586cce471eb6 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -588,8 +588,9 @@ nf_nat_setup_info(struct nf_conn *ct,
if (nf_ct_is_confirmed(ct))
return NF_ACCEPT;
- WARN_ON(maniptype != NF_NAT_MANIP_SRC &&
- maniptype != NF_NAT_MANIP_DST);
+ if (WARN_ON(maniptype != NF_NAT_MANIP_SRC &&
+ maniptype != NF_NAT_MANIP_DST))
+ return NF_DROP;
if (WARN_ON(nf_nat_initialized(ct, maniptype)))
return NF_DROP;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0245/1887] net: sparx5: make ports inherit the switch base mac address type
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0244/1887] netfilter: bpf: reject invalid NAT manipulation types Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0246/1887] net: add and use skb_get_hash_net Greg Kroah-Hartman
` (753 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Quentin Freimanis, Simon Horman,
Daniel Machon, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quentin Freimanis <quentin@q-lab.dev>
[ Upstream commit 5642b1648d5c4561d8ed7a410d0a7017f706604d ]
When the switch uses a random base MAC address it does not mark each
port's address as random:
$ dmesg | grep "MAC addr"
sparx5-switch e00c0000.switch: MAC addr was not set, use random MAC
$ cat /sys/class/net/eth0/addr_assign_type
0
0 is NET_ADDR_PERM, so userspace thinks this is a stable address.
With a random MAC reported as NET_ADDR_PERM, systemd's
MACAddressPolicy=persistent [1] leaves it unchanged, so a DHCP client
gets a new IP address every boot and a static reservation can't be used.
Reporting it as NET_ADDR_RANDOM makes systemd replace it with a stable
address derived from the interface name and machine-id.
Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
Signed-off-by: Quentin Freimanis <quentin@q-lab.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20260928045012.30178-1-quentin@q-lab.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 1 +
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 1 +
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 1ed69e77b8958..fbff85b52472c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -828,6 +828,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
dev_info(sparx5->dev, "MAC addr was not set, use random MAC\n");
eth_random_addr(sparx5->base_mac);
sparx5->base_mac[5] = 0;
+ sparx5->base_mac_assign_type = NET_ADDR_RANDOM;
}
sparx5->fdma_irq = platform_get_irq_byname(sparx5->pdev, "fdma");
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index cb3173d2b0e8d..6d01585dbedff 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -255,6 +255,7 @@ struct sparx5 {
struct notifier_block switchdev_blocking_nb;
/* Switch state */
u8 base_mac[ETH_ALEN];
+ u8 base_mac_assign_type;
/* Associated bridge device (when bridged) */
struct net_device *hw_bridge_dev;
/* Bridged interfaces */
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
index d078156581d54..090aa6c14a0f1 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
@@ -270,6 +270,7 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno)
ndev->ethtool_ops = &sparx5_ethtool_ops;
eth_hw_addr_gen(ndev, sparx5->base_mac, portno + 1);
+ ndev->addr_assign_type = sparx5->base_mac_assign_type;
return ndev;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0246/1887] net: add and use skb_get_hash_net
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0245/1887] net: sparx5: make ports inherit the switch base mac address type Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0247/1887] ipv6: sr: use skb_get_hash_net() in seg6_make_flowlabel() Greg Kroah-Hartman
` (752 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Paasch, Willem de Bruijn,
Florian Westphal, Eric Dumazet, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit b975d3ee5962237c1e2f5d5aeeaaf0dc2173486c ]
Years ago flow dissector gained ability to delegate flow dissection
to a bpf program, scoped per netns.
Unfortunately, skb_get_hash() only gets an sk_buff argument instead
of both net+skb. This means the flow dissector needs to obtain the
netns pointer from somewhere else.
The netns is derived from skb->dev, and if that is not available, from
skb->sk. If neither is set, we hit a (benign) WARN_ON_ONCE().
Trying both dev and sk covers most cases, but not all, as recently
reported by Christoph Paasch.
In case of nf-generated tcp reset, both sk and dev are NULL:
WARNING: .. net/core/flow_dissector.c:1104
skb_flow_dissect_flow_keys include/linux/skbuff.h:1536 [inline]
skb_get_hash include/linux/skbuff.h:1578 [inline]
nft_trace_init+0x7d/0x120 net/netfilter/nf_tables_trace.c:320
nft_do_chain+0xb26/0xb90 net/netfilter/nf_tables_core.c:268
nft_do_chain_ipv4+0x7a/0xa0 net/netfilter/nft_chain_filter.c:23
nf_hook_slow+0x57/0x160 net/netfilter/core.c:626
__ip_local_out+0x21d/0x260 net/ipv4/ip_output.c:118
ip_local_out+0x26/0x1e0 net/ipv4/ip_output.c:127
nf_send_reset+0x58c/0x700 net/ipv4/netfilter/nf_reject_ipv4.c:308
nft_reject_ipv4_eval+0x53/0x90 net/ipv4/netfilter/nft_reject_ipv4.c:30
[..]
syzkaller did something like this:
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
meta nftrace set 1
tcp dport 42 reject with tcp reset
}
chain output {
type filter hook output priority filter; policy accept;
# empty chain is enough
}
}
... then sends a tcp packet to port 42.
Initial attempt to simply set skb->dev from nf_reject_ipv4 doesn't cover
all cases: skbs generated via ipv4 igmp_send_report trigger similar splat.
Moreover, Pablo Neira found that nft_hash.c uses __skb_get_hash_symmetric()
which would trigger same warn splat for such skbs.
Lets allow callers to pass the current netns explicitly.
The nf_trace infrastructure is adjusted to use the new helper.
__skb_get_hash_symmetric is handled in the next patch.
Reported-by: Christoph Paasch <cpaasch@apple.com>
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/494
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20240608221057.16070-2-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 8ec454dcd00c ("ipv6: sr: use skb_get_hash_net() in seg6_make_flowlabel()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/skbuff.h | 12 ++++++++++--
net/core/flow_dissector.c | 15 +++++++++++----
net/netfilter/nf_tables_trace.c | 2 +-
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c5a2b0f6516c7..2d5cf255cf73a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1487,7 +1487,7 @@ __skb_set_sw_hash(struct sk_buff *skb, __u32 hash, bool is_l4)
__skb_set_hash(skb, hash, true, is_l4);
}
-void __skb_get_hash(struct sk_buff *skb);
+void __skb_get_hash_net(const struct net *net, struct sk_buff *skb);
u32 __skb_get_hash_symmetric(const struct sk_buff *skb);
u32 skb_get_poff(const struct sk_buff *skb);
u32 __skb_get_poff(const struct sk_buff *skb, const void *data,
@@ -1567,10 +1567,18 @@ void skb_flow_dissect_hash(const struct sk_buff *skb,
struct flow_dissector *flow_dissector,
void *target_container);
+static inline __u32 skb_get_hash_net(const struct net *net, struct sk_buff *skb)
+{
+ if (!skb->l4_hash && !skb->sw_hash)
+ __skb_get_hash_net(net, skb);
+
+ return skb->hash;
+}
+
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
if (!skb->l4_hash && !skb->sw_hash)
- __skb_get_hash(skb);
+ __skb_get_hash_net(NULL, skb);
return skb->hash;
}
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index e604c6a08cbd0..12216a5710a92 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1760,7 +1760,8 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
/**
- * __skb_get_hash: calculate a flow hash
+ * __skb_get_hash_net: calculate a flow hash
+ * @net: associated network namespace, derived from @skb if NULL
* @skb: sk_buff to calculate flow hash from
*
* This function calculates a flow hash based on src/dst addresses
@@ -1768,18 +1769,24 @@ EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
* on success, zero indicates no valid hash. Also, sets l4_hash in skb
* if hash is a canonical 4-tuple hash over transport ports.
*/
-void __skb_get_hash(struct sk_buff *skb)
+void __skb_get_hash_net(const struct net *net, struct sk_buff *skb)
{
struct flow_keys keys;
u32 hash;
+ memset(&keys, 0, sizeof(keys));
+
+ __skb_flow_dissect(net, skb, &flow_keys_dissector,
+ &keys, NULL, 0, 0, 0,
+ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+
__flow_hash_secret_init();
- hash = ___skb_get_hash(skb, &keys, &hashrnd);
+ hash = __flow_hash_from_keys(&keys, &hashrnd);
__skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
}
-EXPORT_SYMBOL(__skb_get_hash);
+EXPORT_SYMBOL(__skb_get_hash_net);
__u32 skb_get_hash_perturb(const struct sk_buff *skb,
const siphash_key_t *perturb)
diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c
index 1163ba9c14011..68916b5297e72 100644
--- a/net/netfilter/nf_tables_trace.c
+++ b/net/netfilter/nf_tables_trace.c
@@ -289,7 +289,7 @@ void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt,
net_get_random_once(&trace_key, sizeof(trace_key));
info->skbid = (u32)siphash_3u32(hash32_ptr(skb),
- skb_get_hash(skb),
+ skb_get_hash_net(nft_net(pkt), skb),
skb->skb_iif,
&trace_key);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0247/1887] ipv6: sr: use skb_get_hash_net() in seg6_make_flowlabel()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0246/1887] net: add and use skb_get_hash_net Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0248/1887] i2c: at91: release DMA channels when probe defers Greg Kroah-Hartman
` (751 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+9408fbe0e6452a12e9ab,
Eric Dumazet, Xuanqiang Luo, Ido Schimmel, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit 8ec454dcd00ce3375119111c6394964455b36d0d ]
Since commit d58e468b1112 ("flow_dissector: implements flow dissector
BPF hook") __skb_flow_dissect() needs a net pointer, either from
skb->dev, skb->sk, or since commit 3cbf4ffba5ee ("net: plumb network
namespace into __skb_flow_dissect") a caller provided pointer.
syzbot was able to reach seg6_make_flowlabel() with an skb having
neither skb->dev nor skb->sk set: a TIPC UDP bearer sends a discovery
message through an IPv4 route using seg6 encap, while
net.ipv6.seg6_flowlabel is set to 1.
seg6_make_flowlabel() already has a net pointer, use skb_get_hash_net().
WARNING: net/core/flow_dissector.c:1131 at __skb_flow_dissect+0x910/0x5368 net/core/flow_dissector.c:1126, CPU#0: syz.0.17/4930
Call trace:
__skb_flow_dissect+0x910/0x5368 net/core/flow_dissector.c:1126 (P)
__skb_get_hash_net+0xe0/0x29c net/core/flow_dissector.c:1903
skb_get_hash include/linux/skbuff.h:1663 [inline]
seg6_make_flowlabel+0xcc/0x1ec net/ipv6/seg6_iptunnel.c:132
__seg6_do_srh_encap+0x320/0xbf4 net/ipv6/seg6_iptunnel.c:161
seg6_do_srh+0x4b4/0xa44 net/ipv6/seg6_iptunnel.c:431
seg6_output_core+0x164/0x688 net/ipv6/seg6_iptunnel.c:681
seg6_output+0x44/0x1ac net/ipv6/seg6_iptunnel.c:744
lwtunnel_output+0x3d0/0x664 net/core/lwtunnel.c:356
dst_output include/net/dst.h:470 [inline]
ip_local_out+0x110/0x148 net/ipv4/ip_output.c:131
iptunnel_xmit+0x50c/0xd38 net/ipv4/ip_tunnel_core.c:97
udp_tunnel_xmit_skb+0x220/0x348 net/ipv4/udp_tunnel_core.c:187
tipc_udp_xmit+0x75c/0x9c0 net/tipc/udp_media.c:202
tipc_udp_send_msg+0x214/0x374 net/tipc/udp_media.c:274
tipc_bearer_xmit_skb+0x260/0x3b0 net/tipc/bearer.c:576
tipc_enable_bearer net/tipc/bearer.c:366 [inline]
__tipc_nl_bearer_enable+0xc90/0xfb0 net/tipc/bearer.c:1048
tipc_nl_bearer_enable+0x2c/0x48 net/tipc/bearer.c:1057
genl_family_rcv_msg_doit+0x1e4/0x2d4 net/netlink/genetlink.c:1114
Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
Reported-by: syzbot+9408fbe0e6452a12e9ab@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6abac2eb.3654fce1.1bec97.0000.GAE@google.com/
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260928194524.3617299-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/seg6_iptunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 96d2ca23ee385..d0968a3196359 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -116,7 +116,7 @@ static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb,
u32 hash;
if (do_flowlabel > 0) {
- hash = skb_get_hash(skb);
+ hash = skb_get_hash_net(net, skb);
hash = rol32(hash, 16);
flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
} else if (!do_flowlabel && skb->protocol == htons(ETH_P_IPV6)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0248/1887] i2c: at91: release DMA channels when probe defers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0247/1887] ipv6: sr: use skb_get_hash_net() in seg6_make_flowlabel() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0249/1887] perf: Fix race between perf_event_exit_task() and perf_pending_task() Greg Kroah-Hartman
` (750 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hongjian Dai, Andi Shyti,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongjian Dai <daihongjian@kylinsec.com.cn>
[ Upstream commit c98bf3b86609a18ab16d067280257326e557c636 ]
at91_twi_probe_master() can return -EPROBE_DEFER from
at91_init_twi_recovery_info() after at91_twi_configure_dma() has already
claimed the tx/rx DMA channels. at91_twi_probe() then returns without
releasing them, and since dma_request_chan() is not devres-managed the
channels leak on every deferred probe attempt.
Release the channels before deferring the probe.
Fixes: f7eeb1af8537 ("i2c: at91: release DMA channels on remove and probe error")
Assisted-by: LLM
Signed-off-by: Hongjian Dai <daihongjian@kylinsec.com.cn>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/7D85C6CB6BF0A82E+20260929164340.41628-1-daihongjian@kylinsec.com.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/busses/i2c-at91-master.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index 28ed1bde3d68a..593881902a0d9 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -919,8 +919,14 @@ int at91_twi_probe_master(struct platform_device *pdev,
at91_calc_twi_clock(dev);
rc = at91_init_twi_recovery_info(pdev, dev);
- if (rc == -EPROBE_DEFER)
+ if (rc == -EPROBE_DEFER) {
+ /*
+ * The DMA channels were already set up above, release them
+ * before deferring the probe so they are not leaked.
+ */
+ at91_twi_dma_release(dev);
return rc;
+ }
dev->adapter.algo = &at91_twi_algorithm;
dev->adapter.quirks = &at91_twi_quirks;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0249/1887] perf: Fix race between perf_event_exit_task() and perf_pending_task()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0248/1887] i2c: at91: release DMA channels when probe defers Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0250/1887] PCI: Accept AtomicOps already enabled by the hypervisor Greg Kroah-Hartman
` (749 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luo Gengkun, Peter Zijlstra (Intel),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun <luogengkun2@huawei.com>
[ Upstream commit ffb684f2aa141eeb0caa6308422e7e05d1ded7c4 ]
A race condition exists between perf_event_exit_task() and
perf_pending_task() during begin_new_exec().
During begin_new_exec(), perf_event_exit_task() may be called, and the
PF_EXITING flag is not set on task. So perf_sigtrap() continues to execute
and triggers WARN_ON_ONCE(event->ctx->task != current).
Since both task exit and exec paths can call perf_event_exit_task() which
sets ctx->task to TASK_TOMBSTONE, fix this by explicitly checking if
event->ctx->task equals TASK_TOMBSTONE and dropping the redundant
PF_EXITING check.
Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
Signed-off-by: Luo Gengkun <luogengkun2@huawei.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260920075026.990582-1-luogengkun2@huawei.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index e5c79c55ce48e..013c3a4afb8a3 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6596,9 +6596,11 @@ static void perf_sigtrap(struct perf_event *event)
{
/*
* Both perf_pending_task() and perf_pending_irq() can race with the
- * task exiting.
+ * task exiting or exec-ing. We can determine if such a race has
+ * occurred by checking if perf_event_exit_task(), which will set
+ * ctx->task to TASK_TOMBSTONE, has already been called.
*/
- if (current->flags & PF_EXITING)
+ if (event->ctx->task == TASK_TOMBSTONE)
return;
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0250/1887] PCI: Accept AtomicOps already enabled by the hypervisor
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0249/1887] perf: Fix race between perf_event_exit_task() and perf_pending_task() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0251/1887] drm/amd/pm/si: Check AMD_IS_MOBILITY flag for PPSMC_SYSTEMFLAG_GPIO_DC Greg Kroah-Hartman
` (748 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikola Prica, Bjorn Helgaas,
Gerd Bayer, Christian König, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikola Prica <nikola.prica@amd.com>
[ Upstream commit 40cce45b921f7930886bcba43069edc579725457 ]
pci_enable_atomic_ops_to_root() currently fails when no Root Port is
visible. That is common in passthrough guests (ESXi, Hyper-V): the Endpoint
is assigned to the VM, but the Root Port above it is not visible in the
guest topology.
In those setups the hypervisor may already have enabled AtomicOp Requester
Enable on the device. If PCI_EXP_DEVCTL2_ATOMIC_REQ is set, treat AtomicOps
as already enabled and return success instead of failing the Root Port
walk.
After 1ae8c4ce1570 ("PCI: Enable AtomicOps only if Root Port supports
them"), pci_enable_atomic_ops_to_root() always returns failure if the Root
Port is not visible, so drivers don't use atomics when they could. On
systems where the Root Port is not visible but *does* support AtomicOps,
this is a regression: prior to 1ae8c4ce1570, it enabled AtomicOps in the
endpoint and returned success.
Fixes: 1ae8c4ce1570 ("PCI: Enable AtomicOps only if Root Port supports them")
Signed-off-by: Nikola Prica <nikola.prica@amd.com>
[bhelgaas: commit log, code comment]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Gerd Bayer <gbayer@linux.ibm.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Link: https://patch.msgid.link/20260921111903.978687-1-nikprica@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/pci.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b0d4c3bc205bf..6e861dd4020cb 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3822,8 +3822,21 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
}
root = pcie_find_root_port(dev);
- if (!root)
+ if (!root) {
+
+ /*
+ * A hypervisor may expose a topology with the root port
+ * not visible to the guest. If the hypervisor has already
+ * set AtomicOp Requester Enable in the endpoint, we assume
+ * it has verified support in the root port, so it is safe
+ * for the driver to use AtomicOps.
+ */
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCTL2, &ctl2);
+ if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ)
+ return 0;
+
return -EINVAL;
+ }
pcie_capability_read_dword(root, PCI_EXP_DEVCAP2, &cap);
if ((cap & cap_mask) != cap_mask)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0251/1887] drm/amd/pm/si: Check AMD_IS_MOBILITY flag for PPSMC_SYSTEMFLAG_GPIO_DC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0250/1887] PCI: Accept AtomicOps already enabled by the hypervisor Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0252/1887] drm/amd/pm/si: Fix updating clock limits on AC/DC Greg Kroah-Hartman
` (747 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Timur Kristóf,
Mario Limonciello, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <timur.kristof@gmail.com>
commit cd883d0a3937df82a5ea03709ba8ba623b868419 upstream.
Unfortunately, some desktop boards eg. the FirePro D500
have the HARDWAREDC platform flag set and also have
a battery power state configured in their VBIOS.
This makes no sense for a desktop GPU and results in
incorrect behaviour: the clocks are stuck at lowest.
We observed that the kernel driver can work around
the issue in two possible ways:
1. Set PPSMC_SWSTATE_FLAG_DC on all power states
2. Clear PPSMC_SYSTEMFLAG_GPIO_DC
We think that the PPSMC_SYSTEMFLAG_GPIO_DC flag
makes the SMC assume it's running on battery even
though this is a desktop machine with no battery,
and that's why it doesn't do DPM on power states
without PPSMC_SYSTEMFLAG_GPIO_DC.
Issue was uncovered by "Fix updating clock limits from
power states" because previously the limits for the
battery state were not tracked separately. However,
battery power state has lower frequencies and voltages,
so the kernel doesn't set the DC flag on the current
power state anymore. That causes the SMC to be stuck
on the lowest clocks.
Let's clear PPSMC_SYSTEMFLAG_GPIO_DC on desktop GPUs.
We can use the AMD_IS_MOBILITY flag to determine that.
Fixes: e6c5d36756e7 ("drm/amd/pm/si: Fix updating clock limits from power states")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/16352
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260923120354.1027996-1-timur.kristof@gmail.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 58473c7c49ce9f5f5a4a1c24ffb9aa1d3c8771f4)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -5239,7 +5239,8 @@ static int si_init_smc_table(struct amdg
break;
}
- if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+ if ((adev->flags & AMD_IS_MOBILITY) &&
+ (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC))
table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0252/1887] drm/amd/pm/si: Fix updating clock limits on AC/DC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0251/1887] drm/amd/pm/si: Check AMD_IS_MOBILITY flag for PPSMC_SYSTEMFLAG_GPIO_DC Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0253/1887] drm/amdgpu/gfx6: fix firmware leak on teardown Greg Kroah-Hartman
` (746 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Timur Kristóf,
Mario Limonciello, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <timur.kristof@gmail.com>
commit 08c9100f65299c64439e22e6057d750ae0e6c660 upstream.
Assume that the AC limits are the maximum of all power states,
and the DC limits are the maximum of battery power states.
This shouldn't make any difference in practice, but is
cleaner and more robust against bogus information in the VBIOS.
Fixes: e6c5d36756e7 ("drm/amd/pm/si: Fix updating clock limits from power states")
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260923120354.1027996-2-timur.kristof@gmail.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ef8cb9dcc7db7b7abcbdbe870a080cc81e4f0bf3)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 36 ++++++++++++++---------------
1 file changed, 18 insertions(+), 18 deletions(-)
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -7211,6 +7211,19 @@ static void si_parse_pplib_non_clock_inf
adev->pm.dpm.uvd_ps = rps;
}
+static void si_update_limits(struct amdgpu_clock_and_voltage_limits *limits,
+ struct rv7xx_pl *pl)
+{
+ if (pl->sclk > limits->sclk)
+ limits->sclk = pl->sclk;
+ if (pl->mclk > limits->mclk)
+ limits->mclk = pl->mclk;
+ if (pl->vddc > limits->vddc)
+ limits->vddc = pl->vddc;
+ if (pl->vddci > limits->vddci)
+ limits->vddci = pl->vddci;
+}
+
static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
struct amdgpu_ps *rps, int index,
union pplib_clock_info *clock_info)
@@ -7219,7 +7232,6 @@ static void si_parse_pplib_clock_info(st
struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
struct si_power_info *si_pi = si_get_pi(adev);
struct si_ps *ps = si_get_ps(rps);
- struct amdgpu_clock_and_voltage_limits *limits;
u16 leakage_voltage;
struct rv7xx_pl *pl = &ps->performance_levels[index];
int ret;
@@ -7284,26 +7296,14 @@ static void si_parse_pplib_clock_info(st
* VBIOS can contain conflicting values between:
* - the maximum allowed clocks and voltages on AC or DC
* - the clocks and voltages in power states on AC or DC
+ *
+ * Assume that the AC limits are the maximum of all power states,
+ * and the DC limits are the maximum of battery power states.
*/
+ si_update_limits(&adev->pm.dpm.dyn_state.max_clock_voltage_on_ac, pl);
if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
- ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE)
- limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
- else if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
- limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
- else
- limits = NULL;
-
- if (limits) {
- if (pl->sclk > limits->sclk)
- limits->sclk = pl->sclk;
- if (pl->mclk > limits->mclk)
- limits->mclk = pl->mclk;
- if (pl->vddc > limits->vddc)
- limits->vddc = pl->vddc;
- if (pl->vddci > limits->vddci)
- limits->vddci = pl->vddci;
- }
+ si_update_limits(&adev->pm.dpm.dyn_state.max_clock_voltage_on_dc, pl);
}
union pplib_power_state {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0253/1887] drm/amdgpu/gfx6: fix firmware leak on teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0252/1887] drm/amd/pm/si: Fix updating clock limits on AC/DC Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0254/1887] drm/radeon: Read the VRAM VBIOS signature with readb() Greg Kroah-Hartman
` (745 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Willian Oliveira, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willian Oliveira <williandossantosdeoliveira287@gmail.com>
commit cc172e177795c5f87bc2d71768d077e1c10633e8 upstream.
The firmware requested in gfx_v6_0_init_microcode() is not released
when the GFX block is torn down, leaking the firmware resources.
Add gfx_v6_0_free_microcode() and call it from gfx_v6_0_sw_fini()
to release the PFP, ME, CE and RLC firmware.
Signed-off-by: Willian Oliveira <williandossantosdeoliveira287@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 386e81346f95ab0be5a82c5535de932e7a456924)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -308,6 +308,14 @@ static const u32 verde_rlc_save_restore_
0x00000000
};
+static void gfx_v6_0_free_microcode(struct amdgpu_device *adev)
+{
+ amdgpu_ucode_release(&adev->gfx.pfp_fw);
+ amdgpu_ucode_release(&adev->gfx.me_fw);
+ amdgpu_ucode_release(&adev->gfx.ce_fw);
+ amdgpu_ucode_release(&adev->gfx.rlc_fw);
+}
+
static int gfx_v6_0_init_microcode(struct amdgpu_device *adev)
{
const char *chip_name;
@@ -3197,6 +3205,7 @@ static int gfx_v6_0_sw_fini(void *handle
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
amdgpu_gfx_rlc_fini(adev);
+ gfx_v6_0_free_microcode(adev);
return 0;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0254/1887] drm/radeon: Read the VRAM VBIOS signature with readb()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0253/1887] drm/amdgpu/gfx6: fix firmware leak on teardown Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0255/1887] drm/amdgpu: fix IP instance memory leak on kobject add failure Greg Kroah-Hartman
` (744 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Kaloz <kaloz@kernel.org>
commit de1eab13efef83fd2b76f4688de5bf672644596f upstream.
igp_read_bios_from_vram() checked bios[0]/bios[1] with a plain
__iomem load, which faults on sparc64 before the copy runs at all.
radeon_read_bios() already reads its two signature bytes with
readb() ahead of its own copy; use the same accessor here, keeping
the check before the allocation.
Fixes: b442962a9e82 ("drm/radeon/kms: add support for "Surround View"")
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 09155b8932e5013dbce0f5cdff7d75264a279ee5)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/radeon/radeon_bios.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -49,6 +49,7 @@
static bool igp_read_bios_from_vram(struct radeon_device *rdev)
{
uint8_t __iomem *bios;
+ uint8_t val1, val2;
resource_size_t vram_base;
resource_size_t size = 256 * 1024; /* ??? */
@@ -63,7 +64,10 @@ static bool igp_read_bios_from_vram(stru
return false;
}
- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+ val1 = readb(&bios[0]);
+ val2 = readb(&bios[1]);
+
+ if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
iounmap(bios);
return false;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0255/1887] drm/amdgpu: fix IP instance memory leak on kobject add failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0254/1887] drm/radeon: Read the VRAM VBIOS signature with readb() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0256/1887] drm/amdgpu: fix ACP MFD device leak on init failure Greg Kroah-Hartman
` (743 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Lijo Lazar, Guangshuo Li,
Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit f5a5add3605935163dd0f75749b6a7869e9765af upstream.
amdgpu_discovery_sysfs_ips() allocates ip_hw_instance with
kzalloc_flex() and initializes its embedded kobject before calling
kobject_add().
If kobject_add() fails, the return value is ignored and execution
continues without dropping the initial kobject reference. The failed
kobject is not retained in the kset list, so the normal sysfs teardown
path cannot find it. As a result, ip_hw_instance_release() is never
called and the ip_hw_instance allocation is leaked.
Call kobject_put() when kobject_add() fails so the initial reference is
dropped and ip_hw_instance_release() can free the allocation. Keep the
existing best-effort sysfs behavior by continuing with the remaining IP
entries after the failed registration.
The issue was identified by a static analysis tool I developed and
confirmed by manual review.
Fixes: a6c40b178092 ("drm/amdgpu: Show IP discovery in sysfs")
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 5c75fbcca8af1096d8d9415b91d8ea6212c22ee1)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -903,6 +903,8 @@ static int amdgpu_discovery_sysfs_ips(st
ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset;
res = kobject_add(&ip_hw_instance->kobj, NULL,
"%d", ip_hw_instance->num_instance);
+ if (res)
+ kobject_put(&ip_hw_instance->kobj);
next_ip:
ip_offset += struct_size(ip, base_address, ip->num_base_address);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0256/1887] drm/amdgpu: fix ACP MFD device leak on init failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0255/1887] drm/amdgpu: fix IP instance memory leak on kobject add failure Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0257/1887] binder: fix is_failure flag for superseded transaction cleanup Greg Kroah-Hartman
` (742 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit f0013046151b7467e62c471c1c83d63ea255799c upstream.
acp_hw_init() registers ACP child devices with mfd_add_devices() before
attaching them to the ACP power domain and initializing the hardware.
If attaching a child to the power domain fails, or if the ACP reset or
clock enable operation times out, the failure path frees only the
source cell, resource, and platform-data allocations. The child
platform devices already registered by mfd_add_devices() remain
registered and are never released.
Remove the children from the power domain and unregister the MFD
devices on failures that occur after mfd_add_devices() succeeds. Keep
mfd_add_devices() failures on the existing cleanup path since the MFD
core already rolls back partially registered children itself.
The issue was identified by a static analysis tool I developed and
confirmed by manual review.
Fixes: 25030321ba28 ("drm/amd: add pm domain for ACP IP sub blocks")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 63da68d6a2279ec945581c990c5a59a5ae8b5560)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -324,7 +324,7 @@ static int acp_hw_init(void *handle)
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
acp_genpd_add_device);
if (r)
- goto failure;
+ goto failure_remove_mfd;
break;
}
default:
@@ -446,7 +446,7 @@ static int acp_hw_init(void *handle)
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
acp_genpd_add_device);
if (r)
- goto failure;
+ goto failure_remove_mfd;
}
/* Assert Soft reset of ACP */
@@ -464,7 +464,7 @@ static int acp_hw_init(void *handle)
if (--count == 0) {
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
r = -ETIMEDOUT;
- goto failure;
+ goto failure_remove_mfd;
}
udelay(100);
}
@@ -482,7 +482,7 @@ static int acp_hw_init(void *handle)
if (--count == 0) {
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
r = -ETIMEDOUT;
- goto failure;
+ goto failure_remove_mfd;
}
udelay(100);
}
@@ -492,6 +492,11 @@ static int acp_hw_init(void *handle)
cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
return 0;
+failure_remove_mfd:
+ device_for_each_child(adev->acp.parent, NULL,
+ acp_genpd_remove_device);
+ mfd_remove_devices(adev->acp.parent);
+
failure:
kfree(i2s_pdata);
kfree(adev->acp.acp_res);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0257/1887] binder: fix is_failure flag for superseded transaction cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0256/1887] drm/amdgpu: fix ACP MFD device leak on init failure Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0258/1887] binder: fix leaked fd fixups on TF_UPDATE_TXN supersede Greg Kroah-Hartman
` (741 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Tomer Pomeranc,
Carlos Llamas
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomer Pomeranc <tomerpo@gmail.com>
commit 22c135635fdd9816c0ef140d6de7b2e4fdf73e89 upstream.
When a TF_UPDATE_TXN transaction supersedes a pending async transaction,
binder_release_entire_buffer() is called with is_failure=false. Since the
superseded transaction was never delivered, binder_apply_fd_fixups() was
never called and no fds were installed in the target process.
With is_failure=false, the BINDER_TYPE_FDA cleanup handler interprets
stale buffer contents as installed fd numbers and passes them to
binder_deferred_fd_close(), closing unrelated file descriptors.
Pass is_failure=true since the transaction was never delivered to the
target, matching the semantics of all other undelivered-transaction
cleanup paths.
Fixes: 9864bb480133 ("Binder: add TF_UPDATE_TXN to replace outdated txn")
Cc: stable <stable@kernel.org>
Signed-off-by: Tomer Pomeranc <tomerpo@gmail.com>
Acked-by: Carlos Llamas <cmllamas@google.com>
Link: https://patch.msgid.link/20260812195316.259136-3-tomerpo@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/android/binder.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2833,7 +2833,7 @@ static int binder_proc_transaction(struc
t_outdated->buffer = NULL;
buffer->transaction = NULL;
trace_binder_transaction_update_buffer_release(buffer);
- binder_release_entire_buffer(proc, NULL, buffer, false);
+ binder_release_entire_buffer(proc, NULL, buffer, true);
binder_alloc_free_buf(&proc->alloc, buffer);
kfree(t_outdated);
binder_stats_deleted(BINDER_STAT_TRANSACTION);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0258/1887] binder: fix leaked fd fixups on TF_UPDATE_TXN supersede
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0257/1887] binder: fix is_failure flag for superseded transaction cleanup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0259/1887] kgdboc: Fix tty driver reference leak in configure_kgdboc() Greg Kroah-Hartman
` (740 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Tomer Pomeranc,
Carlos Llamas, Alice Ryhl
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomer Pomeranc <tomerpo@gmail.com>
commit c4c02084d6687d5cd5edccaf52cc45e5160f1184 upstream.
When a TF_UPDATE_TXN transaction supersedes a pending async transaction
in a frozen process, the outdated transaction is freed with kfree()
directly. This skips binder_free_txn_fixups(), leaking all
binder_txn_fd_fixup entries and their fget()'d struct file references.
The leaked file refcounts never reach zero, so the struct file objects
are permanently pinned in memory. They survive process exit and
accumulate across invocations until file-max exhaustion.
Every other transaction cleanup path (binder_free_transaction(),
binder_transaction() error paths, binder_release_work()) correctly
calls binder_free_txn_fixups(). Add the missing call before kfree()
in the t_outdated cleanup block.
Fixes: 9864bb480133 ("Binder: add TF_UPDATE_TXN to replace outdated txn")
Cc: stable <stable@kernel.org>
Signed-off-by: Tomer Pomeranc <tomerpo@gmail.com>
Acked-by: Carlos Llamas <cmllamas@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260812195316.259136-2-tomerpo@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/android/binder.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2835,6 +2835,7 @@ static int binder_proc_transaction(struc
trace_binder_transaction_update_buffer_release(buffer);
binder_release_entire_buffer(proc, NULL, buffer, true);
binder_alloc_free_buf(&proc->alloc, buffer);
+ binder_free_txn_fixups(t_outdated);
kfree(t_outdated);
binder_stats_deleted(BINDER_STAT_TRANSACTION);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0259/1887] kgdboc: Fix tty driver reference leak in configure_kgdboc()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0258/1887] binder: fix leaked fd fixups on TF_UPDATE_TXN supersede Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0260/1887] Input: atkbd - skip deactivate for Lenovo IdeaPad Slim 3 15IWC11 Greg Kroah-Hartman
` (739 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Wentao Liang,
Douglas Anderson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit ef3134cd0d4831ae2137aee2883987859b80b2c6 upstream.
tty_find_polling_driver() returns the tty driver with an extra
reference taken by tty_driver_kref_get(). configure_kgdboc() stores it
in kgdb_tty_driver but the reference is never dropped: it is leaked when
kgdb_register_io_module() fails, when the configuration is cleared, and
on every reconfigure.
Release the reference both when unconfiguring and on the error path.
Fixes: 7d7b93c1452f ("tty: kref the tty driver object")
Cc: stable@kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://patch.msgid.link/20260917155523.2161202-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/kgdboc.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -190,6 +190,11 @@ static void cleanup_kgdboc(void)
return;
kgdboc_unregister_kbd();
kgdb_unregister_io_module(&kgdboc_io_ops);
+
+ if (kgdb_tty_driver) {
+ tty_driver_kref_put(kgdb_tty_driver);
+ kgdb_tty_driver = NULL;
+ }
}
static int configure_kgdboc(void)
@@ -250,6 +255,10 @@ nmi_con_failed:
kgdb_unregister_io_module(&kgdboc_io_ops);
noconfig:
kgdboc_unregister_kbd();
+ if (kgdb_tty_driver) {
+ tty_driver_kref_put(kgdb_tty_driver);
+ kgdb_tty_driver = NULL;
+ }
configured = 0;
return err;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0260/1887] Input: atkbd - skip deactivate for Lenovo IdeaPad Slim 3 15IWC11
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0259/1887] kgdboc: Fix tty driver reference leak in configure_kgdboc() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0261/1887] Input: i8042 - add nomux quirk for Fujitsu LIFEBOOK U7410 Greg Kroah-Hartman
` (738 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Martino Papero, Hans de Goede,
Dmitry Torokhov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martino Papero <martino.papero@lcb.to.it>
commit 3bf8d603fd45649c106cae6290a10f20b1bbb569 upstream.
The internal keyboard on the Lenovo IdeaPad Slim 3 15IWC11 (83RR)
does not work correctly with the default i8042 settings. Using
i8042.nopnp=1 and i8042.dumbkbd=1 restores keyboard input, but prevents
the Caps Lock LED from working. Using i8042.nopnp=1 alone does not fix
the keyboard.
The laptop works correctly when atkbd_deactivate_fixup is used instead.
Add a DMI quirk for the 83RR to enable it.
This was tested without any i8042 command-line parameters. Keyboard
input and the Caps Lock LED work correctly, including after suspend
and resume and after a cold boot.
Link: https://lore.kernel.org/all/4f43465f-98ba-4722-8e29-03df20315369@kernel.org/
Signed-off-by: Martino Papero <martino.papero@lcb.to.it>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Link: https://patch.msgid.link/c0b597b8-e7ad-4fba-a2bb-5d252e3dfbd3@lcb.to.it
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/keyboard/atkbd.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1955,6 +1955,14 @@ static const struct dmi_system_id atkbd_
.callback = atkbd_deactivate_fixup,
},
{
+ /* Lenovo IdeaPad Slim 3 15IWC11 (83RR) */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "83RR"),
+ },
+ .callback = atkbd_deactivate_fixup,
+ },
+ {
/* Xiaomi Book Pro 14 (TM2424) */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "XIAOMI"),
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0261/1887] Input: i8042 - add nomux quirk for Fujitsu LIFEBOOK U7410
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0260/1887] Input: atkbd - skip deactivate for Lenovo IdeaPad Slim 3 15IWC11 Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0262/1887] Input: s6sy761 - fix resume ordering and restore sensing Greg Kroah-Hartman
` (737 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Brey, Lovekesh Solanki,
Dmitry Torokhov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
commit 495cd7f858b45d2ffa9b685bba3a8c23c1ca4dd3 upstream.
On the Fujitsu LIFEBOOK U7410 the internal keyboard and touchpad die
shortly after boot if i8042 multiplexing controller is probed and
switched to muxed mode. These multiplexing setup commands disturb the EC
emulated keyboard and atkbd reports "Spurious ACK" and "Unknown key
pressed" warnings, after which both keyboard and touchpad stop
delivering events. Both touchpad and keyboard work in BIOS and GRUB.
Disabling multiplexer using i8042.nomux=1 makes both devices work on
warm/cold boot.
Add a DMI quirk to force nomux mode for this model.
Reported-by: Heiko Brey <cico0815@gmx.de>
Link: https://lore.kernel.org/all/89f36f3f5e4c2d07b9ff72bc0b355875c336e498.camel@gmx.de/
Signed-off-by: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Link: https://patch.msgid.link/20260920113541.1484808-1-lovekeshsolanki00@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/serio/i8042-acpipnpio.h | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -671,6 +671,15 @@ static const struct dmi_system_id i8042_
.driver_data = (void *)(SERIO_QUIRK_NOAUX)
},
{
+ /* Fujitsu LIFEBOOK U7410 */
+ /* Mux mode also disturbs the EC keyboard, causing spurious ACKs */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U7410"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX)
+ },
+ {
/* Gigabyte M912 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0262/1887] Input: s6sy761 - fix resume ordering and restore sensing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0261/1887] Input: i8042 - add nomux quirk for Fujitsu LIFEBOOK U7410 Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0263/1887] Input: synaptics - add LEN205b entry to smbus_pnp_ids for ThinkPad T490 Greg Kroah-Hartman
` (736 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, David Heidelberg, Dmitry Torokhov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Heidelberg <david@ixit.cz>
commit a215720959c5450b3699e243904b39c3f8f68888 upstream.
System suspend powers the controller off and resume powers it back on,
but the resume path enables the interrupt before s6sy761_power_on()
checks the boot. The firmware raises its boot-complete event on the
interrupt line, the threaded handler consumes it, s6sy761_power_on()
then reads an empty event and resume fails with -ENODEV, skipping the
touch function setup:
s6sy761 2-0048: PM: dpm_run_callback(): s6sy761_resume [s6sy761] returns -19
Power the chip on first and only then unmask the interrupt. Once resume
completes the boot handshake the chip comes back with sensing off, as
at probe where input_open() turns it on, so the touchscreen stays dead
after resume. Send SENSE_ON again when the input device is open.
Tested on a Pixel 3 XL over several s2idle cycles: resume succeeds and
the touch function and sense status match the pre-suspend state.
Assisted-by: LLM
Cc: stable@vger.kernel.org
Fixes: 0145a7141e59 ("Input: add support for the Samsung S6SY761 touchscreen")
Signed-off-by: David Heidelberg <david@ixit.cz>
Link: https://patch.msgid.link/20260926-s6sy761-suspend-v2-1-8f00a96ee6e8@ixit.cz
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/touchscreen/s6sy761.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
--- a/drivers/input/touchscreen/s6sy761.c
+++ b/drivers/input/touchscreen/s6sy761.c
@@ -508,10 +508,22 @@ static int __maybe_unused s6sy761_suspen
static int __maybe_unused s6sy761_resume(struct device *dev)
{
struct s6sy761_data *sdata = dev_get_drvdata(dev);
+ int err;
+
+ err = s6sy761_power_on(sdata);
+ if (err)
+ return err;
enable_irq(sdata->client->irq);
- return s6sy761_power_on(sdata);
+ guard(mutex)(&sdata->input->mutex);
+
+ if (!input_device_enabled(sdata->input))
+ return 0;
+
+ err = i2c_smbus_write_byte(sdata->client, S6SY761_SENSE_ON);
+
+ return err;
}
static const struct dev_pm_ops s6sy761_pm_ops = {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0263/1887] Input: synaptics - add LEN205b entry to smbus_pnp_ids for ThinkPad T490
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0262/1887] Input: s6sy761 - fix resume ordering and restore sensing Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0264/1887] Input: synaptics - limit T440p InterTouch quirk to LEN0036 Greg Kroah-Hartman
` (735 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Rosencutter, Lovekesh Solanki,
Dmitry Torokhov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
commit a961417c5ae77bbb728a23d9577ecd8f4d8a4b5a upstream.
Lenovo ThinkPad T490 has a Synaptics Touchpad that supports SMBus/RMI4
mode, but is not listed in smbus_pnp_ids table.
Add LEN205b to smbus_pnp_ids[] passlist.
Reported-by: John Rosencutter <rosencutter@gmail.com>
Closes: https://lore.kernel.org/all/CAOGuaRh025eKcBf9P8UrvtXNp68vQ0HVF2EbNMp-kpdaC1HNpA@mail.gmail.com/
Signed-off-by: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Link: https://patch.msgid.link/20260920200730.1836756-1-lovekeshsolanki00@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/mouse/synaptics.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -190,6 +190,7 @@ static const char * const smbus_pnp_ids[
"LEN2054", /* E480 */
"LEN2055", /* E580 */
"LEN2058", /* E490 */
+ "LEN205b", /* T490 */
"LEN2068", /* T14 Gen 1 */
"SYN1221", /* TUXEDO InfinityBook Pro 14 v5 */
"SYN3003", /* HP EliteBook 850 G1 */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0264/1887] Input: synaptics - limit T440p InterTouch quirk to LEN0036
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0263/1887] Input: synaptics - add LEN205b entry to smbus_pnp_ids for ThinkPad T490 Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0265/1887] nitro_enclaves: fix use-after-free on SLOT_ALLOC failure Greg Kroah-Hartman
` (734 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel Salmun, Raphaël Larocque,
Dmitry Torokhov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphaël Larocque <rlarocque@disroot.org>
commit f0fd8993082ca229faa3f9844f1c9fe182eca20b upstream.
The ThinkPad L440 also uses board id 2722, but does not have the SMBus
initialization problem seen on the T440p. On the L440, the SMBus
companion becomes available shortly after psmouse probes, allowing the
touchpad to use SMBus/RMI4 normally.
The T440p's quirk is currently applied to all Synaptics touchpads with
board id 2722, unnecessarily disabling SMBus InterTouch on the L440,
as reported by Daniel Salmun.
Restrict the quirk to PNP ID LEN0036, which identifies the T440p, so
that other devices sharing board id 2722 retain their normal
SMBus/RMI4 operation.
Reported-by: Daniel Salmun <salmundani@gmail.com>
Link: https://lore.kernel.org/all/20260925230039.236786-1-salmundani@gmail.com/
Fixes: 26eb3d92c7a4 ("Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722)")
Cc: stable@vger.kernel.org
Signed-off-by: Raphaël Larocque <rlarocque@disroot.org>
Link: https://patch.msgid.link/20260927005810.85971-1-rlarocque@disroot.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/mouse/synaptics.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1811,8 +1811,10 @@ static int synaptics_setup_intertouch(st
return -ENXIO;
}
- /* Disable intertouch on known-broken board revisions */
- if (info->board_id == 2722) {
+ /* Disable intertouch on known-broken T440p board revisions */
+ if (info->board_id == 2722 &&
+ psmouse_matches_pnp_id(psmouse,
+ (const char * const []){"LEN0036", NULL})) {
psmouse_info(psmouse,
"Disabling intertouch for board id %u\n",
info->board_id);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0265/1887] nitro_enclaves: fix use-after-free on SLOT_ALLOC failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0264/1887] Input: synaptics - limit T440p InterTouch quirk to LEN0036 Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0266/1887] USB: cdc-acm: fix racy TIOCMIWAIT implementation Greg Kroah-Hartman
` (733 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhaofeng Chen, Yuxiao Wang,
Alexander Graf
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuxiao Wang <yuxiao.wang@certik.com>
commit 9bc184a2eda8b773c88ecbff934001ad649b9cc1 upstream.
When ne_create_vm_ioctl() fails the SLOT_ALLOC request after
anon_inode_getfile() has succeeded, the error path calls
fput(enclave_file) and then frees ne_enclave.
In normal userspace context, fput() defers the final __fput() via
task_work. ne_enclave_release() therefore runs after ne_enclave has
already been freed and dereferences ne_enclave->slot_uid, causing a
use-after-free: KASAN: slab-use-after-free in ne_enclave_release.
The enclave has no slot allocated and is not yet linked into the
enclaves list on this error path, so ne_enclave_release() is expected
to return early when slot_uid is zero. However, reading slot_uid
already accesses the freed object.
Clear enclave_file->private_data before fput() on the error path.
ne_enclave_release() then returns immediately when private_data is
NULL, leaving the ioctl error path as the sole owner of ne_enclave.
This is safe because the file has not been fd_install()'d yet.
Tested on an AWS EC2 m5.2xlarge with CONFIG_KASAN=y. Without the
patch, the reproducer triggers a KASAN slab-use-after-free on every
SLOT_ALLOC failure. With the patch, no KASAN report is produced and
the SLOT_ALLOC error is still returned. Normal enclave creation and
teardown are unaffected.
Fixes: 9c8eb50fe9e2 ("nitro_enclaves: Add logic for terminating an enclave")
Cc: stable@vger.kernel.org
Co-developed-by: Zhaofeng Chen <zhaofeng.chen@certik.com>
Signed-off-by: Zhaofeng Chen <zhaofeng.chen@certik.com>
Signed-off-by: Yuxiao Wang <yuxiao.wang@certik.com>
Reviewed-by: Alexander Graf <graf@amazon.com>
Link: https://patch.msgid.link/20260909124400.27857-1-graf@amazon.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/virt/nitro_enclaves/ne_misc_dev.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/virt/nitro_enclaves/ne_misc_dev.c
+++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c
@@ -1710,6 +1710,7 @@ static int ne_create_vm_ioctl(struct ne_
return enclave_fd;
put_file:
+ enclave_file->private_data = NULL;
fput(enclave_file);
put_fd:
put_unused_fd(enclave_fd);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0266/1887] USB: cdc-acm: fix racy TIOCMIWAIT implementation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0265/1887] nitro_enclaves: fix use-after-free on SLOT_ALLOC failure Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0267/1887] USB: cdc-acm: skip URB restart in port_shutdown if disconnected Greg Kroah-Hartman
` (732 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Oliver Neukum, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit be4219dd98608736e13e0b790ef742b76a13254d upstream.
Check the wakeup condition after adding the task to the waitqueue and
updating the task state to avoid missing a racing modem status update or
disconnect.
Store the old icount on entry and do not update it in the completion
handler to avoid missing events or reporting spurious ones (due to modem
status changes before TIOCMIWAIT was called).
Fixes: 5a6a62bdb925 ("cdc-acm: add TIOCMIWAIT")
Cc: stable <stable@kernel.org>
Cc: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260907095130.130636-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/class/cdc-acm.c | 36 +++++++++++++++++++-----------------
drivers/usb/class/cdc-acm.h | 1 -
2 files changed, 19 insertions(+), 18 deletions(-)
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -320,7 +320,6 @@ static void acm_process_notification(str
difference = acm->ctrlin ^ newctrl;
spin_lock_irqsave(&acm->read_lock, flags);
acm->ctrlin = newctrl;
- acm->oldcount = acm->iocount;
if (difference & USB_CDC_SERIAL_STATE_DSR)
acm->iocount.dsr++;
@@ -1002,11 +1001,16 @@ static int wait_serial_change(struct acm
DECLARE_WAITQUEUE(wait, current);
struct async_icount old, new;
- do {
+ spin_lock_irq(&acm->read_lock);
+ old = acm->iocount;
+ spin_unlock_irq(&acm->read_lock);
+
+ add_wait_queue(&acm->wioctl, &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
spin_lock_irq(&acm->read_lock);
- old = acm->oldcount;
new = acm->iocount;
- acm->oldcount = new;
spin_unlock_irq(&acm->read_lock);
if ((arg & TIOCM_DSR) &&
@@ -1019,22 +1023,20 @@ static int wait_serial_change(struct acm
old.rng != new.rng)
break;
- add_wait_queue(&acm->wioctl, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- remove_wait_queue(&acm->wioctl, &wait);
if (acm->disconnected) {
- if (arg & TIOCM_CD)
- break;
- else
- rv = -ENODEV;
- } else {
- if (signal_pending(current))
- rv = -ERESTARTSYS;
+ rv = -ENODEV;
+ break;
}
- } while (!rv);
-
+ schedule();
+
+ if (signal_pending(current)) {
+ rv = -ERESTARTSYS;
+ break;
+ }
+ }
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&acm->wioctl, &wait);
return rv;
}
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -90,7 +90,6 @@ struct acm {
unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
unsigned int ctrlout; /* output control lines (DTR, RTS) */
struct async_icount iocount; /* counters for control line changes */
- struct async_icount oldcount; /* for comparison of counter */
wait_queue_head_t wioctl; /* for ioctl */
unsigned int writesize; /* max packet size for the output bulk endpoint */
unsigned int readsize,ctrlsize; /* buffer sizes for freeing */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0267/1887] USB: cdc-acm: skip URB restart in port_shutdown if disconnected
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0266/1887] USB: cdc-acm: fix racy TIOCMIWAIT implementation Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0268/1887] USB: serial: fix port tear down use-after-free Greg Kroah-Hartman
` (731 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Yuchao Zhang
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuchao Zhang <ndaugoing@gmail.com>
commit dc614d6bc991740d41d5a99ac7765c4b675dda88 upstream.
acm_port_shutdown() is called from the tty-port machinery whenever the
last user closes the port. acm_disconnect() sets acm->disconnected and
calls tty_port_tty_vhangup(), which eventually triggers port_shutdown().
At that point acm_disconnect() has already called acm_poison_urbs() and
is about to free the control and read URBs.
However, acm_port_shutdown() unconditionally calls acm_unpoison_urbs()
and, when the ALWAYS_POLL_CTRL quirk is set, immediately re-submits the
ctrlurb and all read URBs. If the concurrent acm_disconnect() then
frees those URBs and their DMA buffers while they are in-flight, the
result is a use-after-free in acm_ctrl_irq() or acm_read_bulk_callback()
accessing the freed DMA memory.
Fix by checking acm->disconnected after draining the delayed anchor and
returning early: if we are in a disconnect path the URBs must remain
poisoned and must not be resubmitted.
The early return is placed after the delayed-anchor drain loop because
that loop only cancels write-side accounting (wb->use = false and
autopm counter) and does not touch the hardware path.
Fixes: f58752ebcb35 ("USB: cdc-acm: Add quirks for Yoga Book 9 14IAH10 INGENIC touchscreen")
Cc: stable <stable@kernel.org>
Signed-off-by: Yuchao Zhang <ndaugoing@gmail.com>
Link: https://patch.msgid.link/20260918114309.3659635-2-ndaugoing@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/class/cdc-acm.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -776,6 +776,9 @@ static void acm_port_shutdown(struct tty
usb_autopm_put_interface_async(acm->control);
}
+ if (acm->disconnected)
+ return;
+
acm_unpoison_urbs(acm);
if (acm->quirks & ALWAYS_POLL_CTRL) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0268/1887] USB: serial: fix port tear down use-after-free
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0267/1887] USB: cdc-acm: skip URB restart in port_shutdown if disconnected Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0269/1887] usb: storage: sierra_ms: reject short SWoC info transfers Greg Kroah-Hartman
` (730 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e5e28c3e953b2eebb16e,
Alan Stern, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 33c920f7c5952dfc42d1b8ea6efe16b1f0bb0c5b upstream.
Some drivers for multiport devices access port driver data from
completion handlers of shared URBs submitted at attach() or first open()
and stopped at disconnect() or last close(), respectively.
A simple NULL check before accessing the driver data makes sure that a
port state container has at least been allocated, but a completion
handler can still race with port tear down.
Reorder the disconnect handling so that ports are not deregistered (and
their driver data freed) until after all ports have been hung up and the
driver disconnect() callback has run so that all I/O has been stopped.
Fixes: 2d93148ab698 ("USB: serial: fix lifetime and locking problems")
Reported-by: syzbot+e5e28c3e953b2eebb16e@syzkaller.appspotmail.com
Link: https://lore.kernel.org/all/6a7e6fb9.ec5dc6cc.21cb3f.00c0.GAE@google.com/
Cc: stable@vger.kernel.org # 2.6.30
Cc: Alan Stern <stern@rowland.harvard.edu>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/usb-serial.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1194,12 +1194,17 @@ static void usb_serial_disconnect(struct
usb_serial_port_poison_urbs(port);
wake_up_interruptible(&port->port.delta_msr_wait);
cancel_work_sync(&port->work);
- if (device_is_registered(&port->dev))
- device_del(&port->dev);
}
+
if (serial->type->disconnect)
serial->type->disconnect(serial);
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (device_is_registered(&port->dev))
+ device_del(&port->dev);
+ }
+
release_sibling(serial, interface);
/* let the last holder of this object cause it to be cleaned up */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0269/1887] usb: storage: sierra_ms: reject short SWoC info transfers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0268/1887] USB: serial: fix port tear down use-after-free Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0270/1887] usb: hub: use shorter 120ms post resume hold for SS root hubs Greg Kroah-Hartman
` (729 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Syed Labeeq Sajid Bukhari
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Syed Labeeq Sajid Bukhari <syedlabeeq@gmail.com>
commit 8a0200d14acd9db388b85cd016e68a4e60d900ec upstream.
sierra_get_swoc_info() requests sizeof(struct swoc_info) (60) bytes
from the device via usb_control_msg(), but its callers only treat a
negative return value as failure. A device that answers the
vendor-specific GetSwocInfo request with a short IN transfer is
therefore accepted, leaving the tail of the freshly allocated
(kmalloc(), non-zeroing) swoc_info buffer uninitialized.
truinst_show() subsequently prints swocInfo->rev, swocInfo->LinuxSKU
and swocInfo->LinuxVer from that buffer into the world-readable
(0444) "truinst" sysfs attribute. An emulated/malicious USB device
(VID 0x1199, PID 0x0fff) can exploit this to disclose up to 5 bytes
of stale kernel heap memory (kmalloc-64) to unprivileged userspace,
once per sysfs read, indefinitely. On kernels built without
init_on_alloc this leaks recently freed heap contents.
Only accept the transfer when the full structure was received.
sierra_ms_init() already retries failed queries, so well-behaved
devices are unaffected.
Fixes: 32fe5e393455 ("USB Storage Sierra: TRU-Install feature update")
Cc: stable <stable@kernel.org>
Signed-off-by: Syed Labeeq Sajid Bukhari <syedlabeeq@gmail.com>
Assisted-by: Kimi:K2 [Kimi Code CLI]
Link: https://patch.msgid.link/20260910140343.49371-1-syedlabeeq@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/storage/sierra_ms.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -77,6 +77,13 @@ static int sierra_get_swoc_info(struct u
sizeof(struct swoc_info), /* __u16 size */
USB_CTRL_SET_TIMEOUT); /* int timeout */
+ /*
+ * A short IN transfer leaves the tail of swocInfo uninitialized;
+ * only a full transfer is valid.
+ */
+ if (result != sizeof(struct swoc_info))
+ return -EIO;
+
swocInfo->LinuxSKU = le16_to_cpu(swocInfo->LinuxSKU);
swocInfo->LinuxVer = le16_to_cpu(swocInfo->LinuxVer);
return result;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0270/1887] usb: hub: use shorter 120ms post resume hold for SS root hubs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0269/1887] usb: storage: sierra_ms: reject short SWoC info transfers Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0271/1887] usb: octeon-hcd: fix the FIFO-flush timeout computation Greg Kroah-Hartman
` (728 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mathieu Fluhr, stable,
Lovekesh Solanki, Mathias Nyman
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
commit 29480b05e6e226594dc11ccf2a036fbd5cdd0e42 upstream.
Holding a USB3 hub PM runtime reference for 200ms at hub resume triggers
an AMD platform issue. Users running Android adb report crashes after
adb has been polling and waking up the USB subsystem once a second for
some time. Vendors are working on a solution. Disabling USB runtime PM
is one way to prevent this issue, but it is also proven that reducing the
hold time to 120ms in resume also mitigates it. See Link for more
details.
Reducing the hold time to 120ms for the USB3 roothub is in itself a valid
change and optimization, as the current 200ms is excessive: a root hub
has no upstream suspended hub whose wake propagation needs to be
accounted for, but still need some time for USB3 link training to
complete.
Keep the 200ms hold for external hubs that commit 8f5b7e2bec1c
("usb: hub: fix detection of high tier USB3 devices behind suspended
hubs") is intended for.
Reported-by: Mathieu Fluhr <mathieu.fluhr@gmail.com>
Link: https://lore.kernel.org/all/CAPyJwA_D9qw0T72f8zwM1yKjP+To=maVANbcdsWM7yRmbBxYvw@mail.gmail.com/
Cc: stable <stable@kernel.org>
Fixes: 8f5b7e2bec1c ("usb: hub: fix detection of high tier USB3 devices behind suspended hubs")
Signed-off-by: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260903112903.542719-1-lovekeshsolanki00@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/hub.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -69,8 +69,11 @@
/*
* Give SS hubs 200ms time after wake to train downstream links before
* assuming no port activity and allowing hub to runtime suspend back.
+ * Root hubs have no upstream hub whose wake propagation needs to be
+ * accounted for, so they need less time, use 120ms for them.
*/
#define USB_SS_PORT_U0_WAKE_TIME 200 /* ms */
+#define USB_SS_RH_PORT_U0_WAKE_TIME 120 /* ms */
/* Protect struct usb_device->state and ->children members
* Note: Both are also protected by ->dev.sem, except that ->state can
@@ -1332,7 +1335,9 @@ static void hub_activate(struct usb_hub
queue_delayed_work(system_power_efficient_wq,
&hub->post_resume_work,
- msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
+ msecs_to_jiffies(hdev->parent ?
+ USB_SS_PORT_U0_WAKE_TIME :
+ USB_SS_RH_PORT_U0_WAKE_TIME));
return;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0271/1887] usb: octeon-hcd: fix the FIFO-flush timeout computation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0270/1887] usb: hub: use shorter 120ms post resume hold for SS root hubs Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0272/1887] usb: ohci-da8xx: disable controller wakeup on cleanup Greg Kroah-Hartman
` (727 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Orgad Shaneh
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Orgad Shaneh <orgads@gmail.com>
commit 4c7a1b9f1f1979f2b3b69428ada12680695159c2 upstream.
cvmx_wait_tx_rx() computes its 100us deadline from
(u64)octeon_get_clock_rate - the address of the function, not its
return value; the parentheses have been missing since the
CVMX_WAIT_FOR_FIELD32 macro became a function. The cast makes it
compile silently, and the resulting deadline is effectively infinite.
On a healthy controller the flush bit clears on the first read and
nothing is noticed. On a controller whose PHY did not come up (for
example when the reference-clock configuration is wrong for the board),
txfflsh/rxfflsh never clear and probe spins forever in __delay() -
observed as a hard hang with a soft-lockup splat on a CN5020 board,
where the board watchdog then resets the system with no console output.
Call the function, restoring the 100us timeout the code always
intended.
Fixes: 3e195a80e096 ("Staging: octeon-usb: Replaces CVMX_WAIT_FOR_FIELD32 macro with a function")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Link: https://patch.msgid.link/20260901193100.1352110-1-orgads@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/octeon-hcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/octeon-hcd.c
+++ b/drivers/usb/host/octeon-hcd.c
@@ -578,7 +578,7 @@ static int cvmx_wait_tx_rx(struct octeon
int result;
u64 address = CVMX_USBCX_GRSTCTL(usb->index);
u64 done = cvmx_get_cycle() + 100 *
- (u64)octeon_get_clock_rate / 1000000;
+ (u64)octeon_get_clock_rate() / 1000000;
union cvmx_usbcx_grstctl c;
while (1) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0272/1887] usb: ohci-da8xx: disable controller wakeup on cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0271/1887] usb: octeon-hcd: fix the FIFO-flush timeout computation Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0273/1887] usb: ohci-s3c2410: disable controller wakeup on removal Greg Kroah-Hartman
` (726 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Alan Stern
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 901197dd4c7dcffbf97426487d4c047555c98554 upstream.
The OHCI core marks controllers with RemoteWakeupConnected as
wakeup-capable. Probe enables wakeup, but neither removal nor a later
notifier registration failure disables it, leaving the wakeup source
attached.
Disable controller wakeup after removing the HCD on both paths.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: a6eeeb9f45b5 ("USB: Update USB default wakeup settings")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260915012011.61874-2-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/ohci-da8xx.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -464,6 +464,7 @@ static int ohci_da8xx_probe(struct platf
err_remove_hcd:
usb_remove_hcd(hcd);
+ device_wakeup_disable(hcd->self.controller);
err:
usb_put_hcd(hcd);
return error;
@@ -474,6 +475,7 @@ static int ohci_da8xx_remove(struct plat
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_remove_hcd(hcd);
+ device_wakeup_disable(hcd->self.controller);
usb_put_hcd(hcd);
return 0;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0273/1887] usb: ohci-s3c2410: disable controller wakeup on removal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0272/1887] usb: ohci-da8xx: disable controller wakeup on cleanup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0274/1887] usb: ohci-st: " Greg Kroah-Hartman
` (725 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Alan Stern
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 8dd8451c527e2a723bca20da5a6d724b8592551f upstream.
Probe enables controller wakeup after the OHCI core marks controllers with
RemoteWakeupConnected as wakeup-capable. Removal does not undo this, so the
wakeup source can remain attached after driver unbind.
Disable controller wakeup after removing the HCD.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: a6eeeb9f45b5 ("USB: Update USB default wakeup settings")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260915012011.61874-3-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/ohci-s3c2410.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -335,6 +335,7 @@ ohci_hcd_s3c2410_remove(struct platform_
struct usb_hcd *hcd = platform_get_drvdata(dev);
usb_remove_hcd(hcd);
+ device_wakeup_disable(hcd->self.controller);
s3c2410_stop_hc(dev);
usb_put_hcd(hcd);
return 0;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0274/1887] usb: ohci-st: disable controller wakeup on removal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0273/1887] usb: ohci-s3c2410: disable controller wakeup on removal Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0275/1887] usb: gadget: f_uac1_legacy: validate bRequest index in generic_{set,get}_cmd Greg Kroah-Hartman
` (724 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Patrice Chotard, Alan Stern
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 08b2ccd7eb7e41f77a04a09112ca3edcc588e3f0 upstream.
Probe enables controller wakeup after the OHCI core marks controllers with
RemoteWakeupConnected as wakeup-capable. Removal does not undo this, so the
wakeup source can remain attached after driver unbind.
Disable controller wakeup after removing the HCD.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: d115837259ad ("usb: host: ohci-st: Add OHCI driver support for ST STB devices")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260915012011.61874-5-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/ohci-st.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/usb/host/ohci-st.c
+++ b/drivers/usb/host/ohci-st.c
@@ -241,6 +241,7 @@ static int st_ohci_platform_remove(struc
int clk;
usb_remove_hcd(hcd);
+ device_wakeup_disable(hcd->self.controller);
if (pdata->power_off)
pdata->power_off(dev);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0275/1887] usb: gadget: f_uac1_legacy: validate bRequest index in generic_{set,get}_cmd
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0274/1887] usb: ohci-st: " Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0276/1887] usb: typec: anx7411 - stop the IRQ before destroying the workqueue Greg Kroah-Hartman
` (723 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Weibin Liu, Liu Chao,
Ivy Lopez
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Chao <liuc63@xiaopeng.com>
commit 9062d50e75c24dc7911be05c9b1719b3b256af15 upstream.
generic_set_cmd() and generic_get_cmd() use the low nibble of
ctrl->bRequest as an index into con->data[]:
u8 cmd = (ctrl->bRequest & 0x0F); /* 0 .. 15 */
...
con->data[cmd] = value; /* OOB when cmd >= 5 */
struct usb_audio_control (include/linux/usb/audio.h) declares data as
a 5-element array, so indices 5 through 15 write (or read) up to 44
bytes past the end of the array on the heap.
A malicious USB host can craft a class-specific SET_CUR / GET_CUR
request with an arbitrary bRequest value, triggering the out-of-bounds
access from an IRQ completion handler with no further preconditions.
Add an ARRAY_SIZE() guard to both functions.
Fixes: c47d7b09891a ("USB: audio: add USB audio class definitions")
Cc: stable <stable@kernel.org>
Reviewed-by: Weibin Liu <liuwb@xiaopeng.com>
Signed-off-by: Liu Chao <liuc63@xiaopeng.com>
Reviewed-by: Ivy Lopez <skunkolee@gmail.com>
Link: https://patch.msgid.link/20260921072551.3708191-1-liuc63@xiaopeng.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/function/f_uac1_legacy.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/usb/gadget/function/f_uac1_legacy.c
+++ b/drivers/usb/gadget/function/f_uac1_legacy.c
@@ -797,6 +797,9 @@ fail:
static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value)
{
+ if (cmd >= ARRAY_SIZE(con->data))
+ return -EINVAL;
+
con->data[cmd] = value;
return 0;
@@ -804,6 +807,9 @@ static int generic_set_cmd(struct usb_au
static int generic_get_cmd(struct usb_audio_control *con, u8 cmd)
{
+ if (cmd >= ARRAY_SIZE(con->data))
+ return -EINVAL;
+
return con->data[cmd];
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0276/1887] usb: typec: anx7411 - stop the IRQ before destroying the workqueue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0275/1887] usb: gadget: f_uac1_legacy: validate bRequest index in generic_{set,get}_cmd Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0277/1887] usb: dwc3: am62: Fix runtime PM usage count leak on probe error path Greg Kroah-Hartman
` (722 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Linkai Gong, Heikki Krogerus
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linkai Gong <gonglinkai@kylinos.cn>
commit 469600d5d292b1482c90dd6853555821d11b8c5f upstream.
The IRQ is devm-managed, so it can still queue plat->work while
remove() is tearing the queue down. Disable it first.
Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support")
Cc: stable <stable@kernel.org>
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260910011150.2966843-1-gonglinkai@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/anx7411.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/usb/typec/anx7411.c
+++ b/drivers/usb/typec/anx7411.c
@@ -1572,8 +1572,11 @@ static void anx7411_i2c_remove(struct i2
anx7411_partner_unregister_altmode(plat);
anx7411_unregister_partner(plat);
- if (plat->workqueue)
+ if (plat->workqueue) {
+ disable_irq(plat->intp_irq);
+ cancel_work_sync(&plat->work);
destroy_workqueue(plat->workqueue);
+ }
if (plat->spi_client)
i2c_unregister_device(plat->spi_client);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0277/1887] usb: dwc3: am62: Fix runtime PM usage count leak on probe error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0276/1887] usb: typec: anx7411 - stop the IRQ before destroying the workqueue Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0278/1887] usb: gadget: aspeed-vhub: cancel wake work on device removal Greg Kroah-Hartman
` (721 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Radhey Shyam Pandey,
Thinh Nguyen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
commit 3d9bbf0ffeb9b7ac1b6ad06b52e037870a7e0c63 upstream.
dwc3_ti_probe() takes a runtime PM reference with pm_runtime_get_noresume()
before creating the dwc3 core child device, and releases it with
pm_runtime_put_autosuspend() once probe has succeeded. The err_pm_disable
error path only disables runtime PM, so the reference taken a few lines
earlier is never dropped.
The usage counter lives in struct device and is not reset when the driver
is unbound, so the leaked reference outlives the failed probe. If the
device is probed again, through a manual rebind or a module reload, the
counter starts at one instead of zero and the pm_runtime_put_autosuspend()
on the success path can no longer bring it back down. The wrapper then
stays runtime resumed for good and autosuspend never kicks in.
Drop the reference before disabling runtime PM, matching the ordering
already used in dwc3_ti_remove().
Fixes: e8784c0aec03 ("drivers: usb: dwc3: Add AM62 USB wrapper driver")
Cc: stable <stable@kernel.org>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20260902-dwc3-am62-rpm-fix-v1-1-7a2807e33307@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/dwc3/dwc3-am62.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ b/drivers/usb/dwc3/dwc3-am62.c
@@ -243,6 +243,7 @@ static int dwc3_ti_probe(struct platform
err_pm_disable:
clk_disable_unprepare(am62->usb2_refclk);
+ pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
return ret;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0278/1887] usb: gadget: aspeed-vhub: cancel wake work on device removal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0277/1887] usb: dwc3: am62: Fix runtime PM usage count leak on probe error path Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0279/1887] USB: gadget: dummy-hcd: Fix wait for outstanding request completions Greg Kroah-Hartman
` (720 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Song Li, Fan Wu,
Benjamin Herrenschmidt
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 20388c8d1d74c203fec8194c45cd31afdfab934e upstream.
wake_work is armed from the gadget .wakeup callback to resume suspended
downstream ports, and it is never cancelled in ast_vhub_remove(), so a
work item queued before or during removal can run after devm has freed
vhub and its ports, a use-after-free.
Cancelling the work alone is not sufficient: usb_gadget_wakeup() takes
no lock and the unbind path never clears wakeup_en, so a remote-wakeup
request in flight on another CPU can re-arm the work after the cancel
and before vhub is freed.
ast_vhub_del_dev() already clears d->registered under vhub->lock before
unregistering the gadget. Refuse the wakeup in ast_vhub_udc_wakeup()
once d->registered is clear: the check and the schedule_work() are then
atomic against the unbind, so a wakeup that passed before the flag was
cleared is drained by the cancel_work_sync() after the del_dev loop,
and one that arrives later returns without arming. Also move INIT_WORK()
to the top of ast_vhub_probe(), since the probe error path reuses
ast_vhub_remove() and would otherwise cancel a never-initialized work
item.
This issue was found by an in-house static analysis tool.
Fixes: 7ecca2a4080c ("usb/gadget: Add driver for Aspeed SoC virtual hub")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Link: https://patch.msgid.link/20260908041740.613713-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/udc/aspeed-vhub/core.c | 4 ++++
drivers/usb/gadget/udc/aspeed-vhub/dev.c | 2 +-
drivers/usb/gadget/udc/aspeed-vhub/hub.c | 5 +++--
drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 1 +
4 files changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
@@ -267,6 +267,9 @@ static int ast_vhub_remove(struct platfo
for (i = 0; i < vhub->max_ports; i++)
ast_vhub_del_dev(&vhub->ports[i].dev);
+ /* Final drain; the worker takes vhub->lock, so stay outside of it */
+ cancel_work_sync(&vhub->wake_work);
+
spin_lock_irqsave(&vhub->lock, flags);
/* Mask & ack all interrupts */
@@ -327,6 +330,7 @@ static int ast_vhub_probe(struct platfor
return -ENOMEM;
spin_lock_init(&vhub->lock);
+ INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);
vhub->pdev = pdev;
vhub->port_irq_mask = GENMASK(VHUB_IRQ_DEV1_BIT + vhub->max_ports - 1,
VHUB_IRQ_DEV1_BIT);
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
@@ -281,7 +281,7 @@ static int ast_vhub_udc_wakeup(struct us
int rc = -EINVAL;
spin_lock_irqsave(&d->vhub->lock, flags);
- if (!d->wakeup_en)
+ if (!d->wakeup_en || !d->registered)
goto err;
DDBG(d, "Device initiated wakeup\n");
--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
@@ -558,7 +558,7 @@ void ast_vhub_device_connect(struct ast_
ast_vhub_send_host_wakeup(vhub);
}
-static void ast_vhub_wake_work(struct work_struct *work)
+void ast_vhub_wake_work(struct work_struct *work)
{
struct ast_vhub *vhub = container_of(work,
struct ast_vhub,
@@ -588,6 +588,8 @@ static void ast_vhub_wake_work(struct wo
void ast_vhub_hub_wake_all(struct ast_vhub *vhub)
{
+ lockdep_assert_held(&vhub->lock);
+
/*
* A device is trying to wake the world, because this
* can recurse into the device, we break the call chain
@@ -1076,7 +1078,6 @@ static int ast_vhub_init_desc(struct ast
int ast_vhub_init_hub(struct ast_vhub *vhub)
{
vhub->speed = USB_SPEED_UNKNOWN;
- INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);
return ast_vhub_init_desc(vhub);
}
--- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
+++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
@@ -546,6 +546,7 @@ void ast_vhub_hub_suspend(struct ast_vhu
void ast_vhub_hub_resume(struct ast_vhub *vhub);
void ast_vhub_hub_reset(struct ast_vhub *vhub);
void ast_vhub_hub_wake_all(struct ast_vhub *vhub);
+void ast_vhub_wake_work(struct work_struct *work);
/* dev.c */
int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0279/1887] USB: gadget: dummy-hcd: Fix wait for outstanding request completions
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0278/1887] usb: gadget: aspeed-vhub: cancel wake work on device removal Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0280/1887] usb: gadget: f_fs: Fix NULL pointer dereference in FUNCTIONFS_ENDPOINT_DESC Greg Kroah-Hartman
` (719 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Minseo Kim, Alan Stern, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <stern@rowland.harvard.edu>
commit b263ff9b0fc5c1f371d65c4eb196b31263d039ff upstream.
The dummy-hcd driver emulates synchronize_irq() by waiting until its
private callback_usage counter drops to 0 (with the private lock not
held). This counter is incremented whenever a gadget driver callback
occurs (which requires the private lock to be dropped), but not when a
request completion handler is called.
This is an oversight. Request completion is triggered by timer
interrupts (emulating device IRQs in a real UDC), and the interrupt
handlers are supposed to have completed when the synchronize_irq()
emulation routine returns -- they aren't supposed to be in the middle
of a completion callback. If this happens it can lead to a gadget
driver's unbind routine running before all outstanding request
completions have finished, maybe even allowing the gadget driver's
module to be unloaded while a completion handler is still running.
Fix the oversight by incrementing the callback_usage value across
request completion callbacks.
Link: https://lore.kernel.org/linux-usb/7a87e293-633c-4100-aa8d-91560ba5e5c5@rowland.harvard.edu/
Fixes: 7dbd8f4cabd9 ("USB: dummy-hcd: Fix erroneous synchronization change")
Tested-by: Minseo Kim <neck3922@gmail.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org>
Link: https://patch.msgid.link/f23b9e1a-f110-441a-a1d8-95f442ec09d5@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/udc/dummy_hcd.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -342,9 +342,11 @@ static void dummy_giveback(struct dummy
{
bool fifo = req == &dum->fifo_req;
+ ++dum->callback_usage;
spin_unlock(&dum->lock);
usb_gadget_giveback_request(_ep, &req->req);
spin_lock(&dum->lock);
+ --dum->callback_usage;
if (fifo)
dum->fifo_req_busy = 0;
}
@@ -758,11 +760,13 @@ static int dummy_queue(struct usb_ep *_e
req->req.complete = fifo_complete;
list_add_tail(&req->queue, &ep->queue);
+ ++dum->callback_usage;
spin_unlock(&dum->lock);
_req->actual = _req->length;
_req->status = 0;
usb_gadget_giveback_request(_ep, _req);
spin_lock(&dum->lock);
+ --dum->callback_usage;
} else
list_add_tail(&req->queue, &ep->queue);
spin_unlock_irqrestore(&dum->lock, flags);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0280/1887] usb: gadget: f_fs: Fix NULL pointer dereference in FUNCTIONFS_ENDPOINT_DESC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0279/1887] USB: gadget: dummy-hcd: Fix wait for outstanding request completions Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0281/1887] usb: chipidea: tegra: disable runtime PM on resume failure Greg Kroah-Hartman
` (718 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Yuchao Zhang,
Michał Nazarewicz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuchao Zhang <ndaugoing@gmail.com>
commit 9cd072788c76595529eb38f42bf94d23852f8534 upstream.
When user space sets up FunctionFS with only full-speed descriptors
(e.g., flags = FUNCTIONFS_HAS_FS_DESC) and the gadget operates at a
higher speed (such as USB_SPEED_HIGH or USB_SPEED_SUPER),
config_ep_by_speed() detects that the function lacks descriptors for
the current speed, logs a warning, and falls back to full-speed
descriptors. The endpoint is then successfully enabled via
usb_ep_enable(), and epfile->ep becomes valid.
However, when user space subsequently issues the FUNCTIONFS_ENDPOINT_DESC
ioctl to query the endpoint descriptor, ffs_epfile_ioctl() selects the
descriptor index solely based on gadget->speed:
switch (epfile->ffs->gadget->speed) {
case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
desc_idx = 2;
break;
case USB_SPEED_HIGH:
desc_idx = 1;
break;
default:
desc_idx = 0;
}
desc = epfile->ep->descs[desc_idx];
memcpy(&desc1, desc, desc->bLength);
Because user space only supplied full-speed descriptors,
epfile->ep->descs[1] is NULL. Dereferencing desc->bLength triggers an
immediate kernel NULL pointer dereference panic.
Fix this by falling back through lower speed descriptors if the current
speed descriptor was not supplied, matching the fallback logic in
config_ep_by_speed() and historical f_fs behavior. If still missing,
fall back to epfile->ep->ep->desc (the active descriptor), and return
-EINVAL safely if no valid descriptor is found. In addition, mark desc
as const to match struct usb_ep::desc and avoid discarding qualifiers.
Fixes: c559a3534109 ("usb: gadget: f_fs: add ioctl returning ep descriptor")
Cc: stable@kernel.org
Signed-off-by: Yuchao Zhang <ndaugoing@gmail.com>
Acked-by: Michał Nazarewicz <mina86@mina86.com>
Link: https://patch.msgid.link/20260918005438.81263-2-ndaugoing@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/function/f_fs.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1351,8 +1351,9 @@ static long ffs_epfile_ioctl(struct file
break;
case FUNCTIONFS_ENDPOINT_DESC:
{
+ const struct usb_endpoint_descriptor *desc;
+ struct usb_endpoint_descriptor desc1;
int desc_idx;
- struct usb_endpoint_descriptor desc1, *desc;
switch (epfile->ffs->gadget->speed) {
case USB_SPEED_SUPER:
@@ -1366,7 +1367,17 @@ static long ffs_epfile_ioctl(struct file
desc_idx = 0;
}
- desc = epfile->ep->descs[desc_idx];
+ do {
+ desc = epfile->ep->descs[desc_idx];
+ } while (!desc && --desc_idx >= 0);
+
+ if (!desc)
+ desc = epfile->ep->ep->desc;
+ if (!desc) {
+ ret = -EINVAL;
+ break;
+ }
+
memcpy(&desc1, desc, desc->bLength);
spin_unlock_irq(&epfile->ffs->eps_lock);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0281/1887] usb: chipidea: tegra: disable runtime PM on resume failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0280/1887] usb: gadget: f_fs: Fix NULL pointer dereference in FUNCTIONFS_ENDPOINT_DESC Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0282/1887] usb: core: clear both ep_in and ep_out for non-ep0 control endpoints Greg Kroah-Hartman
` (717 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Peter Chen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit f1d6f7d25fe88ee49aaad96c8649e090fc3a4b68 upstream.
tegra_usb_probe() enables runtime PM before resuming the device. If
pm_runtime_resume_and_get() fails, probe returns without disabling runtime
PM. The later error paths reach pm_runtime_force_suspend(), but this early
return bypasses that cleanup.
Disable runtime PM before returning the resume error. Do not use the
fail_power_off path: the failed resume did not retain a usage reference,
so its pm_runtime_put_sync_suspend() would be unbalanced.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 8b85e11c1a7a ("usb: chipidea: tegra: Add runtime PM and OPP support")
Cc: stable <stable@kernel.org>
Assisted-by: OpenAI:GPT-5.6
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://patch.msgid.link/20260913041033.25144-1-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/chipidea/ci_hdrc_tegra.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/usb/chipidea/ci_hdrc_tegra.c
+++ b/drivers/usb/chipidea/ci_hdrc_tegra.c
@@ -307,8 +307,10 @@ static int tegra_usb_probe(struct platfo
pm_runtime_enable(&pdev->dev);
err = pm_runtime_resume_and_get(&pdev->dev);
- if (err)
+ if (err) {
+ pm_runtime_disable(&pdev->dev);
return err;
+ }
if (device_property_present(&pdev->dev, "nvidia,needs-double-reset"))
usb->needs_double_reset = true;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0282/1887] usb: core: clear both ep_in and ep_out for non-ep0 control endpoints
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0281/1887] usb: chipidea: tegra: disable runtime PM on resume failure Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0283/1887] usb: typec: tcpm: recover after failure to start the frs ams Greg Kroah-Hartman
` (716 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Hui Peng, Alan Stern
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 0e8baa78d872f2db440d8b9ded946ab8dceb89eb upstream.
In usb_enable_endpoint(), non-zero control endpoints (where
usb_endpoint_xfer_control(&ep->desc) is true) populate both
dev->ep_in[epnum] and dev->ep_out[epnum] with the same struct
usb_host_endpoint pointer.
However, usb_disable_endpoint() only clears either dev->ep_out[epnum] or
dev->ep_in[epnum] depending on the direction bit of epaddr when
reset_hardware is set, leaving the opposite direction's array slot
pointing to the disabled/freed endpoint.
Clear both dev->ep_out[epnum] and dev->ep_in[epnum] when disabling a
non-ep0 control endpoint with reset_hardware set, and update the
function kerneldoc accordingly.
Tested in QEMU against Linux 7.3.0-rc3 using dummy_hcd and raw-gadget to
enumerate a USB device with a non-zero control endpoint
(bEndpointAddress 0x01, bmAttributes USB_ENDPOINT_XFER_CONTROL),
verifying that both dev->ep_in[1] and dev->ep_out[1] are cleared when
the interface is disabled.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260920231702.110963-1-benquike@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/message.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1331,7 +1331,8 @@ static void remove_intf_ep_devs(struct u
*
* Disables the endpoint for URB submission and nukes all pending URBs.
* If @reset_hardware is set then also deallocates hcd/hardware state
- * for the endpoint.
+ * for the endpoint (clearing both ep_in and ep_out pointers for
+ * bidirectional non-ep0 control endpoints).
*/
void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
bool reset_hardware)
@@ -1352,6 +1353,11 @@ void usb_disable_endpoint(struct usb_dev
dev->ep_in[epnum] = NULL;
}
if (ep) {
+ if (reset_hardware && epnum != 0 &&
+ usb_endpoint_xfer_control(&ep->desc)) {
+ dev->ep_out[epnum] = NULL;
+ dev->ep_in[epnum] = NULL;
+ }
ep->enabled = 0;
usb_hcd_flush_endpoint(dev, ep);
if (reset_hardware)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0283/1887] usb: typec: tcpm: recover after failure to start the frs ams
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0282/1887] usb: core: clear both ep_in and ep_out for non-ep0 control endpoints Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0284/1887] usb: typec: tipd: fix uninitialized typec_partner_desc in tps6598x_connect() Greg Kroah-Hartman
` (715 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Amit Sunil Dhamne,
Badhri Jagan Sridharan, Heikki Krogerus
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <amitsd@google.com>
commit 90156585765b29304f07b0e4a1c56a969876fcfc upstream.
Reset the port if the tcpm fails to start the FAST_ROLE_SWAP AMS by
initiating error recovery on it.
This helps in cases where some cables (incorrectly) signal an FRS to
an FRS capable port during disconnection. The TCPC autonomously starts
sourcing VBUS on detecting the FRS signal. However, the VBUS sourcing is
left on when the FAST_ROLE_SWAP AMS fails to start (as tcpm_sink_tx_ok
is 0 as CC is open due to the cable disconnect). This is because the
code sets the state to INVALID_STATE without resetting the port state.
Log snippet before changes:
[ 101.401960] AMS FAST_ROLE_SWAP start
[ 101.401971] Sink TX No Go
[ 101.401982] sourcing vbus
[ 101.401987] VBUS on
[ 101.402159] VBUS on
[ 109.257809] CC1: 0 -> 0, CC2: 5 -> 0 [state SNK_READY, polarity 1, disconnected]
[ 111.267442] VBUS on
After changes:
[ 70.541211] AMS FAST_ROLE_SWAP start
[ 70.541220] Sink TX No Go
[ 70.541228] state change SNK_READY -> ERROR_RECOVERY [rev3 NONE_AMS]
[ 70.541362] VBUS on
[ 70.541365] sourcing vbus
[ 70.541367] VBUS on
[ 70.541374] state change ERROR_RECOVERY -> PORT_RESET [rev3 NONE_AMS]
[ 70.541410] disable vbus discharge ret:0
[ 70.543028] Setting usb_comm capable false
[ 70.544009] Setting voltage/current limit 0 mV 0 mA
[ 70.544034] polarity 0
[ 70.544239] Requesting mux state 0, usb-role 0, orientation 0
[ 70.555550] cc:=0
[ 70.555595] pending state change PORT_RESET -> PORT_RESET_WAIT_OFF @ 100 ms [rev3 NONE_AMS]
[ 70.555697] VBUS off
[ 70.555702] VBUS VSAFE0V
[ 70.555762] CC1: 5 -> 0, CC2: 0 -> 0 [state PORT_RESET, polarity 0, disconnected]
[ 70.587794] VBUS off
[ 70.587799] VBUS VSAFE0V
[ 70.655672] state change PORT_RESET -> PORT_RESET_WAIT_OFF [delayed 100 ms]
[ 70.655682] state change PORT_RESET_WAIT_OFF -> SNK_UNATTACHED [rev3 NONE_AMS]
[ 70.655686] Start toggling
[ 70.656274] CC1: 0 -> 0, CC2: 0 -> 0 [state TOGGLING, polarity 0, disconnected]
Fixes: 0908c5aca31e ("usb: typec: tcpm: AMS and Collision Avoidance")
Cc: stable <stable@kernel.org>
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260903-frs-error-handling-v1-1-ad0fee541847@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -5540,7 +5540,7 @@ static void tcpm_pd_event_handler(struct
port->upcoming_state = FR_SWAP_SEND;
ret = tcpm_ams_start(port, FAST_ROLE_SWAP);
if (ret == -EAGAIN)
- port->upcoming_state = INVALID_STATE;
+ tcpm_set_state(port, ERROR_RECOVERY, 0);
} else {
tcpm_log(port, "Discarding FRS_SIGNAL! Not in sink ready");
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0284/1887] usb: typec: tipd: fix uninitialized typec_partner_desc in tps6598x_connect()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0283/1887] usb: typec: tcpm: recover after failure to start the frs ams Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0285/1887] usb: typec: ucsi: Get the connector fwnode based on reg value Greg Kroah-Hartman
` (714 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heikki Krogerus, Radhey Shyam Pandey,
stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
commit c4b27b3605788bbf9e4251f3cd4ab94645ab036f upstream.
tps6598x_connect() passes a stack-allocated typec_partner_desc to
typec_register_partner() after initializing only usb_pd, accessory and
identity.
typec_register_partner() copies attach and deattach from the descriptor
into the partner. With those fields left unset, garbage function pointers
may be stored and later invoked from typec_partner_link_device() when a USB
device is linked to the port. Uninitialized pd_revision and usb_capability
similarly leak stack data through partner sysfs.
Zero-initialize the descriptor so optional callbacks remain NULL and the
remaining fields are zero.
Fixes: 0a4c005bd171 ("usb: typec: driver for TI TPS6598x USB Power Delivery controllers")
Cc: stable <stable@kernel.org> # 5.15+
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/20260906131942.83153-2-radhey.shyam.pandey@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tipd/core.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -231,7 +231,7 @@ static void tps6598x_set_data_role(struc
static int tps6598x_connect(struct tps6598x *tps, u32 status)
{
- struct typec_partner_desc desc;
+ struct typec_partner_desc desc = { };
enum typec_pwr_opmode mode;
int ret;
@@ -242,7 +242,6 @@ static int tps6598x_connect(struct tps65
desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
- desc.identity = NULL;
if (desc.usb_pd) {
ret = tps6598x_read_partner_identity(tps);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0285/1887] usb: typec: ucsi: Get the connector fwnode based on reg value
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0284/1887] usb: typec: tipd: fix uninitialized typec_partner_desc in tps6598x_connect() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0286/1887] usb: typec: ucsi: displayport: Current CAM OOB index fixup Greg Kroah-Hartman
` (713 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Prashanth K, Heikki Krogerus
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth K <prashanth.k@oss.qualcomm.com>
commit 6c51f09c6db5868a5090e8dd4d7764660c87f1ad upstream.
ucsi_find_fwnode() currently maps UCSI connectors to Device tree
connector nodes based on the order in which connector child nodes
are described in DT.
This can fail because the ordering of child nodes isn't guaranteed
in Device-tree. For example, DTB may contain connector@1 before
connector@0, causing connector numbers to be associated with the wrong
fwnode. As a result, role switch and Type-C notifications can be
delivered to the wrong remote endpoints.
Fix this by using the "reg" property of each connector to match
its corresponding fwnode. While at it, if the reg property isn't
present, then fall back to the old method.
Fixes: c1b0bc2dabfa ("usb: typec: Add support for UCSI interface")
Cc: stable <stable@kernel.org>
Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260916042808.2879079-1-prashanth.k@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/ucsi/ucsi.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1092,10 +1092,21 @@ static struct fwnode_handle *ucsi_find_f
{
struct fwnode_handle *fwnode;
int i = 1;
+ int ret;
+ u32 port;
- device_for_each_child_node(con->ucsi->dev, fwnode)
- if (i++ == con->num)
- return fwnode;
+ device_for_each_child_node(con->ucsi->dev, fwnode) {
+ ret = fwnode_property_read_u32(fwnode, "reg", &port);
+ if (ret < 0) {
+ if (i == con->num)
+ return fwnode;
+ } else {
+ if (port == con->num - 1)
+ return fwnode;
+ }
+
+ i++;
+ }
return NULL;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0286/1887] usb: typec: ucsi: displayport: Current CAM OOB index fixup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0285/1887] usb: typec: ucsi: Get the connector fwnode based on reg value Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0287/1887] usb: cdns3: fix use-after-free in cdns3_gadget_exit() Greg Kroah-Hartman
` (712 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Heikki Krogerus,
Benson Leung, Jameson Thies
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jameson Thies <jthies@google.com>
commit ea31c6498c61307dc0d8ce338a7f268cb8cbdd57 upstream.
Update ucsi_displayport_enter() to return invalid error when the PPM
reports an current alternate mode greater than or equal to
UCSI_MAX_ALTMODES. While here, remove 0xff current cam assignment on
failed GET_CURRENT_CAM response.
Fixes: 04cec690b1fd ("usb: typec: ucsi: displayport: Fix OOB altmode array index")
Cc: stable <stable@kernel.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Benson Leung <bleung@chromium.org>
Signed-off-by: Jameson Thies <jthies@google.com>
Link: https://patch.msgid.link/20260917032008.1701888-1-jthies@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/ucsi/displayport.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/usb/typec/ucsi/displayport.c
+++ b/drivers/usb/typec/ucsi/displayport.c
@@ -71,11 +71,14 @@ static int ucsi_displayport_enter(struct
if (ret < 0) {
if (ucsi->version > 0x0100)
goto err_unlock;
- cur = 0xff;
}
- if (cur < UCSI_MAX_ALTMODES) {
- ret = dp->con->port_altmode[cur] == alt ? 0 : -EBUSY;
+ if (cur != 0xff) {
+ if (cur < UCSI_MAX_ALTMODES)
+ ret = dp->con->port_altmode[cur] == alt ? 0 : -EBUSY;
+ else
+ ret = -EINVAL;
+
goto err_unlock;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0287/1887] usb: cdns3: fix use-after-free in cdns3_gadget_exit()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0286/1887] usb: typec: ucsi: displayport: Current CAM OOB index fixup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0288/1887] usb: cdns3: Fix NULL pointer dereference in cdns3_pci_probe Greg Kroah-Hartman
` (711 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Sicong Huang, Song Li,
Fan Wu, Peter Chen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit ebe9b68c396792c15d0ac690d592e449e74ed804 upstream.
cdns3_gadget_start() arms two works on system_freezable_wq:
pending_status_wq for the deferred ep0 status stage and aligned_buf_wq
for realigned request buffers. Both handlers use the cdns3_device the
works are embedded in, and cdns3_pending_setup_status_handler() also
calls the ep0 request completion.
cdns3_gadget_exit() does not wait for these works. It frees all
endpoints and aligned buffers and drops the last reference to the
gadget device, which frees priv_dev, so a work queued before the exit
can run after the free.
Fix this by waiting for both works after the gadget driver is unbound
and the IRQ is freed, when no new work can be queued, and before the
endpoints and buffers are released.
This issue was found by an in-house static analysis tool.
Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
Cc: stable <stable@kernel.org>
Reported-by: Sicong Huang <congei42@163.com>
Closes: https://lore.kernel.org/linux-usb/7f5719b.8700.18f67b324d3.Coremail.congei42@163.com/
Suggested-by: Sicong Huang <congei42@163.com>
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://patch.msgid.link/20260909095655.694527-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/cdns3/cdns3-gadget.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -3265,6 +3265,10 @@ static void cdns3_gadget_exit(struct cdn
usb_del_gadget(&priv_dev->gadget);
devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
+ /* The works can still be queued until the IRQ is freed. */
+ cancel_work_sync(&priv_dev->pending_status_wq);
+ cancel_work_sync(&priv_dev->aligned_buf_wq);
+
cdns3_free_all_eps(priv_dev);
while (!list_empty(&priv_dev->aligned_buf_list)) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0288/1887] usb: cdns3: Fix NULL pointer dereference in cdns3_pci_probe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0287/1887] usb: cdns3: fix use-after-free in cdns3_gadget_exit() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0289/1887] tty: vt: fix memory leak in vc_allocate() Greg Kroah-Hartman
` (710 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Jie Deng, Peter Chen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Deng <dengjie03@kylinos.cn>
commit e5052f2c5c73c1dcca42bafc0bc737af2b2af059 upstream.
The Cadence USBSS controller is a two-function PCI device. The first
probed function allocates the driver data and stores it with
pci_set_drvdata(), while the second function reuses it via
pci_get_drvdata() when pci_is_enabled() reports that the first
function has already been probed.
When the second function is probed while the first one has been
enabled but has not yet set its driver data, pci_get_drvdata()
returns NULL, and the subsequent wrap->devfn assignment dereferences
a NULL pointer and crashes the kernel.
logs:
Call trace:
cdns3_pci_probe+0xa4/0x300
local_pci_probe+0x44/0xa8
pci_call_probe+0x54/0x158
pci_device_probe+0x84/0x100
really_probe+0x184/0x3d0
__driver_probe_device+0x80/0x178
driver_probe_device+0x44/0xe8
__driver_attach+0xec/0x1f8
bus_for_each_dev+0x7c/0xe0
driver_attach+0x28/0x38
bus_add_driver+0x110/0x238
driver_register+0x64/0x128
__pci_register_driver+0x50/0x60
cdns3_pci_driver_init+0x28/0x38
do_one_initcall+0x5c/0x280
do_initcalls+0x104/0x1d8
kernel_init_freeable+0x140/0x218
kernel_init+0x28/0x1f8
ret_from_fork+0x10/0x20
Return -EPROBE_DEFER in this case so that probing is retried after
the first function has completed its probe.
Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Jie Deng <dengjie03@kylinos.cn>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://patch.msgid.link/20260810023626.70669-1-dengjie03@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/cdns3/cdns3-pci-wrap.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/usb/cdns3/cdns3-pci-wrap.c
+++ b/drivers/usb/cdns3/cdns3-pci-wrap.c
@@ -99,6 +99,11 @@ static int cdns3_pci_probe(struct pci_de
if (pci_is_enabled(func)) {
wrap = pci_get_drvdata(func);
+ if (!wrap) {
+ dev_err(&pdev->dev,
+ "second function not initialized, retrying\n");
+ return -EPROBE_DEFER;
+ }
} else {
wrap = kzalloc(sizeof(*wrap), GFP_KERNEL);
if (!wrap)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0289/1887] tty: vt: fix memory leak in vc_allocate()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (287 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0288/1887] usb: cdns3: Fix NULL pointer dereference in cdns3_pci_probe Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0290/1887] tty: amiserial: fix broken TIOCMIWAIT Greg Kroah-Hartman
` (709 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Mingyu Wang
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
commit 5b114bfc1dfd88f9d50822d532f7f1fce0f7388a upstream.
If the screen buffer allocation fails in vc_allocate(), the error handling
path jumps to `err_free`. However, this path fails to release the unicode
screen map attached to `vc->uni_pagedict_loc`.
During the early stages of vc_allocate(), the unicode screen map is either
newly allocated via con_set_default_unimap() or shares the default unicode
map from a previously initialized console (which increments its refcount).
If the subsequent kzalloc() for the screen buffer fails, the err_free path
frees the vc structure but leaves the attached uni_pagedict with an
elevated refcount. This results in an unreferenced object memory leak, as
the reference to the dictionary is lost and its refcount can never reach
zero.
This issue was discovered by DevGen (an automated virtual device modeling
fuzzer based on Syzkaller). During fuzzing with kernel fault injection
(failslab) enabled, the fuzzer forcefully failed the kzalloc() for the
screen buffer, exposing this error-handling path leak.
Fix this by checking *vc->uni_pagedict_loc and calling con_free_unimap(vc)
in the err_free path before kfree(vc). This safely decrements the refcount
and releases the dictionary memory if this was the last reference. The
explicit check is added to maintain consistency with other callers.
Fixes: 34902b7f2754 ("tty: vt, get rid of weird source code flow")
Cc: stable <stable@kernel.org>
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20260803144556.163856-1-25181214217@stu.xidian.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/vt/vt.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1160,6 +1160,8 @@ int vc_allocate(unsigned int currcons) /
return 0;
err_free:
visual_deinit(vc);
+ if (*vc->uni_pagedict_loc)
+ con_free_unimap(vc);
kfree(vc);
vc_cons[currcons].d = NULL;
return err;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0290/1887] tty: amiserial: fix broken TIOCMIWAIT
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (288 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0289/1887] tty: vt: fix memory leak in vc_allocate() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0291/1887] tty: vcc: zero-initialize control packet in vcc_send_ctl() Greg Kroah-Hartman
` (708 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Arnd Bergmann,
Johan Hovold, Jiri Slaby, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 615f35fd5aee169cc4881a8594f2fa234a4d0bb8 upstream.
A change replacing interruptible_sleep_on() inadvertently broke the
TIOCMIWAIT implementation which now immediately returns -EIO (unless
there is a racing modem status update).
Replace the old hangup (and signal) detection with a check for the
TTY_IO_ERROR flag which is set on hangup.
Fixes: 591cee0a3563 ("tty/amiserial: avoid interruptible_sleep_on")
Reported-by: sashiko-bot@kernel.org
Link: https://lore.kernel.org/20260910132029.D80801F00898@smtp.kernel.org
Cc: stable@kernel.org # 3.14
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Link: https://patch.msgid.link/20260911090132.723531-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/amiserial.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1140,11 +1140,6 @@ static int rs_ioctl(struct tty_struct *t
local_irq_save(flags);
cnow = info->icount; /* atomic copy */
local_irq_restore(flags);
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
- ret = -EIO; /* no change => error */
- break;
- }
if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
@@ -1152,6 +1147,10 @@ static int rs_ioctl(struct tty_struct *t
ret = 0;
break;
}
+ if (tty_io_error(tty)) {
+ ret = -EIO;
+ break;
+ }
schedule();
/* see if a signal did it */
if (signal_pending(current)) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0291/1887] tty: vcc: zero-initialize control packet in vcc_send_ctl()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (289 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0290/1887] tty: amiserial: fix broken TIOCMIWAIT Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0292/1887] tty: vcc: hold port lock when clearing tty pointer in vcc_cleanup Greg Kroah-Hartman
` (707 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Joshua Rogers, Jiri Slaby
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <linux@joshua.hu>
commit 1f71f565e3585da1098ff19ca3c24687dab59185 upstream.
The stack-allocated struct vio_vcc pkt was partially initialized,
leaving the tag.stype_env field uninitialized before being sent via
ldc_write(), potentially leaking kernel stack data to the LDC peer.
Assisted-by: AISLE:Snapshot
Cc: stable <stable@kernel.org>
Signed-off-by: Joshua Rogers <linux@joshua.hu>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Link: https://patch.msgid.link/20260803-aisle-tty-vcc-v2-1-a50bc9b15193@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/vcc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/tty/vcc.c
+++ b/drivers/tty/vcc.c
@@ -492,7 +492,7 @@ static ssize_t domain_show(struct device
static int vcc_send_ctl(struct vcc_port *port, int ctl)
{
- struct vio_vcc pkt;
+ struct vio_vcc pkt = {};
int rv;
pkt.tag.type = VIO_TYPE_CTRL;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0292/1887] tty: vcc: hold port lock when clearing tty pointer in vcc_cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (290 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0291/1887] tty: vcc: zero-initialize control packet in vcc_send_ctl() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0293/1887] tty: serial: qcom_geni_serial: Keep console RX functional after deep idle Greg Kroah-Hartman
` (706 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Joshua Rogers, Jiri Slaby
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <linux@joshua.hu>
commit 03b49c991abb8d021ca6fe51cd173447236b0552 upstream.
vcc_cleanup() sets port->tty to NULL without holding port->lock, racing
with vcc_event() LDC callbacks that read port->tty under port->lock and
then use tty->port. This can cause a use-after-free when the callback
dereferences tty->port after cleanup has already destroyed and freed it.
Assisted-by: AISLE:Snapshot
Cc: stable <stable@kernel.org>
Signed-off-by: Joshua Rogers <linux@joshua.hu>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Link: https://patch.msgid.link/20260803-aisle-tty-vcc-v2-2-a50bc9b15193@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/vcc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/tty/vcc.c
+++ b/drivers/tty/vcc.c
@@ -985,7 +985,8 @@ static void vcc_cleanup(struct tty_struc
port = vcc_get(tty->index, true);
if (port) {
- port->tty = NULL;
+ scoped_guard(spinlock_irqsave, &port->lock)
+ port->tty = NULL;
if (port->removed) {
vcc_table_remove(tty->index);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0293/1887] tty: serial: qcom_geni_serial: Keep console RX functional after deep idle
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (291 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0292/1887] tty: vcc: hold port lock when clearing tty pointer in vcc_cleanup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0294/1887] tty: abort break signalling on hangup Greg Kroah-Hartman
` (705 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Konrad Dybcio,
Viken Dadhaniya
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
commit 63ef71d1474b5417b5b2dec700cd251c44a570d9 upstream.
At baud rates up to 115200, the serial console uses only a 1 kBps keepalive
vote for the GENI_TO_CORE ("qup-core") ICC path. This vote keeps the path
active but does not request a QUP Core 2X clock rate.
When the CPU enters a deeper idle state, the missing Core clock vote can
leave the console RX path unresponsive.
Use the 19.2 MHz Core 2X vote at low baud rates, while retaining the 50 MHz
vote at higher baud rates, so that console RX remains functional after deep
idle transitions.
Fixes: 7cf563b2c846 ("tty: serial: qcom_geni_serial: Add interconnect support")
Cc: stable@kernel.org
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Link: https://patch.msgid.link/20260915-correct-icc-bandwidth-vote-constants-v2-2-f78eb611204e@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/qcom_geni_serial.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1056,9 +1056,8 @@ static void qcom_geni_serial_set_termios
* Bump up BW vote on CPU and CORE path as driver supports FIFO mode
* only.
*/
- avg_bw_core = (baud > 115200) ? Bps_to_icc(CORE_2X_50_MHZ)
- : GENI_DEFAULT_BW;
- port->se.icc_paths[GENI_TO_CORE].avg_bw = avg_bw_core;
+ avg_bw_core = baud > 115200 ? CORE_2X_50_MHZ : CORE_2X_19_2_MHZ;
+ port->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(avg_bw_core);
port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud);
geni_icc_set_bw(&port->se);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0294/1887] tty: abort break signalling on hangup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (292 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0293/1887] tty: serial: qcom_geni_serial: Keep console RX functional after deep idle Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0295/1887] serial: 8250_bcm7271: fix use-after-free in brcmuart_remove() Greg Kroah-Hartman
` (704 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 845a2737e0f5ffe5ca8d38de556012b0c9472cdd upstream.
The break ioctls can race with hangup and end up calling into a tty
driver for a device that is already gone or powered down.
Drivers must handle this race, but TCSBRK and TCSBRKP should still be
aborted to avoid calling back into the driver after a user-controlled
timeout (possibly even after the tty has been reopened).
Note that drivers should disable any break state on shutdown so just
return on hangup (calling break_ctl() again is racy and will most likely
fail for drivers handling the race).
Fixes: f34d7a5b7010 ("tty: The big operations rework")
Cc: stable <stable@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260903163736.1499280-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/tty_io.c | 36 +++++++++++++++++++++++++++---------
include/linux/tty.h | 1 +
2 files changed, 28 insertions(+), 9 deletions(-)
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -630,6 +630,8 @@ static void __tty_hangup(struct tty_stru
tty_ldisc_hangup(tty, cons_filp != NULL);
+ wake_up_interruptible(&tty->break_wait);
+
spin_lock_irq(&tty->ctrl.lock);
clear_bit(TTY_THROTTLED, &tty->flags);
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
@@ -2457,6 +2459,7 @@ static int tiocgetd(struct tty_struct *t
* send_break - performed time break
* @tty: device to break on
* @duration: timeout in mS
+ * @file: file object
*
* Perform a timed break on hardware that lacks its own driver level timed
* break functionality.
@@ -2464,8 +2467,9 @@ static int tiocgetd(struct tty_struct *t
* Locking:
* @tty->atomic_write_lock serializes
*/
-static int send_break(struct tty_struct *tty, unsigned int duration)
+static int send_break(struct file *file, struct tty_struct *tty, unsigned int duration)
{
+ long timeout;
int retval;
if (tty->ops->break_ctl == NULL)
@@ -2479,13 +2483,26 @@ static int send_break(struct tty_struct
return -EINTR;
retval = tty->ops->break_ctl(tty, -1);
- if (!retval) {
- msleep_interruptible(duration);
- retval = tty->ops->break_ctl(tty, 0);
- } else if (retval == -EOPNOTSUPP) {
- /* some drivers can tell only dynamically */
- retval = 0;
+ if (retval) {
+ if (retval == -EOPNOTSUPP) {
+ /* some drivers can tell only dynamically */
+ retval = 0;
+ }
+ goto out_unlock;
+ }
+
+ timeout = msecs_to_jiffies(duration);
+ timeout = wait_event_interruptible_timeout(tty->break_wait,
+ tty_hung_up_p(file),
+ timeout);
+ /* return early on hangup only */
+ if (timeout > 0) {
+ retval = -EIO;
+ goto out_unlock;
}
+
+ retval = tty->ops->break_ctl(tty, 0);
+out_unlock:
tty_write_unlock(tty);
if (signal_pending(current))
@@ -2738,10 +2755,10 @@ long tty_ioctl(struct file *file, unsign
* This is used by the tcdrain() termios function.
*/
if (!arg)
- return send_break(tty, 250);
+ return send_break(file, tty, 250);
return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */
- return send_break(tty, arg ? arg*100 : 250);
+ return send_break(file, tty, arg ? arg * 100 : 250);
case TIOCMGET:
return tty_tiocmget(tty, p);
@@ -3104,6 +3121,7 @@ struct tty_struct *alloc_tty_struct(stru
init_ldsem(&tty->ldisc_sem);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
+ init_waitqueue_head(&tty->break_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->ctrl.lock);
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -235,6 +235,7 @@ struct tty_struct {
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
+ wait_queue_head_t break_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0295/1887] serial: 8250_bcm7271: fix use-after-free in brcmuart_remove()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (293 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0294/1887] tty: abort break signalling on hangup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0296/1887] serial: tegra: dont clear the Tx FIFO on an Rx-only reset Greg Kroah-Hartman
` (703 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Song Li, Fan Wu,
Florian Fainelli
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 189b9dc8c96ec9486482f27c1372b04a7152175e upstream.
brcmuart_handle_irq() starts priv->hrt to work around a receive-timeout
quirk of the 8250 core when hardware flow control is enabled; the timer
callback brcmuart_hrtimer_func() dereferences priv.
brcmuart_remove() cancels the hrtimer before it unregisters the port, so
a receive-timeout interrupt that arrives in between re-arms the timer.
After devm frees priv, the callback runs on freed memory.
Unregister the port before cancelling the hrtimer.
serial8250_unregister_port() shuts the port down and frees its IRQ, so
brcmuart_handle_irq() can no longer restart the timer, and the final
hrtimer_cancel() drains any timer that was armed before or during the
unregister.
This issue was found by an in-house static analysis tool.
Fixes: 41a469482de2 ("serial: 8250: Add new 8250-core based Broadcom STB driver")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260909084002.686911-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/8250/8250_bcm7271.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/tty/serial/8250/8250_bcm7271.c
+++ b/drivers/tty/serial/8250/8250_bcm7271.c
@@ -1153,8 +1153,8 @@ static int brcmuart_remove(struct platfo
struct brcmuart_priv *priv = platform_get_drvdata(pdev);
debugfs_remove_recursive(priv->debugfs_dir);
- hrtimer_cancel(&priv->hrt);
serial8250_unregister_port(priv->line);
+ hrtimer_cancel(&priv->hrt);
brcmuart_free_bufs(&pdev->dev, priv);
clk_disable_unprepare(priv->baud_mux_clk);
if (priv->dma_enabled)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0296/1887] serial: tegra: dont clear the Tx FIFO on an Rx-only reset
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (294 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0295/1887] serial: 8250_bcm7271: fix use-after-free in brcmuart_remove() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0297/1887] serial: vt8500: Fix clock reference leak in vt8500_serial_probe() Greg Kroah-Hartman
` (702 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Simon Gassner
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Gassner <simon.gassner@noxsystems.com>
commit 8aebfde6e84dceb7d47fe8001e50b754eb45d5df upstream.
tegra_uart_fifo_reset() applies the Tegra30 workaround for
"cannot clear the Tx FIFO while FIFO mode is enabled"
unconditionally: it leaves FIFO mode, writes the requested FCR
clear bits, and re-enters FIFO mode. Leaving FIFO mode empties
both FIFOs, so an Rx-only reset discards queued Tx data as well.
The break handler in tegra_uart_decode_rx_error() calls it with
UART_FCR_CLEAR_RCVR only. On a half-duplex RS485 board whose Rx
line is pulled low while the transceiver drives the bus, every
transmission raises a spurious break, and all but the first
character of the frame is lost.
Only take the FIFO-mode path when the caller actually asked for
CLEAR_XMIT. Likewise only wait for TEMT in that case: with the Tx
FIFO deliberately left intact, that loop would otherwise spin for
a full frame time in hard IRQ context with the port lock held.
Tested on a Colibri T30 (Tegra30) with Rx DMA:
- Break during transmission: the reset still fires from
tegra_uart_decode_rx_error(), and the complete frame now
reaches the peer. Before this change only the character in
the shift register was sent.
- Internal loopback with a generated break: the Rx FIFO is
correctly cleared by the plain FCR write, and subsequent
receive works with no frame, parity or overrun errors.
Fixes: e9ea096dd225 ("serial: tegra: add serial driver")
Cc: stable@kernel.org
Signed-off-by: Simon Gassner <simon.gassner@noxsystems.com>
Link: https://patch.msgid.link/20261001060539.32659-1-simon.gassner@noxsystems.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/serial-tegra.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -307,11 +307,19 @@ static void tegra_uart_fifo_reset(struct
{
unsigned long fcr = tup->fcr_shadow;
unsigned int lsr, tmout = 10000;
+ bool clear_tx = !!(fcr_bits & UART_FCR_CLEAR_XMIT);
if (tup->rts_active)
set_rts(tup, false);
- if (tup->cdata->allow_txfifo_reset_fifo_mode) {
+ /*
+ * Leaving FIFO mode below is a workaround for a Tegra30
+ * restriction on clearing the Tx FIFO while FIFO mode is
+ * enabled. It empties both FIFOs, so applying it to an
+ * Rx-only reset would destroy an in-flight transmission.
+ * Only take that path when the caller asked for CLEAR_XMIT.
+ */
+ if (tup->cdata->allow_txfifo_reset_fifo_mode || !clear_tx) {
fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
tegra_uart_write(tup, fcr, UART_FCR);
} else {
@@ -336,9 +344,15 @@ static void tegra_uart_fifo_reset(struct
*/
tegra_uart_wait_cycle_time(tup, 32);
+ /*
+ * Only wait for the transmitter to drain when the Tx FIFO was
+ * part of the reset. For an Rx-only reset it is left intact,
+ * and waiting for TEMT here would spin for a full frame time.
+ */
do {
lsr = tegra_uart_read(tup, UART_LSR);
- if ((lsr & UART_LSR_TEMT) && !(lsr & UART_LSR_DR))
+ if ((!clear_tx || (lsr & UART_LSR_TEMT)) &&
+ !(lsr & UART_LSR_DR))
break;
udelay(1);
} while (--tmout);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0297/1887] serial: vt8500: Fix clock reference leak in vt8500_serial_probe()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (295 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0296/1887] serial: tegra: dont clear the Tx FIFO on an Rx-only reset Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0298/1887] ASoC: qcom: lpass-cpu: use DAI table index for playback constraints Greg Kroah-Hartman
` (701 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Wentao Liang
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 9d8955281d9229a899e2041659a59b389027b711 upstream.
of_clk_get() returns a clock with a reference that has to be released
with clk_put(). If clk_prepare_enable() fails the function returns
without doing so, leaking the reference.
Add the missing clk_put() on that error path.
Fixes: 12faa35ae5cb ("serial: vt8500: UART uses gated clock rather than 24Mhz reference")
Cc: stable@kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917155834.2161361-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/vt8500_serial.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -682,6 +682,7 @@ static int vt8500_serial_probe(struct pl
ret = clk_prepare_enable(vt8500_port->clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
+ clk_put(vt8500_port->clk);
return ret;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0298/1887] ASoC: qcom: lpass-cpu: use DAI table index for playback constraints
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (296 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0297/1887] serial: vt8500: Fix clock reference leak in vt8500_serial_probe() Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0299/1887] ALSA: seq: Serialize compat port-info ioctls Greg Kroah-Hartman
` (700 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zimeng Li, Srinivas Kandagatla,
Mark Brown
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zimeng Li <me@lizi.moe>
commit ca51771c8efde5df05476ac98dd1b2af4e2b149f upstream.
The DAI ID is a hardware port ID and is not necessarily the index of
the corresponding entry in variant->dai_driver.
When configuring a DAI with LPAIF_I2SCTL_MODE_QUAD01, the probe code
currently uses dai_id to index variant->dai_driver. This is incorrect
for platforms where DAI IDs are sparse. For example, the IPQ806x MI2S
DAI has ID 4 while it is the only entry in the DAI driver table. If
that DAI is configured for QUAD01 and probe reaches this branch, the
code writes beyond that single entry via dai_driver[4] instead of
updating the DAI being processed.
Use the loop index i when updating the current DAI's playback channel
constraints, while retaining dai_id for indexing the hardware-port
specific playback SD-line mode array.
This fixes the incorrect DAI table access for platforms where the DAI
ID does not match its position in the driver table.
Fixes: c223f41c1a52 ("ASoC: qcom: Add four speaker support on MI2S secondary")
Cc: stable@vger.kernel.org
Signed-off-by: Zimeng Li <me@lizi.moe>
Assisted-by: LLM-assisted source analysis
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Link: https://patch.msgid.link/20260927010911.51980-1-me@lizi.moe
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/qcom/lpass-cpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -1228,8 +1228,8 @@ int asoc_qcom_lpass_cpu_platform_probe(s
}
if (drvdata->mi2s_playback_sd_mode[dai_id] ==
LPAIF_I2SCTL_MODE_QUAD01) {
- variant->dai_driver[dai_id].playback.channels_min = 4;
- variant->dai_driver[dai_id].playback.channels_max = 4;
+ variant->dai_driver[i].playback.channels_min = 4;
+ variant->dai_driver[i].playback.channels_max = 4;
}
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0299/1887] ALSA: seq: Serialize compat port-info ioctls
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (297 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0298/1887] ASoC: qcom: lpass-cpu: use DAI table index for playback constraints Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0300/1887] ALSA: ua101: reject mismatched capture/playback packet sizes Greg Kroah-Hartman
` (699 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Bruno Produit,
Takashi Iwai
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
commit 95b2e0361c88753afa030c10698be0a1a5b67650 upstream.
The native sequencer ioctl path serializes handler calls with
client->ioctl_mutex, but the translated port-info compat path invokes the
same handlers through snd_seq_kernel_client_ctl() without taking that
mutex.
This lets concurrent compat CREATE_PORT requests pass the port-count
check before any request reaches the serialized insertion. The computed
integer port index can then exceed the address field range and wrap to an
existing index. Subsequent subscriber teardown can resolve the duplicate
address to the wrong port and access a freed subscriber.
Take ioctl_mutex while dispatching converted port-info requests, matching
the native ioctl path. All translated port-info commands share this
helper, so their accesses to the client port state are serialized as
well.
Fixes: b3defb791b26 ("ALSA: seq: Make ioctls race-free")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol gpt-6-astra
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: Bruno Produit <bruno.produit@trailofbits.com>
Link: https://patch.msgid.link/20260917105643.90102-1-bruno.produit@trailofbits.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/core/seq/seq_compat.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -44,7 +44,9 @@ static int snd_seq_call_port_info_ioctl(
goto error;
data->kernel = NULL;
- err = snd_seq_kernel_client_ctl(client->number, cmd, data);
+ scoped_guard(mutex, &client->ioctl_mutex) {
+ err = snd_seq_kernel_client_ctl(client->number, cmd, data);
+ }
if (err < 0)
goto error;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0300/1887] ALSA: ua101: reject mismatched capture/playback packet sizes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (298 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0299/1887] ALSA: seq: Serialize compat port-info ioctls Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0301/1887] Bluetooth: RFCOMM: Fix initial port reference race Greg Kroah-Hartman
` (698 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+24304d323d28f156, Xiang Mei,
Takashi Iwai
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <xmei5@asu.edu>
commit 86f86e6fdedc33c5b8d38b9208b350f8accf57ee upstream.
detect_usb_format() cross-checks bSubframeSize, bBitResolution and
tSamFreq between the capture and playback interfaces, but never relates
the two endpoints' wMaxPacketSize and bNrChannels. Each playback URB
gets a buffer of ua->playback.max_packet_bytes, while the number of
bytes written into it is derived from the capture stream:
capture_urb_complete() computes frames from the received capture packet
and capture.frame_bytes, and start_usb_playback() and playback_work()
multiply that by playback.frame_bytes.
A device declaring a large capture wMaxPacketSize with few capture
channels and a small playback wMaxPacketSize with many playback channels
therefore memset()s and memcpy()s past the end of the playback buffer,
in open() of the PCM node the driver registers during probe.
usb_submit_urb() rejects the over-long iso_frame_desc[0].length with
-EMSGSIZE, but only after the write.
Reject such descriptors at probe time. Genuine UA-101/UA-1000 hardware
declares proportional packet sizes and is unaffected.
BUG: KASAN: slab-out-of-bounds in start_usb_playback (sound/usb/misc/ua101.c:586)
Write of size 2048 at addr ffff8881098f3c00 by task exploit/5021
Call Trace:
__asan_memset (mm/kasan/shadow.c:84)
start_usb_playback (sound/usb/misc/ua101.c:586)
playback_pcm_open (sound/usb/misc/ua101.c:679)
snd_pcm_open_substream (sound/core/pcm_native.c:2829)
snd_pcm_open (sound/core/pcm_native.c:2865 sound/core/pcm_native.c:2932)
snd_pcm_playback_open (sound/core/pcm_native.c:2891)
snd_open (sound/core/sound.c:166)
chrdev_open (fs/char_dev.c:411)
do_dentry_open (fs/open.c:996)
vfs_open (fs/open.c:1101)
path_openat (fs/namei.c:4837 fs/namei.c:5000)
do_file_open (fs/namei.c:5029)
do_sys_openat2 (fs/open.c:1417)
__x64_sys_openat (fs/open.c:1423 fs/open.c:1439 fs/open.c:1434)
do_syscall_64 (arch/x86/entry/syscall_64.c:61 arch/x86/entry/syscall_64.c:84)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
The buggy address belongs to the object at ffff8881098f3c00
which belongs to the cache kmalloc-192 of size 192
The buggy address is located 0 bytes inside of
allocated 168-byte region [ffff8881098f3c00, ffff8881098f3ca8)
Cc: stable@vger.kernel.org
Fixes: 63978ab3e3e9 ("sound: add Edirol UA-101 support")
Reported-by: <co+24304d323d28f156@bugs.sh>
Assisted-by: LLM
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260918225753.1278505-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/misc/ua101.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1022,6 +1022,15 @@ static int detect_usb_format(struct ua10
}
ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
ua->playback.max_packet_bytes = usb_endpoint_maxp(epd);
+
+ if (ua->capture.max_packet_bytes / ua->capture.frame_bytes *
+ ua->playback.frame_bytes > ua->playback.max_packet_bytes) {
+ dev_err(&ua->dev->dev,
+ "playback packet size %u too small for %u capture frames\n",
+ ua->playback.max_packet_bytes,
+ ua->capture.max_packet_bytes / ua->capture.frame_bytes);
+ return -ENXIO;
+ }
return 0;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0301/1887] Bluetooth: RFCOMM: Fix initial port reference race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (299 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0300/1887] ALSA: ua101: reject mismatched capture/playback packet sizes Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0302/1887] Bluetooth: hci_conn: Lock parent access during enhanced SCO setup Greg Kroah-Hartman
` (697 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 2d696c1ed3468dcb62578a3911e687110d463520 upstream.
For RFCOMM_RELEASE_ONHUP devices, rfcomm_tty_install() and
__rfcomm_release_dev() both use RFCOMM_TTY_OWNED to decide who drops the
initial tty_port reference. The release path tests the bit separately
from the install path setting it, so both can drop that reference.
The synchronous hangup does not prevent this race: port->tty is not
assigned until tty_port_open(), after installation. The following
interleaving is possible:
1. Install and release each obtain a reference with rfcomm_dev_get().
2. Release observes RFCOMM_TTY_OWNED clear.
3. Install sets RFCOMM_TTY_OWNED and drops the initial reference.
4. Release drops the same initial reference again.
5. TTY cleanup drops its reference and frees the device.
6. Release performs its final tty_port_put() on the freed port.
KASAN reported:
BUG: KASAN: slab-use-after-free in tty_port_put+0x22/0x190
Write of size 4 at addr ffff8881001d3d5c by task poc/92
Call Trace:
tty_port_put+0x22/0x190
rfcomm_dev_ioctl+0x1d4/0x1930
sock_do_ioctl+0x110/0x260
sock_ioctl+0x380/0x590
__x64_sys_ioctl+0x134/0x1c0
Allocated by task 88:
rfcomm_dev_ioctl+0x8f6/0x1930
sock_do_ioctl+0x110/0x260
sock_ioctl+0x380/0x590
__x64_sys_ioctl+0x134/0x1c0
Freed by task 65:
kfree+0x131/0x3c0
rfcomm_dev_destruct+0x23b/0x2f0
release_one_tty+0xc1/0x370
process_one_work+0x661/0x1090
Use test_and_set_bit() in both paths so that only the caller that changes
RFCOMM_TTY_OWNED from clear to set drops the initial reference. Each path
keeps its own lookup reference until release or TTY cleanup, preserving
the existing callback ordering and error handling.
Fixes: 80ea73378af4 ("Bluetooth: Fix unreleased rfcomm_dev reference")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/tty.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -465,7 +465,7 @@ static int __rfcomm_release_dev(void __u
/* Shut down TTY synchronously before freeing rfcomm_dev */
tty_port_tty_vhangup(&dev->port);
- if (!test_bit(RFCOMM_TTY_OWNED, &dev->status))
+ if (!test_and_set_bit(RFCOMM_TTY_OWNED, &dev->status))
tty_port_put(&dev->port);
tty_port_put(&dev->port);
@@ -730,10 +730,9 @@ static int rfcomm_tty_install(struct tty
* when the last process closes the tty. The behaviour is expected by
* userspace.
*/
- if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
- set_bit(RFCOMM_TTY_OWNED, &dev->status);
+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) &&
+ !test_and_set_bit(RFCOMM_TTY_OWNED, &dev->status))
tty_port_put(&dev->port);
- }
return 0;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0302/1887] Bluetooth: hci_conn: Lock parent access during enhanced SCO setup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (300 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0301/1887] Bluetooth: RFCOMM: Fix initial port reference race Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:39 ` [PATCH 6.1 0303/1887] Bluetooth: hci_core: Fix inquiry cache timestamps on 64-bit systems Greg Kroah-Hartman
` (696 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 024e05f73a4c1263d031614bc36700ec135eecb4 upstream.
Bluetooth: hci_conn: Lock parent access during enhanced SCO setup
hci_enhanced_setup_sync() runs on the request workqueue without the
hci_dev_lock held by its caller when setup was queued. Its CVSD
capability check and find_next_esco_param() dereference conn->parent
while the receive workqueue can unlink and release that parent.
The following interleaving can cause a use-after-free:
hci_enhanced_setup_sync() hci_disconn_complete_evt()
load conn->parent
hci_dev_lock()
hci_conn_del(ACL parent)
unlink SCO child
drop link's parent reference
clear child->parent
release ACL parent
bt_link_release()
kfree(parent)
hci_dev_unlock()
read parent->features[0][3]
The reference held for the queued SCO child does not keep its ACL parent
alive after unlinking. Commit 42de40abe25d ("Bluetooth: hci_conn: fix the
SCO setup context lifetime") protects the child stored in the queued
context, but leaves these parent accesses unprotected.
With a 40 ms diagnostic delay after loading conn->parent, an instrumented
kernel based on fd179f8a05be, which already contains 42de40abe25d,
reported:
BUG: KASAN: slab-use-after-free in hci_enhanced_setup_sync+0xda5/0xdf0
Read of size 1 at addr ffff888102204047 by task kworker/u17:0/93
Call Trace:
hci_enhanced_setup_sync+0xda5/0xdf0
hci_cmd_sync_work+0x13c/0x290
process_one_work+0x6b4/0x10e0
Allocated by task 92:
__hci_conn_add+0x304/0x1df0
hci_connect_acl+0x349/0x3e0
hci_connect_sco+0x3b/0x9a0
sco_sock_connect+0x475/0xca0
Freed by task 94:
kfree+0x121/0x3c0
bt_link_release+0x79/0xa0
device_release+0xc8/0x240
kobject_put+0x14d/0x280
hci_conn_del+0x524/0xe30
hci_disconn_complete_evt+0x403/0x8c0
hci_event_packet+0x71b/0xb20
hci_rx_work+0x293/0x730
The accessed address is 71 bytes into the freed ACL parent, at its
features[0][3] byte; the queued SCO child is a different object. The
diagnostic preserves the loaded parent across the delay, matching the
unmodified compiled capability check, and does not change the parent
references or teardown path.
Hold hci_dev_lock() across the codec switch, including every call to
find_next_esco_param(), and release it on all selection errors. Keep
configure_datapath_sync() outside the critical section because it waits
for HCI events. Preserve parameter selection and existing return values.
Fixes: e07a06b4eb41 ("Bluetooth: Convert SCO configure_datapath to hci_sync")
Cc: stable@vger.kernel.org
Assisted-by: GPT-6-Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_conn.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -412,11 +412,13 @@ static int hci_enhanced_setup_sync(struc
cp.tx_bandwidth = cpu_to_le32(0x00001f40);
cp.rx_bandwidth = cpu_to_le32(0x00001f40);
+ hci_dev_lock(hdev);
+
switch (conn->codec.id) {
case BT_CODEC_MSBC:
if (!find_next_esco_param(conn, esco_param_msbc,
ARRAY_SIZE(esco_param_msbc)))
- return -EINVAL;
+ goto unlock;
param = &esco_param_msbc[conn->attempt - 1];
cp.tx_coding_format.id = 0x05;
@@ -442,7 +444,7 @@ static int hci_enhanced_setup_sync(struc
case BT_CODEC_TRANSPARENT:
if (!find_next_esco_param(conn, esco_param_msbc,
ARRAY_SIZE(esco_param_msbc)))
- return -EINVAL;
+ goto unlock;
param = &esco_param_msbc[conn->attempt - 1];
cp.tx_coding_format.id = 0x03;
@@ -469,11 +471,11 @@ static int hci_enhanced_setup_sync(struc
if (lmp_esco_capable(conn->link)) {
if (!find_next_esco_param(conn, esco_param_cvsd,
ARRAY_SIZE(esco_param_cvsd)))
- return -EINVAL;
+ goto unlock;
param = &esco_param_cvsd[conn->attempt - 1];
} else {
if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
- return -EINVAL;
+ goto unlock;
param = &sco_param_cvsd[conn->attempt - 1];
}
cp.tx_coding_format.id = 2;
@@ -496,9 +498,11 @@ static int hci_enhanced_setup_sync(struc
cp.out_transport_unit_size = 16;
break;
default:
- return -EINVAL;
+ goto unlock;
}
+ hci_dev_unlock(hdev);
+
cp.retrans_effort = param->retrans_effort;
cp.pkt_type = __cpu_to_le16(param->pkt_type);
cp.max_latency = __cpu_to_le16(param->max_latency);
@@ -507,6 +511,10 @@ static int hci_enhanced_setup_sync(struc
return -EIO;
return 0;
+
+unlock:
+ hci_dev_unlock(hdev);
+ return -EINVAL;
}
static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0303/1887] Bluetooth: hci_core: Fix inquiry cache timestamps on 64-bit systems
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (301 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0302/1887] Bluetooth: hci_conn: Lock parent access during enhanced SCO setup Greg Kroah-Hartman
@ 2026-10-28 16:39 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0304/1887] Bluetooth: hci_core: Serialize ACL scheduling with channel deletion Greg Kroah-Hartman
` (695 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linmao Li, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
commit 74847177eca5638827ab74cdf77f0b10fc40ca6c upstream.
On 64-bit systems, outgoing BR/EDR connections always fall back to page
scan repetition mode R2 with no clock offset once the system has been
up for more than five minutes, even when inquiry found the peer only
seconds earlier. This lengthens paging and can increase the risk of a
Page Timeout.
The inquiry cache stores jiffies in __u32 timestamps, but its age
helpers subtract them from unsigned long jiffies. INITIAL_JIFFIES casts
-300 * HZ through unsigned int, so jiffies crosses 2^32 five minutes
after boot on 64-bit systems. Assigning it to __u32 then drops the upper
32 bits. In one trace, a 7.6-second-old entry (HZ=1000) was reported as
2^32 + 7620 ticks old and rejected by hci_acl_create_conn_sync().
hci_inquiry() is affected by the same truncation when checking the whole
cache. 32-bit systems are unaffected because unsigned long is 32 bits
wide there.
Use unsigned long for both timestamps so they have the same width as
jiffies on 32-bit and 64-bit systems, and update the debugfs format
specifier accordingly.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/bluetooth/hci_core.h | 4 ++--
net/bluetooth/hci_debugfs.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -63,7 +63,7 @@ struct inquiry_entry {
NAME_PENDING,
NAME_KNOWN,
} name_state;
- __u32 timestamp;
+ unsigned long timestamp;
struct inquiry_data data;
};
@@ -79,7 +79,7 @@ struct discovery_state {
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
- __u32 timestamp;
+ unsigned long timestamp;
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
s8 last_adv_rssi;
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -367,7 +367,7 @@ static int inquiry_cache_show(struct seq
list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
- seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
+ seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %lu\n",
&data->bdaddr,
data->pscan_rep_mode, data->pscan_period_mode,
data->pscan_mode, data->dev_class[2],
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0304/1887] Bluetooth: hci_core: Serialize ACL scheduling with channel deletion
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (302 preceding siblings ...)
2026-10-28 16:39 ` [PATCH 6.1 0303/1887] Bluetooth: hci_core: Fix inquiry cache timestamps on 64-bit systems Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0305/1887] Bluetooth: hci_core: Serialize fragmented ISO packet queueing Greg Kroah-Hartman
` (694 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit f4845ab191a4f686a5da481fbba90ed73bb693b0 upstream.
hci_chan_sent() selects a channel under RCU but drops the read lock before
accessing chan->conn and returning the channel. The ACL and LE schedulers
then use its packet queue and update its transmit counters without any
protection against channel deletion.
After TX selects a channel and releases RCU, a disconnect command timeout
on the separate request workqueue can run hci_conn_failed() and
l2cap_conn_del(). hci_chan_del() can then unlink the channel, complete
synchronize_rcu(), purge its queue and free it before TX resumes. This
causes use-after-free both in hci_chan_sent() and in its callers.
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_chan_sent+0x892/0x9b0
Workqueue: hci0 hci_tx_work
Call Trace:
hci_chan_sent+0x892/0x9b0
hci_tx_work+0x5e6/0xb70
Allocated by task 91:
hci_chan_create+0xe3/0x350
l2cap_conn_add.part.0+0x12/0xa30
l2cap_chan_connect+0x110d/0x1b60
l2cap_sock_connect+0x310/0x530
Freed by task 99:
hci_chan_del+0x11f/0x170
l2cap_conn_del+0x4f1/0x800
l2cap_connect_cfm+0x88c/0xd30
hci_conn_failed+0x150/0x250
hci_abort_conn_sync+0x3e3/0x800
hci_cmd_sync_run+0x7e/0xc0
hci_abort_conn+0x105/0x1f0
disconnect_sync+0x157/0x290
hci_cmd_sync_work+0x13c/0x290
Hold the existing device mutex across channel selection and transmission
in both schedulers to serialize them with channel teardown. Keep timeout
handling outside the critical sections because hci_link_tx_to() acquires
the same mutex. This also permits the transmit path to sleep, unlike
extending the RCU read-side critical section across packet submission.
Fixes: 3eff45eaf817 ("Bluetooth: convert tx_task to workqueue")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3604,6 +3604,8 @@ static void hci_sched_acl_pkt(struct hci
__check_timeout(hdev, cnt, ACL_LINK);
+ hci_dev_lock(hdev);
+
while (hdev->acl_cnt &&
(chan = hci_chan_sent(hdev, ACL_LINK, "e))) {
u32 priority = (skb_peek(&chan->data_q))->priority;
@@ -3635,6 +3637,8 @@ static void hci_sched_acl_pkt(struct hci
if (cnt != hdev->acl_cnt)
hci_prio_recalculate(hdev, ACL_LINK);
+
+ hci_dev_unlock(hdev);
}
static void hci_sched_acl(struct hci_dev *hdev)
@@ -3663,6 +3667,8 @@ static void hci_sched_le(struct hci_dev
__check_timeout(hdev, *cnt, LE_LINK);
+ hci_dev_lock(hdev);
+
tmp = *cnt;
while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) {
u32 priority = (skb_peek(&chan->data_q))->priority;
@@ -3691,6 +3697,8 @@ static void hci_sched_le(struct hci_dev
if (*cnt != tmp)
hci_prio_recalculate(hdev, LE_LINK);
+
+ hci_dev_unlock(hdev);
}
/* Schedule CIS */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0305/1887] Bluetooth: hci_core: Serialize fragmented ISO packet queueing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (303 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0304/1887] Bluetooth: hci_core: Serialize ACL scheduling with channel deletion Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0306/1887] Bluetooth: btintel: fix buffer over-read in btintel_hw_error() Greg Kroah-Hartman
` (693 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 1a572db43c057566771b485598ad2e66cb390821 upstream.
The fragmented path in hci_queue_iso() calls __skb_queue_tail() without
holding conn->data_q.lock. The socket lock serializes senders, but the
transmit worker can concurrently remove packets from this queue using
skb_dequeue().
After an insertion saves the old tail pointer, hci_sched_iso() can dequeue
that packet and pass it to the driver. The driver can free the packet
before the insertion resumes and writes to the old tail's next pointer,
causing a use-after-free. Concurrent updates can also corrupt the queue.
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_send_iso+0xc7d/0xe10
Call Trace:
hci_send_iso+0xc7d/0xe10
iso_sock_sendmsg+0x710/0x900
__sys_sendto+0x34a/0x3a0
Allocated by task 86:
__alloc_skb+0xdd/0x820
alloc_skb_with_frags+0x7e/0x770
sock_alloc_send_pskb+0x67a/0x820
bt_skb_sendmsg.constprop.0+0xc0/0x6c0
iso_sock_sendmsg+0x44e/0x900
Freed by task 90:
kmem_cache_free+0xcb/0x3d0
vhci_read+0x33f/0x4d0
vfs_read+0x177/0xa20
Hold the queue lock across the entire fragment batch, as hci_queue_acl()
does, to serialize insertion against dequeue while preserving fragment
ordering.
Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_core.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3291,6 +3291,8 @@ static void hci_queue_iso(struct hci_con
skb_shinfo(skb)->frag_list = NULL;
+ spin_lock_bh(&queue->lock);
+
__skb_queue_tail(queue, skb);
do {
@@ -3305,6 +3307,8 @@ static void hci_queue_iso(struct hci_con
__skb_queue_tail(queue, skb);
} while (list);
+
+ spin_unlock_bh(&queue->lock);
}
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0306/1887] Bluetooth: btintel: fix buffer over-read in btintel_hw_error()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (304 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0305/1887] Bluetooth: hci_core: Serialize fragmented ISO packet queueing Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0307/1887] ipvs: bound LBLCR and LBLC cache growth Greg Kroah-Hartman
` (692 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chandrashekar Devegowda,
Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
commit 40eb4b18ad167b63644c27fa67a7400ba050379a upstream.
The "Exception info %s" print uses skb->data + 1, but the 12-byte
payload is not guaranteed to be NUL-terminated and can be read past
its end.
Bound the print with "%.*s" and skb->len - 1.
Fixes: 973bb97e5aee ("Bluetooth: btintel: Add generic function for handling hardware errors")
Cc: stable@vger.kernel.org
Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/bluetooth/btintel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -248,7 +248,8 @@ static void btintel_hw_error(struct hci_
goto unlock;
}
- bt_dev_err(hdev, "Exception info %s", (char *)(skb->data + 1));
+ bt_dev_err(hdev, "Exception info %.*s", (int)(skb->len - 1),
+ (char *)(skb->data + 1));
kfree_skb(skb);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0307/1887] ipvs: bound LBLCR and LBLC cache growth
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (305 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0306/1887] Bluetooth: btintel: fix buffer over-read in btintel_hw_error() Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0308/1887] nvme-multipath: fix underflow in ANA log bounds checks Greg Kroah-Hartman
` (691 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Julian Anastasov, Zhiling Zou,
Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 2a3c3de660f96865f303fd25f1285f2ffbfd521d ]
ip_vs_lblcr_new() and ip_vs_lblc_new() create cache entries for
every previously unseen destination address. The table max_size only
tells the periodic collector to reclaim entries after the cache has
already exceeded the limit. It does not reclaim entries that the
attacker continues to use.
Reject new cache entries once either table reaches max_size * 3 / 2.
The extra headroom lets the periodic collector catch up while the
existing scheduler fallback continues to use the selected destination
when cache creation fails. New traffic therefore stays serviceable
without growing the tables further.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
[ sashal: Retained kmalloc() instead of kmalloc_obj(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_lblc.c | 3 +++
net/netfilter/ipvs/ip_vs_lblcr.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 9b0832f56f14e..49ff1f9fe1474 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -207,6 +207,9 @@ ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, const union nf_inet_addr *daddr,
ip_vs_lblc_del(en);
atomic_dec(&tbl->entries);
}
+ if (atomic_read(&tbl->entries) >= tbl->max_size * 3 / 2)
+ return NULL;
+
en = kmalloc(sizeof(*en), GFP_ATOMIC);
if (!en)
return NULL;
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 7469547c8a440..6feab18861e16 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -365,6 +365,9 @@ ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, const union nf_inet_addr *daddr,
en = ip_vs_lblcr_get(af, tbl, daddr);
if (!en) {
+ if (atomic_read(&tbl->entries) >= tbl->max_size * 3 / 2)
+ return NULL;
+
en = kmalloc(sizeof(*en), GFP_ATOMIC);
if (!en)
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0308/1887] nvme-multipath: fix underflow in ANA log bounds checks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (306 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0307/1887] ipvs: bound LBLCR and LBLC cache growth Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0309/1887] nvmet-auth: fix out-of-bounds write in nvmet_auth_challenge() Greg Kroah-Hartman
` (690 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Daehyeon Ko,
Keith Busch
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 63fa2d9c9c37020bd2703fe2a6a38027b5abeb15 upstream.
The number of ANA groups advertised through Identify Controller sizes the
ANA log buffer. The ANA log header and group descriptors independently
supply the number of groups and namespace IDs to parse.
Both bounds checks subtract an untrusted object size from ana_log_size
before comparing the current offset. If the object is larger than the
buffer, the size_t subtraction underflows and lets the parser read beyond
ana_log_buf.
Check the current offset before the first subtraction and compare each
object size with the remaining buffer instead. This rejects inconsistent
ANA data before dereferencing a truncated group descriptor or walking an
oversized namespace ID array.
Fixes: 0d0b660f214d ("nvme: add ANA support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvme/host/multipath.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -616,7 +616,8 @@ static int nvme_parse_ana_log(struct nvm
u32 nr_nsids;
size_t nsid_buf_size;
- if (WARN_ON_ONCE(offset > ctrl->ana_log_size - sizeof(*desc)))
+ if (WARN_ON_ONCE(offset > ctrl->ana_log_size ||
+ sizeof(*desc) > ctrl->ana_log_size - offset))
return -EINVAL;
nr_nsids = le32_to_cpu(desc->nnsids);
@@ -632,7 +633,7 @@ static int nvme_parse_ana_log(struct nvm
return -EINVAL;
offset += sizeof(*desc);
- if (WARN_ON_ONCE(offset > ctrl->ana_log_size - nsid_buf_size))
+ if (WARN_ON_ONCE(nsid_buf_size > ctrl->ana_log_size - offset))
return -EINVAL;
error = cb(ctrl, desc, data);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0309/1887] nvmet-auth: fix out-of-bounds write in nvmet_auth_challenge()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (307 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0308/1887] nvme-multipath: fix underflow in ANA log bounds checks Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0310/1887] mtd: rawnand: cadence: Initialize IRQ state before requesting IRQ Greg Kroah-Hartman
` (689 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+77553a7fc66ac133,
Christoph Hellwig, Hannes Reinecke, Weiming Shi, Keith Busch
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit fa6778e030bed9841ddcdf96bc7018da9ac03562 upstream.
nvmet_auth_challenge() receives its output buffer as a void pointer.
sizeof(*d) therefore evaluates to one with GCC and undercounts the fixed
challenge header by 15 bytes. A short AUTH_RECEIVE buffer can pass the
check before the challenge is copied past the end of its allocation.
Use the typed challenge pointer when calculating the response size.
BUG: KASAN: slab-out-of-bounds in nvmet_execute_auth_receive (drivers/nvme/target/fabrics-cmd-auth.c:442 drivers/nvme/target/fabrics-cmd-auth.c:569)
Write of size 32 by task kworker/1:1H/64
Workqueue: nvmet_tcp_wq nvmet_tcp_io_work
Call Trace:
nvmet_execute_auth_receive (drivers/nvme/target/fabrics-cmd-auth.c:442 drivers/nvme/target/fabrics-cmd-auth.c:569)
nvmet_tcp_try_recv_pdu (drivers/nvme/target/tcp.c:1119 drivers/nvme/target/tcp.c:1243)
nvmet_tcp_io_work (drivers/nvme/target/tcp.c:1350 drivers/nvme/target/tcp.c:1382 drivers/nvme/target/tcp.c:1445)
process_one_work (kernel/workqueue.c:3322)
worker_thread (kernel/workqueue.c:3405 kernel/workqueue.c:3486)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:158)
ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
The buggy address is located 16 bytes inside of
allocated 33-byte region [ffff888000554e80, ffff888000554ea1)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Cc: stable@vger.kernel.org
Fixes: db1312dd9548 ("nvmet: implement basic In-Band Authentication")
Reported-by: co+77553a7fc66ac133@bugs.sh
Closes: https://lore.kernel.org/all/Ah6QavQXwvshtqyUcYD1P1R7XE0ND9fB7lbV@bugs.sh/
Assisted-by: Codex:gpt-5.6
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvme/target/fabrics-cmd-auth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/nvme/target/fabrics-cmd-auth.c
+++ b/drivers/nvme/target/fabrics-cmd-auth.c
@@ -359,7 +359,7 @@ static int nvmet_auth_challenge(struct n
struct nvmet_ctrl *ctrl = req->sq->ctrl;
int ret = 0;
int hash_len = nvme_auth_hmac_hash_len(ctrl->shash_id);
- int data_size = sizeof(*d) + hash_len;
+ int data_size = sizeof(*data) + hash_len;
if (ctrl->dh_tfm)
data_size += ctrl->dh_keysize;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0310/1887] mtd: rawnand: cadence: Initialize IRQ state before requesting IRQ
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (308 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0309/1887] nvmet-auth: fix out-of-bounds write in nvmet_auth_challenge() Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0311/1887] mtd: rawnand: vf610_nfc: fix reads on chips with more than 64 bytes of OOB Greg Kroah-Hartman
` (688 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Miquel Raynal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 21f027016b1290d13c30b198ae7a00e6b3d1d5a5 upstream.
The Cadence NAND interrupt handler uses both the IRQ lock and completion
object. Registering the IRQ before initializing them leaves a window in
which a pending interrupt can access uninitialized synchronization state.
Initialize them before registering the handler.
Fixes: ec4ba01e894d ("mtd: rawnand: Add new Cadence NAND driver to MTD subsystem")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/nand/raw/cadence-nand-controller.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/cadence-nand-controller.c
+++ b/drivers/mtd/nand/raw/cadence-nand-controller.c
@@ -2847,6 +2847,9 @@ static int cadence_nand_init(struct cdns
goto free_buf_desc;
}
+ spin_lock_init(&cdns_ctrl->irq_lock);
+ init_completion(&cdns_ctrl->complete);
+
if (devm_request_irq(cdns_ctrl->dev, cdns_ctrl->irq, cadence_nand_isr,
IRQF_SHARED, "cadence-nand-controller",
cdns_ctrl)) {
@@ -2855,9 +2858,6 @@ static int cadence_nand_init(struct cdns
goto free_buf;
}
- spin_lock_init(&cdns_ctrl->irq_lock);
- init_completion(&cdns_ctrl->complete);
-
ret = cadence_nand_hw_init(cdns_ctrl);
if (ret)
goto disable_irq;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0311/1887] mtd: rawnand: vf610_nfc: fix reads on chips with more than 64 bytes of OOB
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (309 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0310/1887] mtd: rawnand: cadence: Initialize IRQ state before requesting IRQ Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0312/1887] mtd: spinand: fix zero oobavail when no ECC engine is used Greg Kroah-Hartman
` (687 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edward Karpicz, Miquel Raynal,
Mehmet Fide
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
commit 37adc9c5789c76db3b1ee7aeec3999b8503020d0 upstream.
The controller transfers 64 spare bytes per page and the driver only
implements the matching 64-byte ECC layout, so attach_chip() shrinks
mtd->oobsize when the chip provides more. That clamp does not survive:
nand_scan_tail() runs nanddev_init() after ->attach_chip(), and it
restores mtd->oobsize from the memory organization, which still holds
the value detected from the chip. The driver then transfers writesize
plus the chip's full OOB size, the hardware ECC parity ends up at a
different offset than the layout the controller was set up for, and
every ECC-protected read fails with -EBADMSG.
Measured on a Colibri VF61 (MX30LF4G28AC, 2048-byte pages, 112 bytes of
OOB): with the clamp lost, UBI cannot read the erase counter headers of
the pages U-Boot has just written, and the on-flash bad block table
written by an older kernel reads back with ECC errors, so the board
does not boot. Kernels before commit a7ab085d7c16 ("mtd: rawnand:
Initialize the nand_device object") are not affected because nothing
overwrote the clamp there, which is why the same chip works with a v4.4
kernel and with U-Boot, whose copy of this driver has no memory
organization to restore the value from. Edward Karpicz reported that
the clamp no longer takes effect on this chip; see the link below.
Instead of modifying the memory organization, keep the detected OOB
size and give the driver its own mtd_ooblayout_ops: the same layout the
NAND core uses for large pages, but computed on the first 64 OOB bytes
instead of the whole OOB, so the ECC bytes stay where U-Boot and the
old kernels put them. The data paths transfer writesize plus those 64
bytes, as the controller always has.
Since mtd->oobsize now reports the chip's real spare size, fill the
tail of oob_poi with 0xff after the 64 transferred bytes on ECC page
reads: the core may copy the full mtd->oobsize from it, which would
otherwise expose whatever the buffer held before. 0xff also matches
what a raw read returns from flash, since the write path only ever
programs the first 64 spare bytes.
Reported-by: Edward Karpicz <webmaster@toradex.com>
Link: https://community.toradex.com/t/colibri-vf50-vf61-on-the-current-bsp-mainline-u-boot-v2026-07-and-linux-6-18-lts/30735
Suggested-by: Miquel Raynal <miquel.raynal@bootlin.com>
Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object")
Cc: stable@vger.kernel.org
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/nand/raw/vf610_nfc.c | 72 ++++++++++++++++++++++++++++++++-------
1 file changed, 60 insertions(+), 12 deletions(-)
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -504,6 +504,11 @@ static int vf610_nfc_exec_op(struct nand
check_only);
}
+static unsigned int vf610_nfc_spare_size(struct mtd_info *mtd)
+{
+ return min_t(unsigned int, mtd->oobsize, 64);
+}
+
static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat,
uint8_t *oob, int page)
{
@@ -521,7 +526,7 @@ static inline int vf610_nfc_correct_data
return ecc_count;
nfc->data_access = true;
- nand_read_oob_op(&nfc->chip, page, 0, oob, mtd->oobsize);
+ nand_read_oob_op(&nfc->chip, page, 0, oob, vf610_nfc_spare_size(mtd));
nfc->data_access = false;
/*
@@ -529,7 +534,7 @@ static inline int vf610_nfc_correct_data
* at least less then half of the ECC strength.
*/
return nand_check_erased_ecc_chunk(dat, nfc->chip.ecc.size, oob,
- mtd->oobsize, NULL, 0,
+ vf610_nfc_spare_size(mtd), NULL, 0,
flips_threshold);
}
@@ -550,7 +555,7 @@ static int vf610_nfc_read_page(struct na
{
struct vf610_nfc *nfc = chip_to_nfc(chip);
struct mtd_info *mtd = nand_to_mtd(chip);
- int trfr_sz = mtd->writesize + mtd->oobsize;
+ int trfr_sz = mtd->writesize + vf610_nfc_spare_size(mtd);
u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0;
int stat;
@@ -576,11 +581,16 @@ static int vf610_nfc_read_page(struct na
*/
vf610_nfc_rd_from_sram(buf, nfc->regs + NFC_MAIN_AREA(0),
mtd->writesize, false);
- if (oob_required)
+ if (oob_required) {
+ unsigned int spare = vf610_nfc_spare_size(mtd);
+
vf610_nfc_rd_from_sram(chip->oob_poi,
nfc->regs + NFC_MAIN_AREA(0) +
mtd->writesize,
- mtd->oobsize, false);
+ spare, false);
+ /* Not transferred, and never written: reads back erased */
+ memset(chip->oob_poi + spare, 0xff, mtd->oobsize - spare);
+ }
stat = vf610_nfc_correct_data(chip, buf, chip->oob_poi, page);
@@ -598,7 +608,7 @@ static int vf610_nfc_write_page(struct n
{
struct vf610_nfc *nfc = chip_to_nfc(chip);
struct mtd_info *mtd = nand_to_mtd(chip);
- int trfr_sz = mtd->writesize + mtd->oobsize;
+ int trfr_sz = mtd->writesize + vf610_nfc_spare_size(mtd);
u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0;
u8 status;
int ret;
@@ -739,6 +749,49 @@ static void vf610_nfc_init_controller(st
}
}
+/*
+ * With 64 byte OOB chips the core's large page layout matches what
+ * U-Boot uses, and on chips with more, U-Boot and older kernels clamped
+ * mtd->oobsize to 64. Modifying the OOB size is no longer possible, the
+ * actual chip geometry must be respected, so to avoid breaking those
+ * existing setups use our own layout: the core's large page one,
+ * computed over the first 64 spare bytes only.
+ */
+static int vf610_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+ struct nand_device *nand = mtd_to_nanddev(mtd);
+ unsigned int total_ecc_bytes = nand->ecc.ctx.total;
+
+ if (section || !total_ecc_bytes)
+ return -ERANGE;
+
+ oobregion->length = total_ecc_bytes;
+ oobregion->offset = vf610_nfc_spare_size(mtd) - oobregion->length;
+
+ return 0;
+}
+
+static int vf610_nfc_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
+{
+ struct nand_device *nand = mtd_to_nanddev(mtd);
+ unsigned int total_ecc_bytes = nand->ecc.ctx.total;
+
+ if (section)
+ return -ERANGE;
+
+ oobregion->length = vf610_nfc_spare_size(mtd) - total_ecc_bytes - 2;
+ oobregion->offset = 2;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops vf610_nfc_ooblayout_ops = {
+ .ecc = vf610_nfc_ooblayout_ecc,
+ .free = vf610_nfc_ooblayout_free,
+};
+
static int vf610_nfc_attach_chip(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
@@ -769,12 +822,7 @@ static int vf610_nfc_attach_chip(struct
return -ENXIO;
}
- /* Only 64 byte ECC layouts known */
- if (mtd->oobsize > 64)
- mtd->oobsize = 64;
-
- /* Use default large page ECC layout defined in NAND core */
- mtd_set_ooblayout(mtd, nand_get_large_page_ooblayout());
+ mtd_set_ooblayout(mtd, &vf610_nfc_ooblayout_ops);
if (chip->ecc.strength == 32) {
nfc->ecc_mode = ECC_60_BYTE;
chip->ecc.bytes = 60;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0312/1887] mtd: spinand: fix zero oobavail when no ECC engine is used
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (310 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0311/1887] mtd: rawnand: vf610_nfc: fix reads on chips with more than 64 bytes of OOB Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0313/1887] wifi: cw1200: fix TX padding OOB read leaking heap data to device Greg Kroah-Hartman
` (686 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nuno Sá, Miquel Raynal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sá <nuno.sa@analog.com>
commit 636fe10d8f3559210ff63108a208d39ea2e9c3bd upstream.
Commit 00c15b78b4b4 ("mtd: spinand: Allow the case where there is no
ECC engine") made the OOB free bytes count conditional on having an
ECC engine so that probing would not fail when none is requested.
However mtd->oobavail is still assigned from ret just after that
block, and ret is 0 there, so the device ends up advertising no
available OOB bytes at all.
mtd_oobavail() returns mtd->oobavail for MTD_OPS_AUTO_OOB, so a zero
value makes every automatic OOB access fail with -EINVAL. JFFS2 fares
worse: it keeps its cleanmarker in the OOB area on NAND and refuses to
mount outright, reporting "inconsistent device description".
No ECC engine also means no ooblayout was ever installed, which would
make the count return -ENOTSUPP, so install the same fallback layout
the on-die path already uses before counting unconditionally.
Fixes: 00c15b78b4b4 ("mtd: spinand: Allow the case where there is no ECC engine")
Cc: stable@vger.kernel.org
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/nand/spi/core.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1276,12 +1276,17 @@ static int spinand_init(struct spinand_d
mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
mtd->_resume = spinand_mtd_resume;
- if (nand->ecc.engine) {
- ret = mtd_ooblayout_count_freebytes(mtd);
- if (ret < 0)
- goto err_cleanup_ecc_engine;
+ if (!nand->ecc.engine) {
+ if (spinand->eccinfo.ooblayout)
+ mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout);
+ else
+ mtd_set_ooblayout(mtd, &spinand_noecc_ooblayout);
}
+ ret = mtd_ooblayout_count_freebytes(mtd);
+ if (ret < 0)
+ goto err_cleanup_ecc_engine;
+
mtd->oobavail = ret;
/* Propagate ECC information to mtd_info */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0313/1887] wifi: cw1200: fix TX padding OOB read leaking heap data to device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (311 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0312/1887] mtd: spinand: fix zero oobavail when no ECC engine is used Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0314/1887] wifi: iwlegacy: 3945: free EEPROM data on remove Greg Kroah-Hartman
` (685 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <flynnnchen@tencent.com>
commit 7c1611780823b76219cb1478db53dfd890c4a9a2 upstream.
The TX path rounds the transfer size up to the bus alignment
(align_size(), up to 511 bytes for SDIO, 1 byte for SPI) but sends
the padded length straight from the frame buffer, which has no room
reserved for the padding. cw1200_data_write() therefore reads past
the end of the frame and the bus transfer carries those bytes to the
device. A bogus device can collect up to 511 bytes of kernel heap
data per TX frame.
The RX path does not have this problem: it allocates the skb with
the aligned length (alloc_len) before reading.
Compute the exact padding with the bus align_size() callback, make
sure queued TX frames have tailroom for it, and zero the padding
bytes before the transfer so nothing past the frame is exposed.
This is not expected to change driver behavior on most cases: frame
contents and transfer sizes are unchanged, only the content of the
padding bytes (previously undefined stale memory, now zero), which
the device never reads since the WSM header carries the real frame
length. The skb expansion can only fail under memory exhaustion,
in which case the frame is dropped like on the existing error paths
of cw1200_tx().
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/7982b4a7e64f74e2068790ec389ca680a081f730@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/st/cw1200/bh.c | 8 +++++++-
drivers/net/wireless/st/cw1200/txrx.c | 14 ++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/st/cw1200/bh.c
+++ b/drivers/net/wireless/st/cw1200/bh.c
@@ -343,6 +343,7 @@ static int cw1200_bh_tx_helper(struct cw
int *tx_burst)
{
size_t tx_len;
+ size_t aligned_len;
u8 *data;
int ret;
struct wsm_hdr *wsm;
@@ -375,9 +376,14 @@ static int cw1200_bh_tx_helper(struct cw
atomic_inc(&priv->bh_tx);
- tx_len = priv->hwbus_ops->align_size(
+ aligned_len = priv->hwbus_ops->align_size(
priv->hwbus_priv, tx_len);
+ /* Zero the bus alignment padding so no stale data is sent. */
+ if (aligned_len > tx_len)
+ memset(data + tx_len, 0, aligned_len - tx_len);
+ tx_len = aligned_len;
+
/* Check if not exceeding CW1200 capabilities */
if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
pr_debug("Write aligned len: %zu\n", tx_len);
--- a/drivers/net/wireless/st/cw1200/txrx.c
+++ b/drivers/net/wireless/st/cw1200/txrx.c
@@ -14,6 +14,7 @@
#include "wsm.h"
#include "bh.h"
#include "sta.h"
+#include "hwbus.h"
#include "debug.h"
#define CW1200_INVALID_RATE_ID (0xFF)
@@ -716,6 +717,7 @@ void cw1200_tx(struct ieee80211_hw *dev,
struct ieee80211_sta *sta;
struct wsm_tx *wsm;
bool tid_update = false;
+ size_t pad_len;
u8 flags = 0;
int ret;
@@ -764,6 +766,18 @@ void cw1200_tx(struct ieee80211_hw *dev,
sta = t.sta;
+ /*
+ * The bus transfer is padded up to the bus alignment and the
+ * padding is transferred from the frame buffer. Make sure the
+ * buffer has room for the padding so the device never receives
+ * data past the end of the frame.
+ */
+ pad_len = priv->hwbus_ops->align_size(priv->hwbus_priv, skb->len) -
+ skb->len;
+ if (skb_tailroom(skb) < pad_len &&
+ pskb_expand_head(skb, 0, pad_len, GFP_ATOMIC))
+ goto drop;
+
spin_lock_bh(&priv->ps_state_lock);
{
tid_update = cw1200_tx_h_pm_state(priv, &t);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0314/1887] wifi: iwlegacy: 3945: free EEPROM data on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (312 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0313/1887] wifi: cw1200: fix TX padding OOB read leaking heap data to device Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0315/1887] wifi: mac80211: drain PS delivery work during station teardown Greg Kroah-Hartman
` (684 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Stanislaw Gruszka,
Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit f8ebe286394c0bbb4a6dbacb182a34ab6376922d upstream.
il3945_pci_probe() calls il_eeprom_init(), which allocates memory for
the EEPROM data. The probe failure paths release this allocation with
il_eeprom_free(), but the remove path does not free it after a
successful probe.
As a result, the EEPROM data is leaked when the PCI device is removed.
Free the EEPROM data in il3945_pci_remove() before releasing the
mac80211 hardware structure.
This issue was found by manual code inspection.
Fixes: 073d3f5f1b3b ("iwlwifi: changing EEPROM layout handling")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Link: https://patch.msgid.link/20260916073736.2952028-1-lgs201920130244@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/intel/iwlegacy/3945-mac.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -3845,6 +3845,7 @@ il3945_pci_remove(struct pci_dev *pdev)
il_free_channel_map(il);
il_free_geos(il);
+ il_eeprom_free(il);
kfree(il->scan_cmd);
dev_kfree_skb(il->beacon_skb);
ieee80211_free_hw(il->hw);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0315/1887] wifi: mac80211: drain PS delivery work during station teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (313 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0314/1887] wifi: iwlegacy: 3945: free EEPROM data on remove Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0316/1887] wifi: mac80211: minstrel_ht: validate fixed rate index Greg Kroah-Hartman
` (683 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zhao Li, Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
commit 67a9e80c3ca20c9044cd6ee72cd6278dd19b5023 upstream.
Removing an AP or mesh station can notify the driver and wake TXQs after
the station has already been removed from the driver, and can update
num_sta_ps and the power-save queues after station cleanup has purged
them.
sta_deliver_ps_frames() tests sta->dead only before it starts delivery. A
worker that passes that test can be delayed while teardown sets sta->dead
and removes the station from the driver; when it resumes it still runs the
full delivery.
The existing cancel_work_sync() sits near the end of
__cleanup_single_sta(), after the final driver state transition and after
PS accounting and queue purging, so it drains the worker only once the
state it has to protect has already changed. Before commit d34ba2168a3c
("mac80211: don't delay station destruction") cleanup was deferred
through the same ordered workqueue as the delivery work, which kept the
two ordered.
Cancel the work after setting sta->dead and before moving the driver
state, and move the existing cancellation to the start of
__cleanup_single_sta(). The first drain closes the driver-lifetime window;
driver callbacks during the remaining state transitions can still queue
drv_deliver_wk through ieee80211_sta_block_awake(), so retain the second
drain at the start of __cleanup_single_sta(). That drain also covers
insertion failures, which reach cleanup without setting sta->dead.
Fixes: d34ba2168a3c ("mac80211: don't delay station destruction")
Cc: stable@vger.kernel.org
Assisted-by: LLM sparse smatch coccinelle kasan
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260916113735.31029-1-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/sta_info.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -122,6 +122,8 @@ static void __cleanup_single_sta(struct
struct ieee80211_local *local = sdata->local;
struct ps_data *ps;
+ cancel_work_sync(&sta->drv_deliver_wk);
+
if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
@@ -162,8 +164,6 @@ static void __cleanup_single_sta(struct
if (ieee80211_vif_is_mesh(&sdata->vif))
mesh_sta_cleanup(sta);
- cancel_work_sync(&sta->drv_deliver_wk);
-
/*
* Destroy aggregation state here. It would be nice to wait for the
* driver to finish aggregation stop and then clean up, but for now
@@ -1303,6 +1303,8 @@ static void __sta_info_destroy_part2(str
sta->dead = true;
+ cancel_work_sync(&sta->drv_deliver_wk);
+
local->num_sta--;
local->sta_generation++;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0316/1887] wifi: mac80211: minstrel_ht: validate fixed rate index
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (314 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0315/1887] wifi: mac80211: drain PS delivery work during station teardown Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0317/1887] wifi: mac80211: release mesh path quota on failed additions Greg Kroah-Hartman
` (682 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei,
Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
commit 15fb9e3cea55fbc378261ce35a32b0f8828f0000 upstream.
The fixed_rate_idx debugfs file is a plain u32 attribute, so any value
can be written to it. minstrel_ht_update_stats() then copies the value
into mi->max_tp_rate[] and mi->max_prob_rate, and
minstrel_ht_set_rate() uses MI_RATE_GROUP()/MI_RATE_IDX() to index
minstrel_mcs_groups[] (42 entries) and mi->groups[].rates[] (10 entries)
with it.
Writing e.g. 65535 selects group 4095 and rate index 15, far outside
both arrays. The out-of-bounds entries are dereferenced and updated as
struct minstrel_rate_stats (retry counts, etc.), so the invalid index
corrupts adjacent kernel memory. With CONFIG_UBSAN_BOUNDS the access is
reported as an array-index-out-of-bounds in minstrel_ht_set_rate().
Only a valid group/rate pair, or U32_MAX to disable fixed rate
processing, can be used safely, so reject any other value when the
debugfs file is written.
The file is only reachable through a root-only debugfs mount, so this is
not a privilege boundary. The out-of-bounds access is still a bug that
must not be reachable through a writable debugfs attribute.
Fixes: 24f7580e852b ("minstrel_ht: fixed rate mode through debugfs")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/288e6f6d30dc82ff40da502755e6666982f6b735.1789798000.git.xuyuqiabc@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/rc80211_minstrel_ht.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -7,6 +7,7 @@
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/debugfs.h>
+#include <linux/limits.h>
#include <linux/random.h>
#include <linux/moduleparam.h>
#include <linux/ieee80211.h>
@@ -1977,14 +1978,39 @@ minstrel_ht_alloc(struct ieee80211_hw *h
}
#ifdef CONFIG_MAC80211_DEBUGFS
+static int minstrel_ht_fixed_rate_idx_get(void *data, u64 *val)
+{
+ *val = *(u32 *)data;
+ return 0;
+}
+
+static int minstrel_ht_fixed_rate_idx_set(void *data, u64 val)
+{
+ u32 idx = val;
+
+ /* U32_MAX is the default and keeps fixed rate processing disabled */
+ if (val != U32_MAX &&
+ (val > U16_MAX ||
+ MI_RATE_GROUP(idx) >= ARRAY_SIZE(minstrel_mcs_groups) ||
+ MI_RATE_IDX(idx) >= MCS_GROUP_RATES))
+ return -EINVAL;
+
+ *(u32 *)data = idx;
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(minstrel_ht_fixed_rate_idx_fops,
+ minstrel_ht_fixed_rate_idx_get,
+ minstrel_ht_fixed_rate_idx_set, "%llu\n");
+
static void minstrel_ht_add_debugfs(struct ieee80211_hw *hw, void *priv,
struct dentry *debugfsdir)
{
struct minstrel_priv *mp = priv;
mp->fixed_rate_idx = (u32) -1;
- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
- &mp->fixed_rate_idx);
+ debugfs_create_file("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
+ &mp->fixed_rate_idx, &minstrel_ht_fixed_rate_idx_fops);
}
#endif
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0317/1887] wifi: mac80211: release mesh path quota on failed additions
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (315 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0316/1887] wifi: mac80211: minstrel_ht: validate fixed rate index Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0318/1887] wifi: mac80211: handle empty FILS association request payload Greg Kroah-Hartman
` (681 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zhao Li, Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
commit 7325a44474f20c1393a1c114c6811abce6ddfaf4 upstream.
Repeated failed or duplicate mesh path additions can exhaust
MESH_MAX_MPATHS while the path table holds fewer paths, which stops new
paths to reachable destinations from being created.
mesh_path_add() reserves a slot before allocating and inserting a path.
If allocation fails, the function returns without releasing the slot. If
the rhashtable insertion reports an error or an existing destination, the
function discards its candidate but retains the reservation. No new path
is installed in any of these cases.
Release the reservation whenever the candidate is not installed.
Fixes: ae76eef027f7 ("mac80211: return new mpath from mesh_path_add()")
Fixes: 60854fd94573 ("mac80211: mesh: convert path table to rhashtable")
Cc: stable@vger.kernel.org
Assisted-by: LLM sparse kasan
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260916113649.28315-2-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/mesh_pathtbl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -407,8 +407,10 @@ struct mesh_path *mesh_path_add(struct i
return ERR_PTR(-ENOSPC);
new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
- if (!new_mpath)
+ if (!new_mpath) {
+ atomic_dec(&sdata->u.mesh.mpaths);
return ERR_PTR(-ENOMEM);
+ }
tbl = &sdata->u.mesh.mesh_paths;
spin_lock_bh(&tbl->walk_lock);
@@ -421,6 +423,7 @@ struct mesh_path *mesh_path_add(struct i
if (mpath) {
kfree(new_mpath);
+ atomic_dec(&sdata->u.mesh.mpaths);
if (IS_ERR(mpath))
return mpath;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0318/1887] wifi: mac80211: handle empty FILS association request payload
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (316 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0317/1887] wifi: mac80211: release mesh path quota on failed additions Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0319/1887] USB: serial: cp210x: add Corsair AX1500i Power Supply Greg Kroah-Hartman
` (680 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei,
Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
commit 5bfd4b0b40b79781d900cb2f7da0685070f53c67 upstream.
fils_encrypt_assoc_req() accepts a (Re)Association Request frame whose
last element is the FILS Session element. crypt_len is then zero and
aes_siv_encrypt() is called with an empty plaintext.
kmemdup() returns ZERO_SIZE_PTR for a zero-length allocation, so the
unconditional sg_init_one() puts an invalid page into the scatterlist.
With CONFIG_DEBUG_SG this triggers a kernel BUG in sg_set_buf();
without the debug check the bogus page is handed to the crypto backend.
AES-SIV is defined for empty plaintext and the S2V result is then the
complete output, so handle this case before the CTR step, which has
nothing to encrypt.
Fixes: 39404feee691 ("mac80211: FILS AEAD protection for station mode association frames")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/325c048982d637a3af80d74ac5b36e9369b93f1e.1789751126.git.xuyuqiabc@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/fils_aead.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/mac80211/fils_aead.c
+++ b/net/mac80211/fils_aead.c
@@ -95,6 +95,14 @@ static int aes_siv_encrypt(const u8 *key
if (res)
return res;
+ /* With an empty plaintext there is no ciphertext to produce and
+ * the S2V result is the complete output.
+ */
+ if (!plain_len) {
+ memcpy(out, v, AES_BLOCK_SIZE);
+ return 0;
+ }
+
/* Use a temporary buffer of the plaintext to handle need for
* overwriting this during AES-CTR.
*/
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0319/1887] USB: serial: cp210x: add Corsair AX1500i Power Supply
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (317 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0318/1887] wifi: mac80211: handle empty FILS association request payload Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0320/1887] USB: serial: quatech2: fix baud rate overflow Greg Kroah-Hartman
` (679 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jérémy Carrat,
Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Carrat <jeremy.carrat@icloud.com>
commit d84e27d87738634b92001500435ae4dadba10a13 upstream.
The Corsair AX1500i power supply exposes its Corsair Link monitoring
interface on a mini-USB port through an on-board CP2103, using a
Corsair-specific product ID. Without the ID in the table no driver binds
and no tty is created.
Tested by forcing the driver association with
echo 1b1c 1c02 > /sys/bus/usb-serial/drivers/cp210x/new_id
and then setting the serial port to 115200 8N1. Adding the ID is sufficient
to talk to the device: the tty reaches a USB-to-SMBus bridge sitting behind
the UART, which identifies itself as "USB to SMB Bridge (Firmware by Ross
Fosler)" version 0.9 and relays PMBus reads to the power supply controller.
Input voltage and current, input and output power, internal temperature and
fan speed were all read back on an AX1500i.
[ 7.806181] usb 3-14: New USB device found, idVendor=1b1c, idProduct=1c02, bcdDevice= 1.00
[ 698.526754] usbcore: registered new interface driver cp210x
[ 698.526767] usbserial: USB Serial support registered for cp210x
[ 698.527863] cp210x 3-14:1.0: cp210x converter detected
[ 698.529263] usb 3-14: cp210x converter now attached to ttyUSB0
The related AX1600i (1b1c:1c11, iProduct "USB API") is expected to be the
same kind of device but has not been tested here, so it is not added.
Cc: stable@vger.kernel.org
Signed-off-by: Jérémy Carrat <jeremy.carrat@icloud.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/cp210x.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -223,6 +223,7 @@ static const struct usb_device_id id_tab
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
+ { USB_DEVICE(0x1B1C, 0x1C02) }, /* Corsair AX1500i Power Supply */
{ USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0320/1887] USB: serial: quatech2: fix baud rate overflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (318 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0319/1887] USB: serial: cp210x: add Corsair AX1500i Power Supply Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0321/1887] USB: serial: ssu100: " Greg Kroah-Hartman
` (678 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bill Pemberton, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit ec06546b43b612cefc851558981b4955c0ef9e46 upstream.
The requested baud rate is incorrectly truncated to 16 bits so that
line speeds above 65535 bps cannot be set.
Use 32 bits for the rate while rejecting rates outside of
[50,921600] to avoid having the 16-bit divisor overflow.
Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver")
Cc: stable@vger.kernel.org # 3.5
Cc: Bill Pemberton <wfp5p@virginia.edu>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/quatech2.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -54,6 +54,7 @@
#define QT2_XMIT_FLUSH 0x05 /* no following info */
#define QT2_CONTROL_ESCAPE 0xff /* pass through previous 2 control bytes */
+#define MIN_BAUD_RATE 50
#define MAX_BAUD_RATE 921600
#define DEFAULT_BAUD_RATE 9600
@@ -158,7 +159,7 @@ static inline int calc_baud_divisor(int
static inline int qt2_set_port_config(struct usb_device *dev,
unsigned char port_number,
- u16 baudrate, u16 lcr)
+ speed_t baudrate, u16 lcr)
{
int divisor = calc_baud_divisor(baudrate);
u16 index = ((u16) (lcr << 8) | (u16) (port_number));
@@ -267,9 +268,9 @@ static void qt2_set_termios(struct tty_s
struct usb_device *dev = port->serial->dev;
struct qt2_port_private *port_priv;
struct ktermios *termios = &tty->termios;
- u16 baud;
unsigned int cflag = termios->c_cflag;
u16 new_lcr = 0;
+ speed_t baud;
int status;
port_priv = usb_get_serial_port_data(port);
@@ -287,6 +288,18 @@ static void qt2_set_termios(struct tty_s
if (!baud)
baud = 9600;
+ if (baud < MIN_BAUD_RATE || baud > MAX_BAUD_RATE) {
+ if (old_termios)
+ baud = tty_termios_baud_rate(old_termios);
+ else
+ baud = clamp(baud, MIN_BAUD_RATE, MAX_BAUD_RATE);
+
+ tty_encode_baud_rate(tty, baud, baud);
+
+ if (!baud)
+ baud = 9600;
+ }
+
status = qt2_set_port_config(dev, port_priv->device_port, baud,
new_lcr);
if (status < 0)
@@ -383,7 +396,7 @@ static int qt2_open(struct tty_struct *t
port_priv->device_port = (u8) device_port;
if (tty)
- qt2_set_termios(tty, port, &tty->termios);
+ qt2_set_termios(tty, port, NULL);
return 0;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0321/1887] USB: serial: ssu100: fix baud rate overflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (319 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0320/1887] USB: serial: quatech2: fix baud rate overflow Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0322/1887] USB: serial: fix dynamic id driver deregistration race Greg Kroah-Hartman
` (677 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bill Pemberton, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit afc235a217360c6859068d2e37a4df305c4d1be2 upstream.
The requested baud rate is incorrectly truncated to 16 bits so that
line speeds above 65535 bps cannot be set.
Use 32 bits for the rate and remainder while rejecting rates outside of
[50,460800] to avoid having the divisor or remainder overflow.
This issue was flagged by an LLM.
Fixes: 52af95459939 ("USB: add USB serial ssu100 driver")
Cc: stable@vger.kernel.org # 2.6.36
Cc: Bill Pemberton <wfp5p@virginia.edu>
Assisted-by: LLM
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/ssu100.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -34,6 +34,7 @@
#define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR)
+#define MIN_BAUD_RATE 50
#define MAX_BAUD_RATE 460800
#define ATC_DISABLED 0x00
@@ -219,9 +220,10 @@ static void ssu100_set_termios(struct tt
{
struct usb_device *dev = port->serial->dev;
struct ktermios *termios = &tty->termios;
- u16 baud, divisor, remainder;
+ speed_t baud, remainder;
unsigned int cflag = termios->c_cflag;
u16 urb_value = 0; /* will hold the new flags */
+ u16 divisor;
int result;
if (cflag & PARENB) {
@@ -237,6 +239,18 @@ static void ssu100_set_termios(struct tt
if (!baud)
baud = 9600;
+ if (baud < MIN_BAUD_RATE || baud > MAX_BAUD_RATE) {
+ if (old_termios)
+ baud = tty_termios_baud_rate(old_termios);
+ else
+ baud = clamp(baud, MIN_BAUD_RATE, MAX_BAUD_RATE);
+
+ tty_encode_baud_rate(tty, baud, baud);
+
+ if (!baud)
+ baud = 9600;
+ }
+
dev_dbg(&port->dev, "%s - got baud = %d\n", __func__, baud);
@@ -312,7 +326,7 @@ static int ssu100_open(struct tty_struct
dev_dbg(&port->dev, "%s - set uart failed\n", __func__);
if (tty)
- ssu100_set_termios(tty, port, &tty->termios);
+ ssu100_set_termios(tty, port, NULL);
return usb_serial_generic_open(tty, port);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0322/1887] USB: serial: fix dynamic id driver deregistration race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (320 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0321/1887] USB: serial: ssu100: " Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0323/1887] USB: serial: fix driver deregistration order Greg Kroah-Hartman
` (676 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 63594e8ffe097bc0b7639936f33799a7653dded2 upstream.
Only free the dynamic ids after having deregistered the driver and
removed the "new_id" attribute to avoid leaking any id added by a racing
write to the attribute.
Fixes: 93bacefc4cc0 ("USB serial: add dynamic id support to usb-serial core")
Cc: stable@vger.kernel.org # 2.6.21
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/bus.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -165,7 +165,7 @@ int usb_serial_bus_register(struct usb_s
void usb_serial_bus_deregister(struct usb_serial_driver *driver)
{
- free_dynids(driver);
driver_unregister(&driver->driver);
+ free_dynids(driver);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0323/1887] USB: serial: fix driver deregistration order
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (321 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0322/1887] USB: serial: fix dynamic id driver deregistration race Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0324/1887] USB: serial: option: add support for SIMCom SIM8260C Greg Kroah-Hartman
` (675 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alan Stern, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 646e5b28b4fdbc1b828a2398d6ced2c1dd308a46 upstream.
USB serial driver modules register one driver for the USB bus and one or
more drivers for the ports on the USB serial bus.
When unloading a driver module, the USB driver must be deregistered
before the USB serial bus drivers so that I/O is stopped before
unbinding the ports to avoid use-after-free in completion handlers
accessing port data.
Note that the "new_id" attributes must first be removed to prevent new
ids from being added and triggering a probe of the USB driver after it
has been deregistered.
Fixes: 765e0ba62613 ("usb-serial: new API for driver registration")
Cc: stable@vger.kernel.org # 3.4
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/bus.c | 4 ++++
drivers/usb/serial/usb-serial.c | 21 ++++++++++++++++++---
include/linux/usb/serial.h | 1 +
3 files changed, 23 insertions(+), 3 deletions(-)
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -169,3 +169,7 @@ void usb_serial_bus_deregister(struct us
free_dynids(driver);
}
+void usb_serial_bus_remove_new_id(struct usb_serial_driver *driver)
+{
+ driver_remove_file(&driver->driver, &driver_attr_new_id);
+}
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1471,7 +1471,7 @@ int usb_serial_register_drivers(struct u
{
int rc;
struct usb_driver *udriver;
- struct usb_serial_driver * const *sd;
+ struct usb_serial_driver * const *sd, * const *s;
/*
* udriver must be registered before any of the serial drivers,
@@ -1523,9 +1523,11 @@ int usb_serial_register_drivers(struct u
return 0;
err_deregister_drivers:
+ for (s = serial_drivers; s < sd; ++s)
+ usb_serial_bus_remove_new_id(*s);
+ usb_deregister(udriver);
while (sd-- > serial_drivers)
usb_serial_deregister(*sd);
- usb_deregister(udriver);
err_free_driver:
kfree(udriver);
return rc;
@@ -1543,10 +1545,23 @@ EXPORT_SYMBOL_GPL(usb_serial_register_dr
void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
{
struct usb_driver *udriver = (*serial_drivers)->usb_driver;
+ struct usb_serial_driver * const *sd;
+
+ /*
+ * udriver must be deregistered before the serial drivers so that
+ * I/O is stopped before unbinding the ports.
+ *
+ * Remove the new_id attributes to prevent ids from being added and
+ * triggering a probe of udriver after it has been deregistered.
+ */
+ for (sd = serial_drivers; *sd; ++sd)
+ usb_serial_bus_remove_new_id(*sd);
+
+ usb_deregister(udriver);
for (; *serial_drivers; ++serial_drivers)
usb_serial_deregister(*serial_drivers);
- usb_deregister(udriver);
+
kfree(udriver);
}
EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -377,6 +377,7 @@ void usb_serial_handle_dcd_change(struct
int usb_serial_bus_register(struct usb_serial_driver *device);
void usb_serial_bus_deregister(struct usb_serial_driver *device);
+void usb_serial_bus_remove_new_id(struct usb_serial_driver *driver);
extern struct bus_type usb_serial_bus_type;
extern struct tty_driver *usb_serial_tty_driver;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0324/1887] USB: serial: option: add support for SIMCom SIM8260C
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (322 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0323/1887] USB: serial: fix driver deregistration order Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0325/1887] USB: serial: option: add Quectel EG060W Greg Kroah-Hartman
` (674 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zhao Dongdong, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Dongdong <zhaodongdong@kylinos.cn>
commit 35c950c9ec2c4c4d45dc9b63cfe8fca774ce33a0 upstream.
Add support for SIMCom SIM8260C (1e0e:902b).
T: Bus=08 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0
D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1
P: Vendor=1e0e ProdID=902b Rev= 5.04
S: Manufacturer=SIMCOM
S: Product=SDXLEMUR-LITE-MTP _SN:120696AB
S: SerialNumber=0123456789ABCDEF
C:* #Ifs= 8 Cfg#= 1 Atr=a0 MxPwr=896mA
A: FirstIf#= 5 IfCount= 3 Cls=01(audio) Sub=00 Prot=20
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan_simcom
E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 5 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=20 Driver=snd-usb-audio
I:* If#= 6 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio
I: If#= 6 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio
E: Ad=05(O) Atr=0d(Isoc) MxPS= 34 Ivl=1ms
I:* If#= 7 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=20 Driver=(none)
I: If#= 7 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=(none)
E: Ad=89(I) Atr=0d(Isoc) MxPS= 34 Ivl=1ms
Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/option.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2169,6 +2169,8 @@ static const struct usb_device_id option
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */
.driver_info = RSVD(7) },
+ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x902b, 0xff),
+ .driver_info = RSVD(4) },
{ USB_DEVICE(0x1e0e, 0x9071), /* Simcom SIM8230 RMNET mode */
.driver_info = RSVD(3) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9078, 0xff), /* Simcom SIM8230 ECM mode */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0325/1887] USB: serial: option: add Quectel EG060W
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (323 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0324/1887] USB: serial: option: add support for SIMCom SIM8260C Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0326/1887] USB: serial: option: add Compal EXM-G1x support Greg Kroah-Hartman
` (673 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Carlo Szelinsky, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlo Szelinsky <github@szelinsky.de>
commit cd243401994880b8b6810c53177bce56eebaece5 upstream.
Add Quectel EG060W with product ID 0x6004.
The three vendor-specific interfaces are DIAG, NMEA and AT; the CDC-NCM
data interfaces are handled by the cdc_ncm driver.
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=2c7c ProdID=6004 Rev= 3.18
S: Manufacturer=Quectel
S: Product=EG060W-EAAA
S: SerialNumber=123456789ABCD
C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr= 2mA
A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0d Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0d Prot=00 Driver=cdc_ncm
E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm
I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Cc: stable@vger.kernel.org
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/option.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -281,6 +281,7 @@ static void option_instat_callback(struc
#define QUECTEL_PRODUCT_EC200U 0x0901
#define QUECTEL_PRODUCT_EG912Y 0x6001
#define QUECTEL_PRODUCT_EC200S_CN 0x6002
+#define QUECTEL_PRODUCT_EG060W 0x6004
#define QUECTEL_PRODUCT_EC200A 0x6005
#define QUECTEL_PRODUCT_EG916Q 0x6007
#define QUECTEL_PRODUCT_EM061K_LWW 0x6008
@@ -1269,6 +1270,7 @@ static const struct usb_device_id option
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG060W, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG916Q, 0xff, 0x00, 0x00) },
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0326/1887] USB: serial: option: add Compal EXM-G1x support
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (324 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0325/1887] USB: serial: option: add Quectel EG060W Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0327/1887] USB: serial: option: add Quectel RG660QB Greg Kroah-Hartman
` (672 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Lin, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Lin <jisayme@gmail.com>
commit 7f11480cda081de78a05d8c97073df66326b50b3 upstream.
The Compal EXM-G1x is a Qualcomm SDX12-based LTE modem. Add support for
its vendor-specific serial interfaces with protocols 0x30, 0x40, and
0x60.
Relevant output from usb-devices:
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=5000 MxCh= 0
D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1
P: Vendor=04b7 ProdID=8217 Rev=05.04
S: Manufacturer=COMPAL
S: Product=EXM-G1x
C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#= 8 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
Tested on a Compal EXM-G1x modem.
Assisted-by: Codex:GPT-5
Signed-off-by: Ian Lin <jisayme@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/option.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2434,6 +2434,9 @@ static const struct usb_device_id option
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe167, 0xff), /* Foxconn T99W640 MBIM */
.driver_info = RSVD(3) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x30) }, /* Compal EXM-G1x */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x40) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x60) },
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
{ USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0327/1887] USB: serial: option: add Quectel RG660QB
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (325 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0326/1887] USB: serial: option: add Compal EXM-G1x support Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0328/1887] USB: serial: option: add Compal EXC-T1 support Greg Kroah-Hartman
` (671 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sebastian Sjoholm, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Sjoholm <sebastian.sjoholm@gmail.com>
commit 6177bcd94be83f80a032c2e69a06606d325335b9 upstream.
Add support for the Quectel RG660QB 5G module (USB ID 2c7c:013d).
The interface layout is the same as the RG650V:
If 0: DIAG ff/ff/30, 2 endpoints
If 1: NMEA ff/00/00, 2 endpoints
If 2: AT ff/00/00, 3 endpoints
If 3: Modem ff/00/00, 3 endpoints
If 4: QMI ff/ff/ff, 3 endpoints
Match the serial interfaces on class/subclass/protocol so that the QMI
interface is left to qmi_wwan.
# lsusb -v -d 2c7c:013d
Bus 004 Device 002: ID 2c7c:013d Quectel Wireless Solutions Co., Ltd. RG660QB-EU
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 3.20
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 9
idVendor 0x2c7c Quectel Wireless Solutions Co., Ltd.
idProduct 0x013d
bcdDevice 6.06
iManufacturer 1 Quectel
iProduct 2 RG660QB-EU
iSerial 3 f50119d0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0105
bNumInterfaces 5
bConfigurationValue 1
iConfiguration 4 DIAG_SER_RMNET
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 896mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 48
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 6 CDEV Serial
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 6 CDEV Serial
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 7 RmNet
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 6
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 2
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 0x0023
bNumDeviceCaps 2
SuperSpeed USB Device Capability:
bLength 10
bDescriptorType 16
bDevCapabilityType 3
bmAttributes 0x00
wSpeedsSupported 0x000f
Device can operate at Low Speed (1Mbps)
Device can operate at Full Speed (12Mbps)
Device can operate at High Speed (480Mbps)
Device can operate at SuperSpeed (5Gbps)
bFunctionalitySupport 1
Lowest fully-functional device speed is Full Speed (12Mbps)
bU1DevExitLat 0 micro seconds
bU2DevExitLat 0 micro seconds
SuperSpeedPlus USB Device Capability:
bLength 20
bDescriptorType 16
bDevCapabilityType 10
bmAttributes 0x00000001
Sublink Speed Attribute count 1
Sublink Speed ID count 0
wFunctionalitySupport 0x1100
bmSublinkSpeedAttr[0] 0x000a4030
Speed Attribute ID: 0 10Gb/s Symmetric RX SuperSpeedPlus
bmSublinkSpeedAttr[1] 0x000a40b0
Speed Attribute ID: 0 10Gb/s Symmetric TX SuperSpeedPlus
Device Status: 0x0000
(Bus Powered)
Tested with an early sample of the module on a Quectel 5G EVB connected
over USB 3 to a Raspberry Pi 5.
Assisted-by: LLM
Signed-off-by: Sebastian Sjoholm <sebastian.sjoholm@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/option.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -261,6 +261,7 @@ static void option_instat_callback(struc
#define QUECTEL_PRODUCT_EM060K_12a 0x012a
#define QUECTEL_PRODUCT_EM060K_12b 0x012b
#define QUECTEL_PRODUCT_EM060K_12c 0x012c
+#define QUECTEL_PRODUCT_RG660QB 0x013d
#define QUECTEL_PRODUCT_EG91 0x0191
#define QUECTEL_PRODUCT_EG95 0x0195
#define QUECTEL_PRODUCT_BG96 0x0296
@@ -1277,6 +1278,8 @@ static const struct usb_device_id option
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG660QB, 0xff, 0xff, 0x30) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG660QB, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x40) },
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0328/1887] USB: serial: option: add Compal EXC-T1 support
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (326 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0327/1887] USB: serial: option: add Quectel RG660QB Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0329/1887] thunderbolt: Fix KASAN reported use-after-free when request is canceled Greg Kroah-Hartman
` (670 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Lin, Johan Hovold
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Lin <ian.lin@jetone.com.tw>
commit b51faf3f2e307f114854bbe6d495f03cd5370686 upstream.
The Compal EXC-T1 is a Qualcomm MDM9207-based LTE modem which reports
"EXC-x1" as its USB product string. It exposes diagnostic, modem, AT,
and NMEA ports as vendor-specific interfaces with subclass 0x10 and
protocols 0x01 through 0x04.
Add exact interface matches for these four ports, leaving the ff/ff/ff
interface unbound.
Relevant output from usb-devices:
T: Bus=03 Lev=02 Prnt=03 Port=03 Cnt=01 Dev#= 6 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=04b7 ProdID=4d22 Rev=03.18
S: Manufacturer=CEI
S: Product=EXC-x1
C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=10 Prot=01 Driver=option
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=02 Driver=option
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=03 Driver=option
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=04 Driver=option
I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=10 Prot=05 Driver=qmi_wwan
Tested on a Compal EXC-T1 modem using an Ubuntu kernel build. The four
serial interfaces bound to option and exposed ttyUSB3 through ttyUSB6.
Assisted-by: Codex:GPT-5
Signed-off-by: Ian Lin <ian.lin@jetone.com.tw>
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/serial/option.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2437,6 +2437,10 @@ static const struct usb_device_id option
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe167, 0xff), /* Foxconn T99W640 MBIM */
.driver_info = RSVD(3) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x4d22, 0xff, 0x10, 0x01) }, /* Compal EXC-T1 */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x4d22, 0xff, 0x10, 0x02) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x4d22, 0xff, 0x10, 0x03) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x4d22, 0xff, 0x10, 0x04) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x30) }, /* Compal EXM-G1x */
{ USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x04b7, 0x8217, 0xff, 0xff, 0x60) },
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0329/1887] thunderbolt: Fix KASAN reported use-after-free when request is canceled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (327 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0328/1887] USB: serial: option: add Compal EXC-T1 support Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0330/1887] thunderbolt: Disable CL states for the Anker Prime TB5 dock Greg Kroah-Hartman
` (669 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alan Borzeszkowski, Mika Westerberg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg <mika.westerberg@linux.intel.com>
commit a02188ddc24b7872f0c5e0c5873f827318717803 upstream.
Alan reported that when doing stress testing sometimes KASAN notices
use-after-free during control channel operation (stripped down keeping
the relevant parts):
BUG: KASAN: slab-use-after-free in tb_cfg_request_sync+0x240/0x250 [thunderbolt]
Read of size 24 at addr ffff88811067f290 by task kworker/u40:2/1760
<TASK>
tb_cfg_request_sync+0x240/0x250 [thunderbolt]
tb_cfg_read_raw+0x367/0x510 [thunderbolt]
tb_cfg_read+0xec/0x240 [thunderbolt]
tb_port_get_link_generation+0x258/0x420 [thunderbolt]
tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
process_one_work+0x675/0x1230
worker_thread+0x5e6/0xf70
kthread+0x365/0x470
ret_from_fork+0x54d/0x710
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 1760:
__kmalloc_cache_noprof+0x1ee/0x550
tb_cfg_read_raw+0x1d3/0x510 [thunderbolt]
tb_cfg_read+0xec/0x240 [thunderbolt]
tb_port_get_link_generation+0x258/0x420 [thunderbolt]
tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
process_one_work+0x675/0x1230
worker_thread+0x5e6/0xf70
kthread+0x365/0x470
ret_from_fork+0x54d/0x710
ret_from_fork_asm+0x1a/0x30
Freed by task 926:
kfree+0x18f/0x4a0
tb_cfg_request_put+0xb7/0xe0 [thunderbolt]
tb_cfg_request_work+0x82/0x120 [thunderbolt]
process_one_work+0x675/0x1230
worker_thread+0x5e6/0xf70
kthread+0x365/0x470
ret_from_fork+0x54d/0x710
ret_from_fork_asm+0x1a/0x30
Second to last potentially related work creation:
__queue_work+0x575/0xd00
queue_work_on+0x77/0x80
tb_cfg_request_cancel+0xc7/0x260 [thunderbolt]
tb_cfg_request_sync+0x1f6/0x250 [thunderbolt]
tb_cfg_read_raw+0x367/0x510 [thunderbolt]
tb_cfg_read+0xec/0x240 [thunderbolt]
tb_port_get_link_generation+0x258/0x420 [thunderbolt]
tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
process_one_work+0x675/0x1230
worker_thread+0x5e6/0xf70
kthread+0x365/0x470
ret_from_fork+0x54d/0x710
ret_from_fork_asm+0x1a/0x30
The last stack trace is helpful because it shows that we are cancelling
a request and looking at tb_cfg_request_cancel() what might happen is
that tb_cfg_request_work() completes right before tb_cfg_request_cancel()
starts and because of this it will call schedule_work() queueing the
same work to run again. However, it is already removed from the
request_queue and reference count is dropped so when
tb_cfg_request_work() triggers again it will access memory that is
already released.
Fix this so that we first make sure a cancelled request is not handed
away from tb_cfg_request_find() or scheduled to run. Then instead of
relying on the worker to clean up the request we will do it in
tb_cfg_request_cancel() after the work is canceled from running. Make
tb_cfg_request_dequeue() release the request only if it was actually
removed from the queue.
Reported-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
Fixes: d7f781bfdbf4 ("thunderbolt: Rework control channel to be more reliable")
Cc: stable@vger.kernel.org
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/thunderbolt/ctl.c | 63 ++++++++++++++++++++++------------------------
1 file changed, 31 insertions(+), 32 deletions(-)
--- a/drivers/thunderbolt/ctl.c
+++ b/drivers/thunderbolt/ctl.c
@@ -65,7 +65,6 @@ struct tb_ctl {
#define tb_ctl_dbg(ctl, format, arg...) \
dev_dbg(&(ctl)->nhi->pdev->dev, format, ## arg)
-static DECLARE_WAIT_QUEUE_HEAD(tb_cfg_request_cancel_queue);
/* Serializes access to request kref_get/put */
static DEFINE_MUTEX(tb_cfg_request_lock);
@@ -123,41 +122,42 @@ void tb_cfg_request_put(struct tb_cfg_re
static int tb_cfg_request_enqueue(struct tb_ctl *ctl,
struct tb_cfg_request *req)
{
+ tb_cfg_request_get(req);
+
WARN_ON(test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags));
WARN_ON(req->ctl);
- mutex_lock(&ctl->request_queue_lock);
+ guard(mutex)(&ctl->request_queue_lock);
if (!ctl->running) {
- mutex_unlock(&ctl->request_queue_lock);
+ tb_cfg_request_put(req);
return -ENOTCONN;
}
req->ctl = ctl;
list_add_tail(&req->list, &ctl->request_queue);
set_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
- mutex_unlock(&ctl->request_queue_lock);
return 0;
}
-static void tb_cfg_request_dequeue(struct tb_cfg_request *req)
+static bool tb_cfg_request_is_active(struct tb_cfg_request *req)
{
- struct tb_ctl *ctl = req->ctl;
-
- mutex_lock(&ctl->request_queue_lock);
- if (!test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags)) {
- mutex_unlock(&ctl->request_queue_lock);
- return;
- }
+ return test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
+}
- list_del(&req->list);
- clear_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
- if (test_bit(TB_CFG_REQUEST_CANCELED, &req->flags))
- wake_up(&tb_cfg_request_cancel_queue);
- mutex_unlock(&ctl->request_queue_lock);
+static bool tb_cfg_request_is_canceled(struct tb_cfg_request *req)
+{
+ return test_bit(TB_CFG_REQUEST_CANCELED, &req->flags);
}
-static bool tb_cfg_request_is_active(struct tb_cfg_request *req)
+static void tb_cfg_request_dequeue(struct tb_cfg_request *req)
{
- return test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
+ struct tb_ctl *ctl = req->ctl;
+
+ guard(mutex)(&ctl->request_queue_lock);
+ if (tb_cfg_request_is_active(req)) {
+ list_del(&req->list);
+ clear_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
+ tb_cfg_request_put(req);
+ }
}
static struct tb_cfg_request *
@@ -168,7 +168,7 @@ tb_cfg_request_find(struct tb_ctl *ctl,
mutex_lock(&pkg->ctl->request_queue_lock);
list_for_each_entry(iter, &pkg->ctl->request_queue, list) {
tb_cfg_request_get(iter);
- if (iter->match(iter, pkg)) {
+ if (!tb_cfg_request_is_canceled(iter) && iter->match(iter, pkg)) {
req = iter;
break;
}
@@ -495,8 +495,11 @@ static void tb_ctl_rx_callback(struct tb
*/
req = tb_cfg_request_find(pkg->ctl, pkg);
if (req) {
- if (req->copy(req, pkg))
- schedule_work(&req->work);
+ scoped_guard(mutex, &pkg->ctl->request_queue_lock) {
+ if (!tb_cfg_request_is_canceled(req) &&
+ req->copy(req, pkg))
+ schedule_work(&req->work);
+ }
tb_cfg_request_put(req);
}
@@ -508,11 +511,10 @@ static void tb_cfg_request_work(struct w
{
struct tb_cfg_request *req = container_of(work, typeof(*req), work);
- if (!test_bit(TB_CFG_REQUEST_CANCELED, &req->flags))
+ if (!tb_cfg_request_is_canceled(req))
req->callback(req->callback_data);
tb_cfg_request_dequeue(req);
- tb_cfg_request_put(req);
}
/**
@@ -536,10 +538,9 @@ int tb_cfg_request(struct tb_ctl *ctl, s
INIT_WORK(&req->work, tb_cfg_request_work);
INIT_LIST_HEAD(&req->list);
- tb_cfg_request_get(req);
ret = tb_cfg_request_enqueue(ctl, req);
if (ret)
- goto err_put;
+ return ret;
ret = tb_ctl_tx(ctl, req->request, req->request_size,
req->request_type);
@@ -553,9 +554,6 @@ int tb_cfg_request(struct tb_ctl *ctl, s
err_dequeue:
tb_cfg_request_dequeue(req);
-err_put:
- tb_cfg_request_put(req);
-
return ret;
}
@@ -569,9 +567,10 @@ err_put:
*/
void tb_cfg_request_cancel(struct tb_cfg_request *req, int err)
{
- set_bit(TB_CFG_REQUEST_CANCELED, &req->flags);
- schedule_work(&req->work);
- wait_event(tb_cfg_request_cancel_queue, !tb_cfg_request_is_active(req));
+ scoped_guard(mutex, &req->ctl->request_queue_lock)
+ set_bit(TB_CFG_REQUEST_CANCELED, &req->flags);
+ cancel_work_sync(&req->work);
+ tb_cfg_request_dequeue(req);
req->result.err = err;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0330/1887] thunderbolt: Disable CL states for the Anker Prime TB5 dock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (328 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0329/1887] thunderbolt: Fix KASAN reported use-after-free when request is canceled Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0331/1887] thunderbolt: Reject oversized XDomain properties responses Greg Kroah-Hartman
` (668 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kurt Lieber, Mika Westerberg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kurt Lieber <kurt@lieber.org>
commit 395e9f2967a7ac6898026e8f136c369805dc2fd9 upstream.
The Anker Prime TB5 dock identifies itself in the DROM as 01ea:83b5.
Its router config space is an Intel Barlow Ridge 80G hub (8087:5786).
The upstream lane adapter advertises CL0s, CL1, and CL2. With CLx left
enabled, TMU uni-directional LowRes setup fails with -ENOTCONN, the USB3
and DisplayPort tunnels are aborted, and the router reconnects in a loop.
Loading thunderbolt with clx=0 keeps the link up on this machine.
Match the DROM id together with the Barlow Ridge hub id and disable CL
states for this dock only. QUIRK_NO_CLX takes the same early-out as the
module parameter, without disabling CLx for every other router.
Closes: https://lore.kernel.org/linux-usb/SJ0PR15MB4696D491504DB667AA8E0617A3812@SJ0PR15MB4696.namprd15.prod.outlook.com/
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Kurt Lieber <kurt@lieber.org>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/thunderbolt/quirks.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/thunderbolt/quirks.c
+++ b/drivers/thunderbolt/quirks.c
@@ -92,6 +92,9 @@ static const struct tb_quirk tb_quirks[]
quirk_usb3_maximum_bandwidth },
{ 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE, 0x0000, 0x0000,
quirk_usb3_maximum_bandwidth },
+ /* CLx is unstable on the Anker Prime TB5 dock (DROM 01ea:83b5) */
+ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE, 0x01ea, 0x83b5,
+ quirk_clx_disable },
/*
* Block Runtime PM in DP redrive mode for Intel Barlow Ridge host
* controllers.
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0331/1887] thunderbolt: Reject oversized XDomain properties responses
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (329 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0330/1887] thunderbolt: Disable CL states for the Anker Prime TB5 dock Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0332/1887] iio: accel: kxcjk-1013: reject duplicate event disable Greg Kroah-Hartman
` (667 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Mika Westerberg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 80756e263846ab694984e749e8c626897331438f upstream.
tb_xdp_properties_request() allocates room for 45 data dwords in its
252-byte response buffer. The XDomain length field is six bits wide,
however, and a malicious peer can set it to 63. After the fixed response
fields are subtracted, the driver treats this as 48 data dwords.
Commit 322e93448d90 ("thunderbolt: Clamp XDomain response data copy to
allocation size") only bounds the copy against data_len. If data_len is
at least 48, memcpy() reads 192 bytes from the 180-byte res->data array,
causing a 12-byte heap out-of-bounds read. Commit 4db2bd2ed478
("thunderbolt: Limit XDomain response copy to actual frame size") limits
the earlier copy but does not constrain this header-derived length.
Reject response data lengths that exceed the allocated source buffer
before copying them into the assembled property block.
Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/thunderbolt/xdomain.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -377,6 +377,10 @@ static int tb_xdp_properties_request(str
len += sizeof(res->hdr.xd_hdr) / 4;
len -= sizeof(*res) / 4;
+ if (len > TB_XDP_PROPERTIES_MAX_DATA_LENGTH) {
+ ret = -EINVAL;
+ goto err;
+ }
if (res->offset != req.offset) {
ret = -EINVAL;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0332/1887] iio: accel: kxcjk-1013: reject duplicate event disable
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (330 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0331/1887] thunderbolt: Reject oversized XDomain properties responses Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0333/1887] iio: accel: sca3000: fix frequency divider condition check Greg Kroah-Hartman
` (666 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jiale Yao, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiale Yao <yaojiale02@163.com>
commit dd30c10ff60d2b30386c23bb7c61cc97f2385c97 upstream.
The IIO core does not filter duplicate writes to the event enable
attribute. kxcjk1013_write_event_config() already ignores repeated
enable requests, but a repeated disable request still calls
kxcjk1013_set_power_state(data, false), dropping a runtime PM reference
that was not acquired for this request. This can underflow the runtime
PM usage count and trigger a "Runtime PM usage count underflow" warning.
Return early when the requested state already matches ev_enable_state.
Fixes: b4b491c0832e ("iio: accel: kxcjk-1013: Support thresholds")
Signed-off-by: Jiale Yao <yaojiale02@163.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/accel/kxcjk-1013.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -1051,7 +1051,7 @@ static int kxcjk1013_write_event_config(
struct kxcjk1013_data *data = iio_priv(indio_dev);
int ret;
- if (state && data->ev_enable_state)
+ if (state == data->ev_enable_state)
return 0;
mutex_lock(&data->mutex);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0333/1887] iio: accel: sca3000: fix frequency divider condition check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (331 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0332/1887] iio: accel: kxcjk-1013: reject duplicate event disable Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0334/1887] iio: adc: sun4i-gpadc-iio: clean up on thermal zone registration failure Greg Kroah-Hartman
` (665 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Salah Triki, Joshua Crofts,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <salah.triki@gmail.com>
commit d380bf5f94a892e546d9a94e8557ad866b043a2a upstream.
When setting the sampling frequency, the check for `base_freq / 2` is
followed by an independent `if` statement for `base_freq / 4`. If `val`
equals `base_freq / 2`, the second check fails and falls through to the
`else if (val != base_freq)` branch, returning `-EINVAL` erroneously.
Fix this by chaining the checks with `else if`.
Fixes: e0f3fc9b47e6 ("iio: accel: sca3000_core: implemented IIO_CHAN_INFO_SAMP_FREQ")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/accel/sca3000.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/accel/sca3000.c
+++ b/drivers/iio/accel/sca3000.c
@@ -652,7 +652,7 @@ static int sca3000_write_raw_samp_freq(s
if (val == base_freq / 2)
ctrlval |= SCA3000_REG_OUT_CTRL_BUF_DIV_2;
- if (val == base_freq / 4)
+ else if (val == base_freq / 4)
ctrlval |= SCA3000_REG_OUT_CTRL_BUF_DIV_4;
else if (val != base_freq)
return -EINVAL;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0334/1887] iio: adc: sun4i-gpadc-iio: clean up on thermal zone registration failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (332 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0333/1887] iio: accel: sca3000: fix frequency divider condition check Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0335/1887] iio: adc: sun4i-gpadc-iio: drop underflowing pm_runtime_put() calls Greg Kroah-Hartman
` (664 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Gu, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <ustc.gu@gmail.com>
commit 2cdc7ef31827db4fbc6283750420639569e1f0e9 upstream.
If devm_thermal_of_zone_register() fails, probe returns without
unregistering the IIO map array or disabling runtime PM.
Jump to err_map to release them.
Fixes: b0a242894f11 ("iio: adc: sun4i-gpadc-iio: register in the thermal after registering in pm")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -645,10 +645,10 @@ static int sun4i_gpadc_probe(struct plat
* thermal because no thermal DT node is found.
*/
if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) {
- dev_err(&pdev->dev,
- "could not register thermal sensor: %ld\n",
- PTR_ERR(info->tzd));
- return PTR_ERR(info->tzd);
+ ret = dev_err_probe(&pdev->dev,
+ PTR_ERR(info->tzd),
+ "could not register thermal sensor\n");
+ goto err_map;
}
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0335/1887] iio: adc: sun4i-gpadc-iio: drop underflowing pm_runtime_put() calls
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (333 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0334/1887] iio: adc: sun4i-gpadc-iio: clean up on thermal zone registration failure Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0336/1887] iio: adc: xilinx-xadc: free IRQ before cancelling the unmask worker on unbind Greg Kroah-Hartman
` (663 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Gu, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <ustc.gu@gmail.com>
commit 8b958dd214ad0c003f56549e9e039cb8067dc1a2 upstream.
Neither the error path in sun4i_gpadc_probe() nor sun4i_gpadc_remove()
ever holds a runtime PM usage count. So the pm_runtime_put() in both
places always triggers the "Runtime PM usage count underflow!" warning
on every failed probe and every unbind.
Drop both calls.
Fixes: d1caa9905538 ("iio: adc: add support for Allwinner SoCs ADC")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -664,7 +664,6 @@ err_map:
if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF))
iio_map_array_unregister(indio_dev);
- pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
@@ -675,7 +674,6 @@ static int sun4i_gpadc_remove(struct pla
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
- pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ENABLED(CONFIG_THERMAL_OF))
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0336/1887] iio: adc: xilinx-xadc: free IRQ before cancelling the unmask worker on unbind
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (334 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0335/1887] iio: adc: sun4i-gpadc-iio: drop underflowing pm_runtime_put() calls Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0337/1887] iio: buffer: Ensure bounce buffer used for unaligned case is zeroed Greg Kroah-Hartman
` (662 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Lechner, Fan Wu,
Sai Krishna Potthuri, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 0f3f427076240e75ff265e61645627a71ca4918c upstream.
The ZYNQ XADC alarm IRQ handler queues zynq_unmask_work via
schedule_delayed_work(); that work is cleared by a devm callback.
Register the devm callback before devm_request_irq() so the devres LIFO
teardown frees the IRQ first, ensuring the handler can no longer queue
work by the time the workqueue is cleared. Otherwise the handler could
re-arm the work and run it after the xadc structure has been freed.
This issue was found by an in-house static analysis tool.
Fixes: 2a9685d1a3b7 ("iio: adc: xilinx: use more devres helpers and remove remove()")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Reviewed-by: David Lechner <dlechner@baylibre.com>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/adc/xilinx-xadc-core.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -1406,13 +1406,14 @@ static int xadc_probe(struct platform_de
}
if (irq > 0) {
- ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler,
- 0, dev_name(dev), indio_dev);
+ /* Clear out any work queued by the interrupt */
+ ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
+ &xadc->zynq_unmask_work);
if (ret)
return ret;
- ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
- &xadc->zynq_unmask_work);
+ ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler,
+ 0, dev_name(dev), indio_dev);
if (ret)
return ret;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0337/1887] iio: buffer: Ensure bounce buffer used for unaligned case is zeroed.
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (335 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0336/1887] iio: adc: xilinx-xadc: free IRQ before cancelling the unmask worker on unbind Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0338/1887] iio: frequency: admv1013: fix wrong channel field used in admv1013_read_raw() Greg Kroah-Hartman
` (661 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Andy Shevchenko,
Joshua Crofts, Nuno Sá, Stable, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
commit 5330036bc68d23672bfcc16c60c54701ae123083 upstream.
iio_push_to_buffers_with_ts_unaligned() leaks uninitialized heap memory
to userspace if the data passed in is not a multiple of 8 bytes and the
timestamp is enabled. Specify __GFP_ZERO for the devm_krealloc()
to ensure any extra space is cleared.
Fixes: 95ec3fdf2b79 ("iio: core: Introduce iio_push_to_buffers_with_ts_unaligned()")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260529121005.1470-1-kimjinseob88%40gmail.com
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/industrialio-buffer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -1905,7 +1905,8 @@ int iio_push_to_buffers_with_ts_unaligne
bb = devm_krealloc(&indio_dev->dev,
iio_dev_opaque->bounce_buffer,
- indio_dev->scan_bytes, GFP_KERNEL);
+ indio_dev->scan_bytes,
+ GFP_KERNEL | __GFP_ZERO);
if (!bb)
return -ENOMEM;
iio_dev_opaque->bounce_buffer = bb;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0338/1887] iio: frequency: admv1013: fix wrong channel field used in admv1013_read_raw()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (336 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0337/1887] iio: buffer: Ensure bounce buffer used for unaligned case is zeroed Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0339/1887] iio: gyro: adis16136: fix unprotected debugfs reads Greg Kroah-Hartman
` (660 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Salah Triki, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <salah.triki@gmail.com>
commit 2093236e886ad9446ec3285ba520e024dd1464e1 upstream.
admv1013_read_raw() switches on chan->channel instead of
chan->channel2 when handling IIO_CHAN_INFO_CALIBBIAS. The channel
field only ever holds 0 or 1 (see ADMV1013_CHAN_CALIB()), while the
IIO_MOD_I / IIO_MOD_Q modifiers are stored in channel2. As a result,
the switch always falls through to the default case and calibbias
reads always fail with -EINVAL, even though the corresponding
admv1013_write_raw() path correctly uses channel2 and works as
expected.
Fix the read path to switch on chan->channel2, matching the write
path and the actual channel_spec definition.
Fixes: da35a7b526d9 ("iio: frequency: admv1013: add support for ADMV1013")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/frequency/admv1013.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/frequency/admv1013.c
+++ b/drivers/iio/frequency/admv1013.c
@@ -197,7 +197,7 @@ static int admv1013_read_raw(struct iio_
switch (info) {
case IIO_CHAN_INFO_CALIBBIAS:
- switch (chan->channel) {
+ switch (chan->channel2) {
case IIO_MOD_I:
addr = ADMV1013_REG_OFFSET_ADJUST_I;
break;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0339/1887] iio: gyro: adis16136: fix unprotected debugfs reads
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (337 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0338/1887] iio: frequency: admv1013: fix wrong channel field used in admv1013_read_raw() Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0340/1887] iio: imu: adis16400: " Greg Kroah-Hartman
` (659 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arka Mondal, Andy Shevchenko,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arka Mondal <arkamondalofficial@gmail.com>
commit 2b498df75d6c29aa3e760127ae0f0003df598b53 upstream.
The serial_number file operations are open coded and never call
debugfs_file_get(), which debugfs_create_file_unsafe() requires.
debugfs_remove_recursive() therefore does not wait for a read in
progress, and unbind frees the iio_dev underneath it.
Use debugfs_create_file() instead.
Fixes: 9aaea09b4cbd ("gyro:adis16136: fix debugfs_simple_attr.cocci warnings")
Signed-off-by: Arka Mondal <arkamondalofficial@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/gyro/adis16136.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/gyro/adis16136.c
+++ b/drivers/iio/gyro/adis16136.c
@@ -145,7 +145,7 @@ static int adis16136_debugfs_init(struct
struct adis16136 *adis16136 = iio_priv(indio_dev);
struct dentry *d = iio_get_debugfs_dentry(indio_dev);
- debugfs_create_file_unsafe("serial_number", 0400,
+ debugfs_create_file("serial_number", 0400,
d, adis16136, &adis16136_serial_fops);
debugfs_create_file_unsafe("product_id", 0400,
d, adis16136, &adis16136_product_id_fops);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0340/1887] iio: imu: adis16400: fix unprotected debugfs reads
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (338 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0339/1887] iio: gyro: adis16136: fix unprotected debugfs reads Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0341/1887] iio: imu: adis16480: " Greg Kroah-Hartman
` (658 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Arka Mondal, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arka Mondal <arkamondalofficial@gmail.com>
commit d94787287a113a1326211647d5e0deed1e9de105 upstream.
adis16400_serial_number_fops is open coded and never calls
debugfs_file_get(), so debugfs_remove_recursive() does not wait for a
read in progress and unbind frees the iio_dev underneath it.
Commit ae1d37a9bb4b ("iio: imu: adis16400: use DEFINE_DEBUGFS_ATTRIBUTE
instead of DEFINE_SIMPLE_ATTRIBUTE") converted product_id and
flash_count to DEFINE_DEBUGFS_ATTRIBUTE, which protects itself, but
moved all three files to debugfs_create_file_unsafe().
serial_number prints three registers as "%.4x-%.4x-%.4x" and
DEFINE_DEBUGFS_ATTRIBUTE() formats a single u64, so it cannot be
converted without changing what the file returns. adis16475 and
adis16550 already use debugfs_create_file() for their open coded
files. Use it here too.
Fixes: ae1d37a9bb4b ("iio: imu: adis16400: use DEFINE_DEBUGFS_ATTRIBUTE instead of DEFINE_SIMPLE_ATTRIBUTE")
Signed-off-by: Arka Mondal <arkamondalofficial@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/imu/adis16400.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/imu/adis16400.c
+++ b/drivers/iio/imu/adis16400.c
@@ -279,7 +279,7 @@ static int adis16400_debugfs_init(struct
struct dentry *d = iio_get_debugfs_dentry(indio_dev);
if (st->variant->flags & ADIS16400_HAS_SERIAL_NUMBER)
- debugfs_create_file_unsafe("serial_number", 0400,
+ debugfs_create_file("serial_number", 0400,
d, st, &adis16400_serial_number_fops);
if (st->variant->flags & ADIS16400_HAS_PROD_ID)
debugfs_create_file_unsafe("product_id", 0400,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0341/1887] iio: imu: adis16480: fix unprotected debugfs reads
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (339 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0340/1887] iio: imu: adis16400: " Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0342/1887] iio: light: gp2ap020a00f: drain irq_work after free_irq Greg Kroah-Hartman
` (657 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arka Mondal, Andy Shevchenko,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arka Mondal <arkamondalofficial@gmail.com>
commit e1dea54496f90a62318cf4eeaa1e9ef8316e92b6 upstream.
The firmware_revision and firmware_date file operations are open coded
and never call debugfs_file_get(), which debugfs_create_file_unsafe()
requires. debugfs_remove_recursive() therefore does not wait for a read
in progress, and unbind frees the iio_dev underneath it.
Use debugfs_create_file() instead.
Fixes: 9bf94f836e32 ("imu:adis16480: fix debugfs_simple_attr.cocci warnings")
Signed-off-by: Arka Mondal <arkamondalofficial@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/imu/adis16480.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -302,9 +302,9 @@ static int adis16480_debugfs_init(struct
struct adis16480 *adis16480 = iio_priv(indio_dev);
struct dentry *d = iio_get_debugfs_dentry(indio_dev);
- debugfs_create_file_unsafe("firmware_revision", 0400,
+ debugfs_create_file("firmware_revision", 0400,
d, adis16480, &adis16480_firmware_revision_fops);
- debugfs_create_file_unsafe("firmware_date", 0400,
+ debugfs_create_file("firmware_date", 0400,
d, adis16480, &adis16480_firmware_date_fops);
debugfs_create_file_unsafe("serial_number", 0400,
d, adis16480, &adis16480_serial_number_fops);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0342/1887] iio: light: gp2ap020a00f: drain irq_work after free_irq
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (340 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0341/1887] iio: imu: adis16480: " Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0343/1887] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup Greg Kroah-Hartman
` (656 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 63213927b141085b6c8719b8037dab3074b7e0fe upstream.
The threaded IRQ handler queues data->work through irq_work_queue() so
the trigger is polled from a per-CPU context. free_irq() does not flush
an irq_work the handler already queued, so after gp2ap020a00f_remove()
returns that work may still run and call iio_trigger_poll() on data->trig,
which the devm cleanup has already freed, causing a use-after-free.
Add irq_work_sync(&data->work) after free_irq() in remove() and in the
probe error path, mirroring commit 78601726d4a5 ("iio: trigger: sysfs:
fix use-after-free on remove").
Found by an in-house static analysis tool, confirmed by manual review.
Fixes: bf29fbeaa13d ("iio: gp2ap020a00f: Add a driver for the device")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/light/gp2ap020a00f.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/iio/light/gp2ap020a00f.c
+++ b/drivers/iio/light/gp2ap020a00f.c
@@ -1565,6 +1565,7 @@ error_trigger_unregister:
iio_trigger_unregister(data->trig);
error_free_irq:
free_irq(client->irq, indio_dev);
+ irq_work_sync(&data->work);
error_uninit_buffer:
iio_triggered_buffer_cleanup(indio_dev);
error_regulator_disable:
@@ -1587,6 +1588,7 @@ static void gp2ap020a00f_remove(struct i
iio_device_unregister(indio_dev);
iio_trigger_unregister(data->trig);
free_irq(client->irq, indio_dev);
+ irq_work_sync(&data->work);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(data->vled_reg);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0343/1887] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (341 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0342/1887] iio: light: gp2ap020a00f: drain irq_work after free_irq Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0344/1887] iio: proximity: isl29501: Fix return type of isl29501_register_write Greg Kroah-Hartman
` (655 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Su, Joshua Crofts,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
commit 56c423b233b214182c58c99861899327b45b0d6c upstream.
The sampling frequency tables store each frequency as an integer part and
a fractional part in micro units. num_sampling_freq_avail is initialized
to the number of flattened integer elements because read_avail() returns
the table as a flat array.
bmp280_write_sampling_frequency(), however, indexes the same table as a
two-dimensional array and uses num_sampling_freq_avail as the number of
rows. Convert the flattened element count back to the number of rows
before iterating over the table.
Fixes: 10b40ffba2f9 ("iio: pressure: bmp280: Add more tunable config parameters for BMP380")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Su <sh_def@163.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/pressure/bmp280-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -725,7 +725,7 @@ static int bmp280_write_sampling_frequen
int val, int val2)
{
const int (*avail)[2] = data->chip_info->sampling_freq_avail;
- const int n = data->chip_info->num_sampling_freq_avail;
+ const int n = data->chip_info->num_sampling_freq_avail / 2;
int ret, prev;
int i;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0344/1887] iio: proximity: isl29501: Fix return type of isl29501_register_write
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (342 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0343/1887] iio: pressure: bmp280: fix out-of-bounds access in sampling frequency lookup Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0345/1887] iio: proximity: pulsedlight: fix iio_device left registered on PM setup failure Greg Kroah-Hartman
` (654 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Salah Triki, Joshua Crofts,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <salah.triki@gmail.com>
commit e8dd273d199f5bbe295a8e3d8b777c5505b6b2e1 upstream.
isl29501_register_write() was returning a u32 instead of an int.
Since the function returns negative error codes (such as -ERANGE or
return values from i2c_smbus_write_byte_data()), returning an unsigned
integer type prevents callers from correctly checking for negative error
conditions.
Fix this by changing the function return type from u32 to int.
This was found through manual code review.
Fixes: 1c28799257bc ("iio: light: isl29501: Add support for the ISL29501 ToF sensor.")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/proximity/isl29501.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/proximity/isl29501.c
+++ b/drivers/iio/proximity/isl29501.c
@@ -227,7 +227,7 @@ err:
return ret;
}
-static u32 isl29501_register_write(struct isl29501_private *isl29501,
+static int isl29501_register_write(struct isl29501_private *isl29501,
enum isl29501_register_name name,
u32 value)
{
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0345/1887] iio: proximity: pulsedlight: fix iio_device left registered on PM setup failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (343 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0344/1887] iio: proximity: isl29501: Fix return type of isl29501_register_write Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0346/1887] iio: proximity: sx9324: Correct proximity channel resolution Greg Kroah-Hartman
` (653 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
commit 4daa9ca557b4b98ae1ad38a6d1deaa3e31eb8edf upstream.
pm_runtime_set_active() failing in probe() jumps to error_unreg_buffer,
which only calls iio_triggered_buffer_cleanup() -- it does not undo the
iio_device_register() that already succeeded a few lines above. probe()
then returns the error, the devm-managed indio_dev is freed, but the
iio core still has it registered: the sysfs/chardev nodes stay live and
point at freed memory.
Add an error_unreg_dev label that unregisters the iio device before
falling through to the existing buffer cleanup, mirroring the teardown
order already used in lidar_remove().
Fixes: 4ac4e086fd8c ("iio: pulsedlight-lidar-lite: add runtime PM")
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
@@ -299,12 +299,14 @@ static int lidar_probe(struct i2c_client
ret = pm_runtime_set_active(&client->dev);
if (ret)
- goto error_unreg_buffer;
+ goto error_unreg_dev;
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
return 0;
+error_unreg_dev:
+ iio_device_unregister(indio_dev);
error_unreg_buffer:
iio_triggered_buffer_cleanup(indio_dev);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0346/1887] iio: proximity: sx9324: Correct proximity channel resolution
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (344 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0345/1887] iio: proximity: pulsedlight: fix iio_device left registered on PM setup failure Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0347/1887] iio: proximity: vcnl3020: fix ISR bitmask check in IRQ handler Greg Kroah-Hartman
` (652 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhang Jie, Andy Shevchenko,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Jie <zhangjie14@huaqin.corp-partner.google.com>
commit fbf33cb18334e7cab1ed4ad2e9a98a1299ad874c upstream.
The proximity channels were previously defined with 12 realbits.
However, PROXDIFF is read from RegDiffMsb (0x65) and RegDiffLsb
(0x66). The SX9324 datasheet assigns bits 7:0 of each register to
PROXDIFF and documents it as a signed two's-complement value
(Revision 3, Section 8, Table 8, page 43). In contrast, RegOffsetMsb
explicitly marks bits 7:6 as reserved. Thus, PROXDIFF is a 16-bit
signed value.
With realbits = 12, sx_common_read_proximity() uses bit 11 as the
sign bit in sign_extend32(), causing samples outside the 12-bit
signed range to wrap into the [-2048, 2047] range.
Correct the realbits value to 16 to accurately reflect the hardware.
Tested on an SX9324-based device: a phase 0 DIFF readback of 0x7fff
was reported as -1 before this change and as 32767 afterward.
Fixes: 4c18a890dff8 ("iio:proximity:sx9324: Add SX9324 support")
Cc: stable@vger.kernel.org
Signed-off-by: Zhang Jie <zhangjie14@huaqin.corp-partner.google.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/proximity/sx9324.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/proximity/sx9324.c
+++ b/drivers/iio/proximity/sx9324.c
@@ -223,7 +223,7 @@ static const struct iio_chan_spec_ext_in
.scan_index = idx, \
.scan_type = { \
.sign = 's', \
- .realbits = 12, \
+ .realbits = 16, \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0347/1887] iio: proximity: vcnl3020: fix ISR bitmask check in IRQ handler
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (345 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0346/1887] iio: proximity: sx9324: Correct proximity channel resolution Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0348/1887] iio: trigger: cancel reenable_work before freeing trigger Greg Kroah-Hartman
` (651 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Salah Triki, Ivan Mikhaylov,
Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <salah.triki@gmail.com>
commit 7d38af8f20239a66e90de7632a79c9425256c574 upstream.
The threaded IRQ handler contained multiple issues in handling interrupt
events and clearing status flags:
1. ISR bit check: The handler incorrectly checked the Interrupt Status
Register (VCNL_ISR) against VCNL_ICR_THRES_EN (BIT(1)), which is a
bitmask meant for the Control Register (VCNL_PS_ICR). In VCNL_ISR,
BIT(1) corresponds only to low-threshold interrupts. A high-threshold
interrupt (VCNL_INT_TH_HI, BIT(0)) on its own was completely ignored and
returned IRQ_NONE.
2. Event direction & channel index: The handler unconditionally pushed a
RISING event code on channel index 1. The driver only registers a single
proximity channel (index 0), and low-threshold interrupts should be
reported with IIO_EV_DIR_FALLING.
3. ISR clearing: The write-back to acknowledge the interrupt only preserved
BIT(1) instead of masking against both valid status bits.
Fix this by checking both VCNL_INT_TH_HI and VCNL_INT_TH_LOW bits in
VCNL_ISR, pushing separate IIO events with the correct direction and
channel index (0), and properly clearing handled status bits.
Fixes: 3363fbbe19e5 ("iio: proximity: vcnl3020: add periodic mode")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
Reviewed-by: Ivan Mikhaylov <fr0st61te@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/proximity/vcnl3020.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
--- a/drivers/iio/proximity/vcnl3020.c
+++ b/drivers/iio/proximity/vcnl3020.c
@@ -584,16 +584,26 @@ static irqreturn_t vcnl3020_handle_irq_t
return IRQ_HANDLED;
}
- if (!(isr & VCNL_ICR_THRES_EN))
+ if (!(isr & (VCNL_INT_TH_HI | VCNL_INT_TH_LOW)))
return IRQ_NONE;
- iio_push_event(indio_dev,
- IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1,
- IIO_EV_TYPE_THRESH,
- IIO_EV_DIR_RISING),
- iio_get_time_ns(indio_dev));
+ if (isr & VCNL_INT_TH_HI) {
+ iio_push_event(indio_dev,
+ IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING),
+ iio_get_time_ns(indio_dev));
+ }
+
+ if (isr & VCNL_INT_TH_LOW) {
+ iio_push_event(indio_dev,
+ IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_FALLING),
+ iio_get_time_ns(indio_dev));
+ }
- rc = regmap_write(data->regmap, VCNL_ISR, isr & VCNL_ICR_THRES_EN);
+ rc = regmap_write(data->regmap, VCNL_ISR, isr & (VCNL_INT_TH_HI | VCNL_INT_TH_LOW));
if (rc)
dev_err(data->dev, "Error (%d) writing in reg (0x%x)\n",
rc, VCNL_ISR);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0348/1887] iio: trigger: cancel reenable_work before freeing trigger
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (346 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0347/1887] iio: proximity: vcnl3020: fix ISR bitmask check in IRQ handler Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0349/1887] jfs: fix array-index-out-of-bounds read in add_missing_indices Greg Kroah-Hartman
` (650 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Jonathan Cameron
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 2a57b9246cecd5dd797a42eb310d6c8816f26d9e upstream.
iio_trigger_notify_done_atomic() defers ->reenable() into
trig->reenable_work on the system workqueue, and the worker dereferences
the owning trigger through container_of(). Nothing cancels this work
before iio_trig_release() frees the trigger, so a worker armed by the
last in-flight IRQ can outlive the free and touch freed memory.
Cancel it at the top of iio_trig_release(), which every free path
reaches through the device core's final put_device().
Found by an in-house static analysis tool.
Fixes: 9020ef659885 ("iio: trigger: Fix a scheduling whilst atomic issue seen on tsc2046")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iio/industrialio-trigger.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -506,6 +506,8 @@ static void iio_trig_release(struct devi
struct iio_trigger *trig = to_iio_trigger(device);
int i;
+ cancel_work_sync(&trig->reenable_work);
+
if (trig->subirq_base) {
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
irq_modify_status(trig->subirq_base + i,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0349/1887] jfs: fix array-index-out-of-bounds read in add_missing_indices
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (347 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0348/1887] iio: trigger: cancel reenable_work before freeing trigger Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0350/1887] drm/amd/powerplay: fix VoltageObjectInfo zero-stride loop and OOB read Greg Kroah-Hartman
` (649 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b974bd41515f770c608b,
Aditya Dutt, Dave Kleikamp, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Dutt <duttaditya18@gmail.com>
[ Upstream commit 5dff41a86377563f7a2b968aae00d25b4ceb37c9 ]
stbl is s8 but it must contain offsets into slot which can go from 0 to
127.
Added a bound check for that error and return -EIO if the check fails.
Also make jfs_readdir return with error if add_missing_indices returns
with an error.
Reported-by: syzbot+b974bd41515f770c608b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com./bug?extid=b974bd41515f770c608b
Signed-off-by: Aditya Dutt <duttaditya18@gmail.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/jfs/jfs_dtree.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 93db6eec44655..ab11849cf9cc3 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2613,7 +2613,7 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
* fsck.jfs should really fix this, but it currently does not.
* Called from jfs_readdir when bad index is detected.
*/
-static void add_missing_indices(struct inode *inode, s64 bn)
+static int add_missing_indices(struct inode *inode, s64 bn)
{
struct ldtentry *d;
struct dt_lock *dtlck;
@@ -2622,7 +2622,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
struct lv *lv;
struct metapage *mp;
dtpage_t *p;
- int rc;
+ int rc = 0;
s8 *stbl;
tid_t tid;
struct tlock *tlck;
@@ -2647,6 +2647,16 @@ static void add_missing_indices(struct inode *inode, s64 bn)
stbl = DT_GETSTBL(p);
for (i = 0; i < p->header.nextindex; i++) {
+ if (stbl[i] < 0) {
+ jfs_err("jfs: add_missing_indices: Invalid stbl[%d] = %d for inode %ld, block = %lld",
+ i, stbl[i], (long)inode->i_ino, (long long)bn);
+ rc = -EIO;
+
+ DT_PUTPAGE(mp);
+ txAbort(tid, 0);
+ goto end;
+ }
+
d = (struct ldtentry *) &p->slot[stbl[i]];
index = le32_to_cpu(d->index);
if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
@@ -2664,6 +2674,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
(void) txCommit(tid, 1, &inode, 0);
end:
txEnd(tid);
+ return rc;
}
/*
@@ -3017,7 +3028,8 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
}
if (fix_page) {
- add_missing_indices(ip, bn);
+ if ((rc = add_missing_indices(ip, bn)))
+ goto out;
page_fixed = 1;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0350/1887] drm/amd/powerplay: fix VoltageObjectInfo zero-stride loop and OOB read
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (348 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0349/1887] jfs: fix array-index-out-of-bounds read in add_missing_indices Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0351/1887] SUNRPC: fix gssx_dec_option_array error path bugs Greg Kroah-Hartman
` (648 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Asad Kamal, Lijo Lazar, Yang Wang,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asad Kamal <asad.kamal@amd.com>
[ Upstream commit 5d3cc8e388464f485d0944b87b8f9426e637d082 ]
Reject voltage objects whose usSize is smaller than the header or would
advance the cursor past the table end, preventing an infinite loop or
heap OOB read when the VBIOS supplies a malformed VoltageObjectInfo table.
Fixes: c82baa281843 ("drm/amd/powerplay: add Tonga dpm support (v3)")
Fixes: 0d2c7569e196 ("drm/amdgpu: add new atomfirmware based helpers for powerplay")
Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 10 ++++++++--
drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c | 11 ++++++++---
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
index 7e37354a03411..640350bbd9085 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
@@ -269,15 +269,21 @@ static const ATOM_VOLTAGE_OBJECT_V3 *atomctrl_lookup_voltage_type_v3(
unsigned int offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
uint8_t *start = (uint8_t *)voltage_object_info_table;
- while (offset < size) {
+ while (offset + sizeof(ATOM_VOLTAGE_OBJECT_HEADER_V3) <= size) {
const ATOM_VOLTAGE_OBJECT_V3 *voltage_object =
(const ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
+ u16 obj_size;
+
+ obj_size = le16_to_cpu(voltage_object->asGpioVoltageObj.sHeader.usSize);
+ if (obj_size < sizeof(voltage_object->asGpioVoltageObj.sHeader) ||
+ offset + obj_size > size)
+ break;
if (voltage_type == voltage_object->asGpioVoltageObj.sHeader.ucVoltageType &&
voltage_mode == voltage_object->asGpioVoltageObj.sHeader.ucVoltageMode)
return voltage_object;
- offset += le16_to_cpu(voltage_object->asGpioVoltageObj.sHeader.usSize);
+ offset += obj_size;
}
return NULL;
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c
index a47a47238e2b9..e5aa787182025 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c
@@ -36,16 +36,21 @@ static const union atom_voltage_object_v4 *pp_atomfwctrl_lookup_voltage_type_v4(
offsetof(struct atom_voltage_objects_info_v4_1, voltage_object[0]);
unsigned long start = (unsigned long)voltage_object_info_table;
- while (offset < size) {
+ while (offset + sizeof(struct atom_voltage_object_header_v4) <= size) {
const union atom_voltage_object_v4 *voltage_object =
(const union atom_voltage_object_v4 *)(start + offset);
+ u16 obj_size;
+
+ obj_size = le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size);
+ if (obj_size < sizeof(voltage_object->gpio_voltage_obj.header) ||
+ offset + obj_size > size)
+ break;
if (voltage_type == voltage_object->gpio_voltage_obj.header.voltage_type &&
voltage_mode == voltage_object->gpio_voltage_obj.header.voltage_mode)
return voltage_object;
- offset += le16_to_cpu(voltage_object->gpio_voltage_obj.header.object_size);
-
+ offset += obj_size;
}
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0351/1887] SUNRPC: fix gssx_dec_option_array error path bugs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (349 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0350/1887] drm/amd/powerplay: fix VoltageObjectInfo zero-stride loop and OOB read Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0352/1887] SUNRPC: reject duplicate CREDS_VALUE options Greg Kroah-Hartman
` (647 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Jeff Layton,
Chuck Lever, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <clm@meta.com>
[ Upstream commit 5e9a94539b1ec17a89177d952badfd0d844d694a ]
Four coupled defects in the gssx XDR option-array decoder make the
error paths unsafe: a NULL deref in the caller, a refcount leak on
the decoded group_info, and a latent use-after-free that the leak
fix would otherwise expose.
gssx_dec_option_array() sets oa->count = 1 before allocating
oa->data. If that allocation fails, -ENOMEM is returned with
oa->count == 1 and oa->data == NULL. All other error paths jump
to free_oa: which frees oa->data and NULLs it but also leaves
oa->count == 1. The caller trusts the count:
gssp_accept_sec_context_upcall()
gssx_dec_accept_sec_context()
gssx_dec_option_array() /* fails, count=1 data=NULL */
data = res.options.data[0].value /* NULL deref */
Independently, free_creds: releases the partially decoded svc_cred
with a bare kfree(creds). gssx_dec_linux_creds() installs a
groups_alloc() result into creds->cr_group_info; that object is
kvmalloc-backed and refcounted, and only put_group_info() reaches
kvfree(). A plain kfree(creds) drops the wrapper and leaks the
group_info allocation.
The natural fix for the leak is to call free_svc_cred(creds) before
kfree(creds), but free_svc_cred() invokes put_group_info() on
creds->cr_group_info unconditionally when non-NULL. The existing
out_free_groups: path in gssx_dec_linux_creds() already called
groups_free() on that pointer without clearing it, so once
free_svc_cred() is wired in, the subsequent put_group_info() would
touch freed memory.
Fix all four together:
- Move the oa->count = 1 assignment below the oa->data allocation
so it is never set when oa->data is NULL.
- Reset oa->count to 0 at free_oa: so count and data stay
coherent and the caller sees an empty option array.
- Call free_svc_cred(creds) before kfree(creds) at free_creds:
so the refcounted cr_group_info is released. free_svc_cred()
either NULL-guards each field explicitly (cr_group_info has
an if() check) or delegates to a helper that is NULL-safe
itself (kfree for the string fields, gss_mech_put() which
guards with if(gm) at gss_mech_switch.c:342), so it is safe
to call on a partially decoded svc_cred where only
cr_uid/cr_gid/cr_group_info have been written and everything
else is zero from kzalloc.
- In gssx_dec_linux_creds()'s out_free_groups: path, release
cr_group_info with put_group_info() rather than groups_free()
so the teardown matches free_svc_cred()'s refcount-aware path,
and clear the pointer so a later free_svc_cred() on the same
creds does not release it a second time.
Fixes: 3cfcfc102a5e ("SUNRPC: fix some memleaks in gssx_dec_option_array")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-2-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/auth_gss/gss_rpc_xdr.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index ee91f4d641e6f..ac9ae42a69762 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -222,7 +222,8 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr,
return 0;
out_free_groups:
- groups_free(creds->cr_group_info);
+ put_group_info(creds->cr_group_info);
+ creds->cr_group_info = NULL;
return err;
}
@@ -242,12 +243,12 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
return 0;
/* we recognize only 1 currently: CREDS_VALUE */
- oa->count = 1;
-
oa->data = kmalloc(sizeof(struct gssx_option), GFP_KERNEL);
if (!oa->data)
return -ENOMEM;
+ oa->count = 1;
+
creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL);
if (!creds) {
err = -ENOMEM;
@@ -294,8 +295,10 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
return 0;
free_creds:
+ free_svc_cred(creds);
kfree(creds);
free_oa:
+ oa->count = 0;
kfree(oa->data);
oa->data = NULL;
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0352/1887] SUNRPC: reject duplicate CREDS_VALUE options
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (350 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0351/1887] SUNRPC: fix gssx_dec_option_array error path bugs Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0353/1887] vc_screen: reload vc pointer before if (ret) in vcs_write() to avoid UAF Greg Kroah-Hartman
` (646 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Jeff Layton,
Chuck Lever, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <clm@meta.com>
[ Upstream commit 2e4ce62385c1b8a887c5370af058ac7b52a8eaf9 ]
gssx_dec_option_array() walks the wire-supplied option array and, for
every entry whose name matches CREDS_VALUE, calls
gssx_dec_linux_creds() on the same struct svc_cred. That helper
unconditionally installs a fresh groups_alloc() result into
creds->cr_group_info without releasing whatever pointer was already
there:
for (i = 0; i < count; i++) {
... decode name ...
if (length == sizeof(CREDS_VALUE) &&
memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
err = gssx_dec_linux_creds(xdr, creds);
...
}
}
A reply that carries two CREDS_VALUE entries therefore overwrites
cr_group_info on the second iteration and orphans the group_info
allocated by the first call. The earlier free_creds path only
releases the last cr_group_info via free_svc_cred(), so the first
allocation's refcount stays at one and its kvmalloc-backed storage
is leaked. No in-tree caller of gssp_accept_sec_context_upcall()
expects more than one CREDS_VALUE per reply.
Fix by tracking whether a CREDS_VALUE option has already been
decoded and returning -EINVAL on any subsequent match, so the
free_creds path releases the single group_info that was installed.
Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-3-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/auth_gss/gss_rpc_xdr.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index ac9ae42a69762..967943ae61c62 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -231,6 +231,7 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
struct gssx_option_array *oa)
{
struct svc_cred *creds;
+ bool creds_decoded = false;
u32 count, i;
__be32 *p;
int err;
@@ -281,9 +282,14 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
if (length == sizeof(CREDS_VALUE) &&
memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
/* We have creds here. parse them */
+ if (creds_decoded) {
+ err = -EINVAL;
+ goto free_creds;
+ }
err = gssx_dec_linux_creds(xdr, creds);
if (err)
goto free_creds;
+ creds_decoded = true;
oa->data[0].value.len = 1; /* presence */
} else {
/* consume uninteresting buffer */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0353/1887] vc_screen: reload vc pointer before if (ret) in vcs_write() to avoid UAF
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (351 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0352/1887] SUNRPC: reject duplicate CREDS_VALUE options Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0354/1887] mtd: rawnand: vf610_nfc: fix false bitflips on reads of erased pages Greg Kroah-Hartman
` (645 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Yi Yang, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yi Yang <yiyang13@huawei.com>
[ Upstream commit 226bd5603371cd9f6642cbb9e9a677f445de3530 ]
The reload of 'vc' added by commit 8fb9ea65c9d1 ("vc_screen: reload load
of struct vc_data pointer in vcs_write() to avoid UAF") sits after the
'if (ret)' block, so the copy-failure break path exits the loop without
reloading vc. If the vc was kfree()'d via vc_port_destruct during the
unlocked copy_from_user() window, the post-loop
'if (written && vc) vcs_scr_updated(vc)' is reached with a stale
non-NULL vc. The '&& vc' guard from commit a287620312dc ("vc_screen:
fix null-ptr-deref in vcs_notifier() during concurrent vcs_write") only
handles the NULL case, not this stale-non-NULL case; vcs_notifier() then
reads param->vc->vc_num from freed memory:
BUG: KASAN: slab-use-after-free in vcs_notifier+0x7c/0xd0
Read of size 2 at addr ffff888007149190
Call Trace:
vcs_notifier+0x7c/0xd0
atomic_notifier_call_chain+0x70/0xa0
vcs_scr_updated+0x77/0xa0
vcs_write+0x71b/0x7e0
Allocated by task: vc_allocate -> con_install -> tty_open
Freed by task: kfree <- vt_ioctl (VT_DISALLOCATE -> vc_port_destruct)
Move the reload to immediately after console_lock(), before 'if (ret)',
so every break path below passes a fresh vc to the post-loop
vcs_scr_updated().
Fixes: a287620312dc ("vc_screen: fix null-ptr-deref in vcs_notifier() during concurrent vcs_write")
Cc: stable@kernel.org
Signed-off-by: Yi Yang <yiyang13@huawei.com>
Link: https://patch.msgid.link/20260901113131.2760010-1-yiyang13@huawei.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: Adapted the direct -ENXIO return to set ret and jump to unlock_out. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/vt/vc_screen.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 27b44dc123859..22735ca14395a 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -643,6 +643,19 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
ret = copy_from_user(con_buf, buf, this_round);
console_lock();
+ /* The vc might have been freed or vcs_size might have changed
+ * while we slept to grab the user buffer; recheck here, before
+ * if (ret), so every break path below passes a fresh vc to the
+ * post-loop vcs_scr_updated(). Return data written so far.
+ */
+ vc = vcs_vc(inode, &viewed);
+ if (!vc) {
+ if (written)
+ break;
+ ret = -ENXIO;
+ goto unlock_out;
+ }
+
if (ret) {
this_round -= ret;
if (!this_round) {
@@ -655,18 +668,6 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
goto unlock_out;
}
}
-
- /* The vc might have been freed or vcs_size might have changed
- * while we slept to grab the user buffer, so recheck.
- * Return data written up to now on failure.
- */
- vc = vcs_vc(inode, &viewed);
- if (!vc) {
- if (written)
- break;
- ret = -ENXIO;
- goto unlock_out;
- }
size = vcs_size(vc, attr, false);
if (size < 0) {
if (written)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0354/1887] mtd: rawnand: vf610_nfc: fix false bitflips on reads of erased pages
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (352 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0353/1887] vc_screen: reload vc pointer before if (ret) in vcs_write() to avoid UAF Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0355/1887] tcp: introduce icsk->icsk_keepalive_timer Greg Kroah-Hartman
` (644 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edward Karpicz, Mehmet Fide,
Miquel Raynal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
[ Upstream commit 68fe2faf5c69d0e21f94cd695d28f0ba677d484f ]
When the ECC engine fails to decode a page, the driver re-reads the OOB
area with the engine bypassed, but runs the erased-page check for the
data area on the buffer left in the controller SRAM by the failed
transfer.
That buffer does not hold what is on the flash: the failing engine
writes a bogus single-bit "correction" into it. In the 60-byte ECC mode
the all-0xff content of an erased page always decodes to the same error
location, so every erased page shows one stale zero bit at data offset
0x5FD, which the erased-page check then reports as a corrected bitflip.
Edward Karpicz discovered this behaviour and identified the offset on a
Colibri VF61; the analysis and the fix build on his finding. Measured
with an instrumented driver on a Colibri VF50 (MX30LF1G18AC, 32-bit
ECC): reading a 126 MiB partition with nanddump increased the corrected
counter by 18035, exactly one per erased page, while raw reads of the
same pages return clean 0xff. A v4.4 kernel on the VF61 (MX30LF4G28AC)
accumulates the same false counts, so the behaviour follows the
controller rather than the chip or the driver generation. Neither the
Vybrid reference manual nor the published mask set errata (VFXXX_2N02G)
document it. The 45-byte ECC mode is not affected.
Restoring the known byte is not enough: on pages that fail to decode
with content other than all-0xff the engine writes its correction
wherever the syndrome points (measured at a different offset on such a
page), so the check has to run on what the flash holds. Re-read the data
area with the ECC engine bypassed, exactly as already done for the OOB
area. The corrected counter then stays at zero on both boards.
Reported-by: Edward Karpicz <webmaster@toradex.com>
Link: https://community.toradex.com/t/colibri-vf50-vf61-on-the-current-bsp-mainline-u-boot-v2026-07-and-linux-6-18-lts/30735
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/raw/vf610_nfc.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
index 262dfcb24c9a4..391fff6357472 100644
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -518,6 +518,7 @@ static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat,
u8 ecc_status;
u8 ecc_count;
int flips_threshold = nfc->chip.ecc.strength / 2;
+ int ret;
ecc_status = vf610_nfc_read(nfc, ecc_status_off) & 0xff;
ecc_count = ecc_status & ECC_STATUS_ERR_COUNT;
@@ -525,15 +526,21 @@ static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat,
if (!(ecc_status & ECC_STATUS_MASK))
return ecc_count;
+ /* The failed decode leaves a bogus correction in SRAM; re-read without ECC */
nfc->data_access = true;
- nand_read_oob_op(&nfc->chip, page, 0, oob, vf610_nfc_spare_size(mtd));
+ ret = nand_read_page_op(&nfc->chip, page, 0, dat, mtd->writesize);
+ if (!ret)
+ ret = nand_read_oob_op(&nfc->chip, page, 0, oob,
+ vf610_nfc_spare_size(mtd));
nfc->data_access = false;
+ if (ret)
+ return ret;
/*
- * On an erased page, bit count (including OOB) should be zero or
- * at least less then half of the ECC strength.
+ * Run the erased-page check with the driver's historic threshold
+ * of half the ECC strength.
*/
- return nand_check_erased_ecc_chunk(dat, nfc->chip.ecc.size, oob,
+ return nand_check_erased_ecc_chunk(dat, mtd->writesize, oob,
vf610_nfc_spare_size(mtd), NULL, 0,
flips_threshold);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0355/1887] tcp: introduce icsk->icsk_keepalive_timer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (353 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0354/1887] mtd: rawnand: vf610_nfc: fix false bitflips on reads of erased pages Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0356/1887] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
` (643 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 08dfe370239e53494453cee1e2ded2cdaa1efd12 ]
sk->sk_timer has been used for TCP keepalives.
Keepalive timers are not in fast path, we want to use sk->sk_timer
storage for retransmit timers, for better cache locality.
Create icsk->icsk_keepalive_timer and change keepalive
code to no longer use sk->sk_timer.
Added space is reclaimed in the following patch.
This includes changes to MPTCP, which was also using sk_timer.
Alias icsk->mptcp_tout_timer and icsk->icsk_keepalive_timer
for inet_sk_diag_fill() sake.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20251124175013.1473655-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Backport to 6.1 as a dependency of 85c580b0d859 ("mptcp: prevent
race between disconnect() and rtx"):
Keep icsk_timeout and the existing TCP retransmit timer. Update the
existing inet_csk keepalive helpers in inet_connection_sock.c instead
of introducing the newer TCP helpers, and use from_timer() in the
callbacks. Adjust the DCCP callback, since DCCP still shares the inet_csk
timer setup in this branch. Omit the absent net_cachelines document.
Also alias sk_timer as mptcp_retransmit_timer and move all MPTCP
retransmit timer users there. The target directly stops this timer and
the new mptcp_tout_timer, so both names must identify the timers actually
in use. Initialize the MPTCP icsk_rto_min to this branch's TCP_RTO_MIN so
the target restores a valid retransmit interval during disconnect.
No functions are added.
[ sashal: Reduced backport -- upstream 08dfe370239e5 touches 11 file(s), this
backport carries 12. Not backported here:
Documentation/networking/net_cachelines/inet_connection_sock.rst
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: 85c580b0d859 ("mptcp: prevent race between disconnect() and rtx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/inet_connection_sock.h | 11 ++++++--
include/net/sock.h | 6 +++-
net/dccp/timer.c | 4 ++-
net/ipv4/inet_connection_sock.c | 10 +++----
net/ipv4/inet_diag.c | 4 +--
net/ipv4/tcp_ipv4.c | 4 +--
net/ipv4/tcp_timer.c | 5 ++--
net/ipv6/tcp_ipv6.c | 4 +--
net/mptcp/protocol.c | 28 +++++++++----------
net/mptcp/protocol.h | 2 +-
.../selftests/bpf/progs/bpf_iter_tcp4.c | 4 +--
.../selftests/bpf/progs/bpf_iter_tcp6.c | 4 +--
12 files changed, 49 insertions(+), 37 deletions(-)
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 9760ba0516b6c..51be99667a23c 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -63,6 +63,9 @@ struct inet_connection_sock_af_ops {
* @icsk_bind2_hash: Bind node in the bhash2 table
* @icsk_timeout: Timeout
* @icsk_retransmit_timer: Resend (no ack)
+ * @icsk_delack_timer: Delayed ACK timer
+ * @icsk_keepalive_timer: Keepalive timer
+ * @mptcp_tout_timer: MPTCP timeout timer
* @icsk_rto: Retransmit timeout
* @icsk_pmtu_cookie Last pmtu seen by socket
* @icsk_ca_ops Pluggable congestion control hook
@@ -89,8 +92,12 @@ struct inet_connection_sock {
struct inet_bind_bucket *icsk_bind_hash;
struct inet_bind2_bucket *icsk_bind2_hash;
unsigned long icsk_timeout;
- struct timer_list icsk_retransmit_timer;
- struct timer_list icsk_delack_timer;
+ struct timer_list icsk_retransmit_timer;
+ struct timer_list icsk_delack_timer;
+ union {
+ struct timer_list icsk_keepalive_timer;
+ struct timer_list mptcp_tout_timer;
+ };
__u32 icsk_rto;
__u32 icsk_rto_min;
__u32 icsk_delack_max;
diff --git a/include/net/sock.h b/include/net/sock.h
index d195cddb8559b..4006584514f24 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -315,6 +315,7 @@ struct sk_filter;
* @sk_txrehash: enable TX hash rethink
* @sk_filter: socket filtering instructions
* @sk_timer: sock cleanup timer
+ * @mptcp_retransmit_timer: MPTCP retransmit timer
* @sk_stamp: time stamp of last packet received
* @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only
* @sk_tsflags: SO_TIMESTAMPING flags
@@ -459,7 +460,10 @@ struct sock {
__u32 sk_dst_pending_confirm;
u32 sk_pacing_status; /* see enum sk_pacing */
long sk_sndtimeo;
- struct timer_list sk_timer;
+ union {
+ struct timer_list sk_timer;
+ struct timer_list mptcp_retransmit_timer;
+ };
__u32 sk_priority;
__u32 sk_mark;
unsigned long sk_pacing_rate; /* bytes per second */
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 27a3b37acd2ef..ff9c0184e3f68 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -160,7 +160,9 @@ static void dccp_write_timer(struct timer_list *t)
static void dccp_keepalive_timer(struct timer_list *t)
{
- struct sock *sk = from_timer(sk, t, sk_timer);
+ struct inet_connection_sock *icsk =
+ from_timer(icsk, t, icsk_keepalive_timer);
+ struct sock *sk = &icsk->icsk_inet.sk;
pr_err("dccp should not use a keepalive timer !\n");
sock_put(sk);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 6184534aa1bf5..5e31302b42505 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -749,7 +749,7 @@ void inet_csk_init_xmit_timers(struct sock *sk,
timer_setup(&icsk->icsk_retransmit_timer, retransmit_handler, 0);
timer_setup(&icsk->icsk_delack_timer, delack_handler, 0);
- timer_setup(&sk->sk_timer, keepalive_handler, 0);
+ timer_setup(&icsk->icsk_keepalive_timer, keepalive_handler, 0);
icsk->icsk_pending = icsk->icsk_ack.pending = 0;
}
EXPORT_SYMBOL(inet_csk_init_xmit_timers);
@@ -762,7 +762,7 @@ void inet_csk_clear_xmit_timers(struct sock *sk)
sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
sk_stop_timer(sk, &icsk->icsk_delack_timer);
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_stop_timer(sk, &icsk->icsk_keepalive_timer);
}
EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
@@ -777,18 +777,18 @@ void inet_csk_clear_xmit_timers_sync(struct sock *sk)
sk_stop_timer_sync(sk, &icsk->icsk_retransmit_timer);
sk_stop_timer_sync(sk, &icsk->icsk_delack_timer);
- sk_stop_timer_sync(sk, &sk->sk_timer);
+ sk_stop_timer_sync(sk, &icsk->icsk_keepalive_timer);
}
void inet_csk_delete_keepalive_timer(struct sock *sk)
{
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_stop_timer(sk, &inet_csk(sk)->icsk_keepalive_timer);
}
EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
{
- sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
+ sk_reset_timer(sk, &inet_csk(sk)->icsk_keepalive_timer, jiffies + len);
}
EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 2bd5d0ed7a6fc..02d8a63f39ebf 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -310,11 +310,11 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
r->idiag_retrans = icsk->icsk_probes_out;
r->idiag_expires =
jiffies_delta_to_msecs(icsk->icsk_timeout - jiffies);
- } else if (timer_pending(&sk->sk_timer)) {
+ } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
r->idiag_timer = 2;
r->idiag_retrans = icsk->icsk_probes_out;
r->idiag_expires =
- jiffies_delta_to_msecs(sk->sk_timer.expires - jiffies);
+ jiffies_delta_to_msecs(icsk->icsk_keepalive_timer.expires - jiffies);
}
if ((ext & (1 << (INET_DIAG_INFO - 1))) && handler->idiag_info_size) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9c5d227b749c4..dc92f20942957 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2647,9 +2647,9 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i)
} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
timer_active = 4;
timer_expires = icsk->icsk_timeout;
- } else if (timer_pending(&sk->sk_timer)) {
+ } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
timer_active = 2;
- timer_expires = sk->sk_timer.expires;
+ timer_expires = icsk->icsk_keepalive_timer.expires;
} else {
timer_active = 0;
timer_expires = jiffies;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 3662b49ce71ae..d086026018d62 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -706,8 +706,9 @@ EXPORT_SYMBOL_GPL(tcp_set_keepalive);
static void tcp_keepalive_timer (struct timer_list *t)
{
- struct sock *sk = from_timer(sk, t, sk_timer);
- struct inet_connection_sock *icsk = inet_csk(sk);
+ struct inet_connection_sock *icsk =
+ from_timer(icsk, t, icsk_keepalive_timer);
+ struct sock *sk = &icsk->icsk_inet.sk;
struct tcp_sock *tp = tcp_sk(sk);
u32 elapsed;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index ec668c19cb976..9e199a2a43ef1 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2001,9 +2001,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
timer_active = 4;
timer_expires = icsk->icsk_timeout;
- } else if (timer_pending(&sp->sk_timer)) {
+ } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
timer_active = 2;
- timer_expires = sp->sk_timer.expires;
+ timer_expires = icsk->icsk_keepalive_timer.expires;
} else {
timer_active = 0;
timer_expires = jiffies;
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 10be901f8c026..593d196dfa8bb 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -426,9 +426,7 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
static void mptcp_stop_rtx_timer(struct sock *sk)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
-
- sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+ sk_stop_timer(sk, &sk->mptcp_retransmit_timer);
mptcp_sk(sk)->timer_ival = 0;
}
@@ -976,12 +974,11 @@ static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list
static bool mptcp_rtx_timer_pending(struct sock *sk)
{
- return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
+ return timer_pending(&sk->mptcp_retransmit_timer);
}
static void mptcp_reset_rtx_timer(struct sock *sk)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
unsigned long tout;
/* prevent rescheduling on close */
@@ -989,7 +986,7 @@ static void mptcp_reset_rtx_timer(struct sock *sk)
return;
tout = mptcp_sk(sk)->timer_ival;
- sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
+ sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout);
}
bool mptcp_schedule_work(struct sock *sk)
@@ -2349,9 +2346,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
static void mptcp_retransmit_timer(struct timer_list *t)
{
- struct inet_connection_sock *icsk = from_timer(icsk, t,
- icsk_retransmit_timer);
- struct sock *sk = &icsk->icsk_inet.sk;
+ struct sock *sk = from_timer(sk, t, mptcp_retransmit_timer);
struct mptcp_sock *msk = mptcp_sk(sk);
bh_lock_sock(sk);
@@ -2369,7 +2364,9 @@ static void mptcp_retransmit_timer(struct timer_list *t)
static void mptcp_tout_timer(struct timer_list *t)
{
- struct sock *sk = from_timer(sk, t, sk_timer);
+ struct inet_connection_sock *icsk =
+ from_timer(icsk, t, mptcp_tout_timer);
+ struct sock *sk = &icsk->icsk_inet.sk;
mptcp_schedule_work(sk);
sock_put(sk);
@@ -2801,7 +2798,7 @@ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)
*/
timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout;
- sk_reset_timer(sk, &sk->sk_timer, timeout);
+ sk_reset_timer(sk, &inet_csk(sk)->mptcp_tout_timer, timeout);
}
static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
@@ -2919,6 +2916,8 @@ static int __mptcp_init_sock(struct sock *sk)
msk->first_pending = NULL;
msk->rmem_fwd_alloc = 0;
WRITE_ONCE(msk->rmem_released, 0);
+ /* MPTCP sockets do not go through tcp_init_sock(). */
+ inet_csk(sk)->icsk_rto_min = TCP_RTO_MIN;
msk->timer_ival = TCP_RTO_MIN;
WRITE_ONCE(msk->first, NULL);
@@ -2931,9 +2930,8 @@ static int __mptcp_init_sock(struct sock *sk)
mptcp_pm_data_init(msk);
spin_lock_init(&msk->fallback_lock);
- /* re-use the csk retrans timer for MPTCP-level retrans */
- timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
- timer_setup(&sk->sk_timer, mptcp_tout_timer, 0);
+ timer_setup(&sk->mptcp_retransmit_timer, mptcp_retransmit_timer, 0);
+ timer_setup(&msk->sk.mptcp_tout_timer, mptcp_tout_timer, 0);
return 0;
}
@@ -3110,7 +3108,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
might_sleep();
mptcp_stop_rtx_timer(sk);
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_stop_timer(sk, &inet_csk(sk)->mptcp_tout_timer);
msk->pm.status = 0;
sk->sk_prot->destroy(sk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 1de257b868399..716a6947fba74 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -698,7 +698,7 @@ static inline void mptcp_stop_tout_timer(struct sock *sk)
if (!inet_csk(sk)->icsk_mtup.probe_timestamp)
return;
- sk_stop_timer(sk, &sk->sk_timer);
+ sk_stop_timer(sk, &inet_csk(sk)->mptcp_tout_timer);
inet_csk(sk)->icsk_mtup.probe_timestamp = 0;
}
diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c b/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
index 92267abb462fc..be540970fcc1f 100644
--- a/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
+++ b/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
@@ -103,9 +103,9 @@ static int dump_tcp_sock(struct seq_file *seq, struct tcp_sock *tp,
} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
timer_active = 4;
timer_expires = icsk->icsk_timeout;
- } else if (timer_pending(&sp->sk_timer)) {
+ } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
timer_active = 2;
- timer_expires = sp->sk_timer.expires;
+ timer_expires = icsk->icsk_keepalive_timer.expires;
} else {
timer_active = 0;
timer_expires = bpf_jiffies64();
diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c b/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c
index 943f7bba180e7..9f72398fc3cc3 100644
--- a/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c
+++ b/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c
@@ -103,9 +103,9 @@ static int dump_tcp6_sock(struct seq_file *seq, struct tcp6_sock *tp,
} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
timer_active = 4;
timer_expires = icsk->icsk_timeout;
- } else if (timer_pending(&sp->sk_timer)) {
+ } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
timer_active = 2;
- timer_expires = sp->sk_timer.expires;
+ timer_expires = icsk->icsk_keepalive_timer.expires;
} else {
timer_active = 0;
timer_expires = bpf_jiffies64();
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0356/1887] mptcp: prevent race between disconnect() and rtx
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (354 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0355/1887] tcp: introduce icsk->icsk_keepalive_timer Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0357/1887] smb: client: split cifsFileInfo bitfields to avoid shared-byte RMW races Greg Kroah-Hartman
` (642 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <pabeni@redhat.com>
[ Upstream commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e ]
Sashiko noted that the two event can race, leading to inconsistent
status. Prevent the race using the synchronous timer stop operation.
Cc: stable@vger.kernel.org
Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ sashal: Use TCP_RTO_MIN for msk->timer_ival instead of
icsk->icsk_rto_min, as ea4eb2adb0d3 ("mptcp: honour configured
min/max RTO in retransmit paths") is not in this tree. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/protocol.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 593d196dfa8bb..5d6dff88bf209 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3269,6 +3269,7 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
static int mptcp_disconnect(struct sock *sk, int flags)
{
+ struct inet_connection_sock *icsk = inet_csk(sk);
struct mptcp_sock *msk = mptcp_sk(sk);
/* We are on the fastopen error path. We can't call straight into the
@@ -3281,8 +3282,13 @@ static int mptcp_disconnect(struct sock *sk, int flags)
mptcp_check_listen_stop(sk);
inet_sk_state_store(sk, TCP_CLOSE);
- mptcp_stop_rtx_timer(sk);
- mptcp_stop_tout_timer(sk);
+ /* The later subflow close can not kick again the tout timer,
+ * as the msk is already in closed status.
+ */
+ msk->timer_ival = TCP_RTO_MIN;
+ sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer);
+ icsk->icsk_mtup.probe_timestamp = 0;
+ sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer);
if (mptcp_sk(sk)->token)
mptcp_event(MPTCP_EVENT_CLOSED, mptcp_sk(sk), NULL, GFP_KERNEL);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0357/1887] smb: client: split cifsFileInfo bitfields to avoid shared-byte RMW races
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (355 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0356/1887] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0358/1887] wifi: wlcore: Convert to platform remove callback returning void Greg Kroah-Hartman
` (641 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
[ Upstream commit 19465a9aeb664f1d710d0d22c07c31bfb7c85446 ]
The invalidHandle, swapfile, oplock_break_cancelled, offload,
and status_file_deleted fields are stored in the same bitfield byte
in struct cifsFileInfo, but are updated in different code paths that
may run simultaneously, and are protected by different locks. Since
bitfield assignments generate byte-level read-modify-write operations,
a modification to one flag can overwrite a concurrent modification to
another flag.
To avoid these races, convert these flags from a bitfield to
separate bool fields.
Closes: https://lore.kernel.org/r/7689764e-c0f6-4016-9557-b54cf4a3de4e@redhat.com
Fixes: 3bc303c254335 ("cifs: convert oplock breaks to use slow_work facility (try #4)")
Fixes: 4e8aea30f7751 ("smb3: enable swap on SMB3 mounts")
Fixes: ffceb7640cbfe ("smb: client: do not defer close open handles to deleted files")
Fixes: 173217bd73365 ("smb3: retrying on failed server close")
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Cc: stable@vger.kernel.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
(cherry picked from commit 19465a9aeb664f1d710d0d22c07c31bfb7c85446)
[ status_file_deleted not present in kernel 6.1 ]
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index a5e9f79c10f90..c37f10eedddf2 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1337,10 +1337,10 @@ struct cifsFileInfo {
struct dentry *dentry;
struct tcon_link *tlink;
unsigned int f_flags;
- bool invalidHandle:1; /* file closed via session abend */
- bool swapfile:1;
- bool oplock_break_cancelled:1;
- bool offload:1; /* offload final part of _put to a wq */
+ bool invalidHandle; /* file closed via session abend */
+ bool swapfile;
+ bool oplock_break_cancelled;
+ bool offload; /* offload final part of _put to a wq */
__u16 oplock_epoch; /* epoch from the lease break */
__u32 oplock_level; /* oplock/lease level from the lease break */
int count;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0358/1887] wifi: wlcore: Convert to platform remove callback returning void
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (356 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0357/1887] smb: client: split cifsFileInfo bitfields to avoid shared-byte RMW races Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0359/1887] wifi: wlcore: Fix runtime PM leak in wlcore_remove() Greg Kroah-Hartman
` (640 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König, Kalle Valo,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit f00928012886a07ca6817ea70eb4856ce280ce05 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is (mostly) ignored
and this typically results in resource leaks. To improve here there is a
quest to make the remove callback return void. In the first step of this
quest all drivers are converted to .remove_new() which already returns
void.
wlcore_remove() returned zero unconditionally. With that converted to
return void instead, the wl12xx and wl18xx driver can be converted to
.remove_new trivially.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230912171249.755901-1-u.kleine-koenig@pengutronix.de
Stable-dep-of: a8b8881d0c1a ("wifi: wlcore: Fix runtime PM leak in wlcore_remove()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ti/wl12xx/main.c | 6 +++---
drivers/net/wireless/ti/wl18xx/main.c | 2 +-
drivers/net/wireless/ti/wlcore/main.c | 6 ++----
drivers/net/wireless/ti/wlcore/wlcore.h | 2 +-
4 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index d06a2c4194479..de045fe4ca1eb 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1919,7 +1919,7 @@ static int wl12xx_probe(struct platform_device *pdev)
return ret;
}
-static int wl12xx_remove(struct platform_device *pdev)
+static void wl12xx_remove(struct platform_device *pdev)
{
struct wl1271 *wl = platform_get_drvdata(pdev);
struct wl12xx_priv *priv;
@@ -1928,7 +1928,7 @@ static int wl12xx_remove(struct platform_device *pdev)
kfree(priv->rx_mem_addr);
- return wlcore_remove(pdev);
+ wlcore_remove(pdev);
}
static const struct platform_device_id wl12xx_id_table[] = {
@@ -1939,7 +1939,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
static struct platform_driver wl12xx_driver = {
.probe = wl12xx_probe,
- .remove = wl12xx_remove,
+ .remove_new = wl12xx_remove,
.id_table = wl12xx_id_table,
.driver = {
.name = "wl12xx_driver",
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 0b3cf8477c6cd..d4a89401f2c47 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -2033,7 +2033,7 @@ MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
static struct platform_driver wl18xx_driver = {
.probe = wl18xx_probe,
- .remove = wlcore_remove,
+ .remove_new = wlcore_remove,
.id_table = wl18xx_id_table,
.driver = {
.name = "wl18xx_driver",
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 2c3f7fbd04330..b5ae25e7ed897 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -6734,7 +6734,7 @@ int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(wlcore_probe);
-int wlcore_remove(struct platform_device *pdev)
+void wlcore_remove(struct platform_device *pdev)
{
struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
struct wl1271 *wl = platform_get_drvdata(pdev);
@@ -6749,7 +6749,7 @@ int wlcore_remove(struct platform_device *pdev)
if (pdev_data->family && pdev_data->family->nvs_name)
wait_for_completion(&wl->nvs_loading_complete);
if (!wl->initialized)
- return 0;
+ return;
if (wl->wakeirq >= 0) {
dev_pm_clear_wake_irq(wl->dev);
@@ -6769,8 +6769,6 @@ int wlcore_remove(struct platform_device *pdev)
free_irq(wl->irq, wl);
wlcore_free_hw(wl);
-
- return 0;
}
EXPORT_SYMBOL_GPL(wlcore_remove);
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 81c94d390623b..1f8511bf9bb35 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -497,7 +497,7 @@ struct wl1271 {
};
int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
-int wlcore_remove(struct platform_device *pdev);
+void wlcore_remove(struct platform_device *pdev);
struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
u32 mbox_size);
int wlcore_free_hw(struct wl1271 *wl);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0359/1887] wifi: wlcore: Fix runtime PM leak in wlcore_remove()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (357 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0358/1887] wifi: wlcore: Convert to platform remove callback returning void Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0360/1887] net: usb: qmi_wwan: add Quectel EG120K-EA Greg Kroah-Hartman
` (639 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
[ Upstream commit a8b8881d0c1aff544fae190469d86db7b07f43a9 ]
pm_runtime_get_sync() keeps the runtime PM usage counter elevated even
when it returns an error, so the reference taken at the beginning of
wlcore_remove() has to be dropped on every exit path. When the device
was not initialized the function returned early without doing so,
leaking the reference.
Release it with pm_runtime_put_noidle() as done on the other early error
paths of this driver.
Fixes: fa2648a34e73f ("wlcore: Add support for runtime PM")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917122325.2150910-1-vulab@iscas.ac.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ti/wlcore/main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b5ae25e7ed897..ec3eaf788abf5 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -6748,8 +6748,10 @@ void wlcore_remove(struct platform_device *pdev)
if (pdev_data->family && pdev_data->family->nvs_name)
wait_for_completion(&wl->nvs_loading_complete);
- if (!wl->initialized)
+ if (!wl->initialized) {
+ pm_runtime_put_noidle(wl->dev);
return;
+ }
if (wl->wakeirq >= 0) {
dev_pm_clear_wake_irq(wl->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0360/1887] net: usb: qmi_wwan: add Quectel EG120K-EA
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (358 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0359/1887] wifi: wlcore: Fix runtime PM leak in wlcore_remove() Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0361/1887] serial: imx: Convert to platform remove callback returning void Greg Kroah-Hartman
` (638 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gilberto Conde, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gilberto Conde <gilbertorconde@gmail.com>
commit 0f2fd31f63c65c409bd336af3a42d478a9207c1f upstream.
Add support for the Quectel EG120K-EA LTE Cat.12 module (USB ID
2c7c:030b). Its QMI interface (interface 4) uses class/subclass/protocol
ff/ff/ff like the other recent Quectel modules, so match it the same way.
The product ID is shared with the EM060K, which the option driver
already knows and uses to claim the serial interfaces. Without a
qmi_wwan entry the data interface is left unbound.
Tested on a GL.iNet GL-X2000, where the module is soldered down and
enumerates at SuperSpeed: cdc-wdm0 and wwan0 appear and ModemManager
brings up a data session.
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0
D: Ver= 3.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1
P: Vendor=2c7c ProdID=030b Rev= 5.04
S: Manufacturer=Quectel
S: Product=EG120K-EA
S: SerialNumber=45546267
C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option
E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
I:* If#=12 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E: Ad=89(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
Signed-off-by: Gilberto Conde <gilbertorconde@gmail.com>
Link: https://patch.msgid.link/20260921093426.2870266-1-gilbertorconde@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1092,6 +1092,7 @@ static const struct usb_device_id produc
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */
+ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x030b)}, /* Quectel EM060K/EG120K-EA */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0361/1887] serial: imx: Convert to platform remove callback returning void
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (359 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0360/1887] net: usb: qmi_wwan: add Quectel EG120K-EA Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0362/1887] serial: imx: serialize imx_uart_ports[] lifetime Greg Kroah-Hartman
` (637 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit c066f87314b7fbbf4d72d38957436a98e7b7e503 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20231110152927.70601-18-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 8b0b29fdcb47 ("serial: imx: serialize imx_uart_ports[] lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/imx.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2534,13 +2534,11 @@ err_clk:
return ret;
}
-static int imx_uart_remove(struct platform_device *pdev)
+static void imx_uart_remove(struct platform_device *pdev)
{
struct imx_port *sport = platform_get_drvdata(pdev);
uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
-
- return 0;
}
static void imx_uart_restore_context(struct imx_port *sport)
@@ -2709,7 +2707,7 @@ static const struct dev_pm_ops imx_uart_
static struct platform_driver imx_uart_platform_driver = {
.probe = imx_uart_probe,
- .remove = imx_uart_remove,
+ .remove_new = imx_uart_remove,
.driver = {
.name = "imx-uart",
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0362/1887] serial: imx: serialize imx_uart_ports[] lifetime
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (360 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0361/1887] serial: imx: Convert to platform remove callback returning void Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:40 ` [PATCH 6.1 0363/1887] usb: gadget: at91_udc: Convert to platform remove callback returning void Greg Kroah-Hartman
` (636 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Karl Mehltretter, Frank Li,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 8b0b29fdcb47907ae0296b8fe829e918e05e300f ]
imx_uart_probe() publishes its devm-allocated port in imx_uart_ports[]
before uart_add_one_port() because console setup uses the table. The entry
is not cleared when adding the port fails or after removal, leaving a
dangling pointer.
A sibling probe can register the shared console through that stale entry.
This was reproduced under KASAN on QEMU mcimx6ul-evk by unbinding a
sibling UART, unbinding the console UART and rebinding the sibling.
Keep the entry valid through uart_remove_one_port(), then clear it. Protect
port addition and removal together with their table updates so sibling
operations cannot interleave. Reject an occupied slot rather than
clobbering an active port during a duplicate-line probe.
Fixes: dbff4e9ea2e8 ("IMX UART: remove statically initialized tables")
Fixes: 9f322ad064f9 ("imx: serial: handle initialisation failure correctly")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/all/20260719162850.043B41F000E9@smtp.kernel.org
Link: https://lore.kernel.org/all/20260719222501.CB4CB1F000E9@smtp.kernel.org
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260731181844.11330-6-kmehltretter@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/imx.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/ktime.h>
+#include <linux/mutex.h>
#include <linux/pinctrl/consumer.h>
#include <linux/rational.h>
#include <linux/slab.h>
@@ -2037,6 +2038,9 @@ static const struct uart_ops imx_uart_po
static struct imx_port *imx_uart_ports[UART_NR];
+/* Held across uart_add/remove_one_port(); console callbacks must not take it. */
+static DEFINE_MUTEX(imx_uart_ports_lock);
+
#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
static void imx_uart_console_putchar(struct uart_port *port, unsigned char ch)
{
@@ -2522,11 +2526,19 @@ static int imx_uart_probe(struct platfor
}
}
- imx_uart_ports[sport->port.line] = sport;
-
platform_set_drvdata(pdev, sport);
- ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port);
+ scoped_guard(mutex, &imx_uart_ports_lock) {
+ if (imx_uart_ports[sport->port.line]) {
+ ret = -EBUSY;
+ } else {
+ imx_uart_ports[sport->port.line] = sport;
+ ret = uart_add_one_port(&imx_uart_uart_driver,
+ &sport->port);
+ if (ret)
+ imx_uart_ports[sport->port.line] = NULL;
+ }
+ }
err_clk:
clk_disable_unprepare(sport->clk_ipg);
@@ -2538,7 +2550,9 @@ static void imx_uart_remove(struct platf
{
struct imx_port *sport = platform_get_drvdata(pdev);
+ guard(mutex)(&imx_uart_ports_lock);
uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+ imx_uart_ports[sport->port.line] = NULL;
}
static void imx_uart_restore_context(struct imx_port *sport)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0363/1887] usb: gadget: at91_udc: Convert to platform remove callback returning void
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (361 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0362/1887] serial: imx: serialize imx_uart_ports[] lifetime Greg Kroah-Hartman
@ 2026-10-28 16:40 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0364/1887] usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed Greg Kroah-Hartman
` (635 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:40 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit cbd1b152519a581bfe14fb6b14ea6e57cca426c1 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().
In the error path emit an error message replacing the (less useful)
message by the core. Apart from the improved error message there is no
change in behaviour.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20231120215830.71071-2-u.kleine-koenig@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: c27d13ce4bab ("usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/udc/at91_udc.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -1927,7 +1927,7 @@ err_unprepare_fclk:
return retval;
}
-static int at91udc_remove(struct platform_device *pdev)
+static void at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
unsigned long flags;
@@ -1935,8 +1935,11 @@ static int at91udc_remove(struct platfor
DBG("remove\n");
usb_del_gadget_udc(&udc->gadget);
- if (udc->driver)
- return -EBUSY;
+ if (udc->driver) {
+ dev_err(&pdev->dev,
+ "Driver still in use but removing anyhow\n");
+ return;
+ }
spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 0);
@@ -1946,8 +1949,6 @@ static int at91udc_remove(struct platfor
remove_debug_file(udc);
clk_unprepare(udc->fclk);
clk_unprepare(udc->iclk);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -2003,7 +2004,7 @@ static int at91udc_resume(struct platfor
#endif
static struct platform_driver at91_udc_driver = {
- .remove = at91udc_remove,
+ .remove_new = at91udc_remove,
.shutdown = at91udc_shutdown,
.suspend = at91udc_suspend,
.resume = at91udc_resume,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0364/1887] usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (362 preceding siblings ...)
2026-10-28 16:40 ` [PATCH 6.1 0363/1887] usb: gadget: at91_udc: Convert to platform remove callback returning void Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0365/1887] USB: gadget: ffs: fix mm lifetime handling Greg Kroah-Hartman
` (634 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit c27d13ce4bab80fbdf6523928071b6c24b37606c ]
In polled-VBUS mode (board.vbus_pin && board.vbus_polled), probe arms a
self-restarting cycle: at91_vbus_timer() schedules vbus_timer_work, and
at91_vbus_timer_work() calls at91_vbus_update() and re-arms the timer via
mod_timer(). Both recover the same udc through container_of and dereference
it on every iteration.
Neither teardown path cancels this cycle. udc is devm-allocated, so it is
freed after at91udc_remove() returns, and is likewise freed when probe
fails and devres runs. A timer callback or work item that is pending or
running at either point dereferences the freed udc.
Add at91_udc_shutdown_vbus_timer() and call it from at91udc_remove() and
from the usb_add_gadget_udc() failure path in probe; the remaining probe
error paths fail before the timer is armed. timer_shutdown_sync() waits
for a running callback and clears timer->function, which makes the work
handler's mod_timer() a permanent no-op; cancel_work_sync() then drains
any pending or running work whose re-arm attempt now does nothing. The
timer must be shut down first, since cancelling the work alone would let
the timer re-queue it. The guard mirrors probe: in IRQ mode the timer and
work_struct are never initialized.
This does not require a fault; a normal driver unbind can interleave with
an already queued work item.
This issue was found by an in-house static analysis tool.
Fixes: 4037242c4f5f ("ARM: 6209/3: at91_udc: Add vbus polarity and polling mode")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260719042839.3167094-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/udc/at91_udc.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -1796,6 +1796,19 @@ static void at91udc_of_init(struct at91_
udc->caps = match->data;
}
+/*
+ * The work handler re-arms this timer, so shut the timer down before
+ * draining the work; otherwise it restarts the polling cycle.
+ */
+static void at91_udc_shutdown_vbus_timer(struct at91_udc *udc)
+{
+ if (!(udc->board.vbus_pin && udc->board.vbus_polled))
+ return;
+
+ timer_shutdown_sync(&udc->vbus_timer);
+ cancel_work_sync(&udc->vbus_timer_work);
+}
+
static int at91udc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1909,7 +1922,7 @@ static int at91udc_probe(struct platform
}
retval = usb_add_gadget_udc(dev, &udc->gadget);
if (retval)
- goto err_unprepare_iclk;
+ goto err_shutdown_vbus;
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
@@ -1917,6 +1930,8 @@ static int at91udc_probe(struct platform
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
return 0;
+err_shutdown_vbus:
+ at91_udc_shutdown_vbus_timer(udc);
err_unprepare_iclk:
clk_unprepare(udc->iclk);
err_unprepare_fclk:
@@ -1935,6 +1950,9 @@ static void at91udc_remove(struct platfo
DBG("remove\n");
usb_del_gadget_udc(&udc->gadget);
+
+ at91_udc_shutdown_vbus_timer(udc);
+
if (udc->driver) {
dev_err(&pdev->dev,
"Driver still in use but removing anyhow\n");
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0365/1887] USB: gadget: ffs: fix mm lifetime handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (363 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0364/1887] usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0366/1887] usb: gadget: f_fs: Fix Use-After-Free in AIO error path Greg Kroah-Hartman
` (633 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gabriel Prostitis, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Prostitis <prostitisgabriel@gmail.com>
[ Upstream commit 5eb5c72c72fef76cb765ef1669b62b6a3ba1bfc8 ]
io_data stores a pointer to the submitting task's mm_struct,
but does not currently hold a reference to it while async
requests are pending.
This can result in a use-after-free if the task exits before
completion handling finishes.
Take a reference with mmgrab() when queuing the read request
and release it with mmdrop() on request completion.
Reported-by: Gabriel Prostitis <prostitisgabriel@gmail.com>
Signed-off-by: Gabriel Prostitis <prostitisgabriel@gmail.com>
Link: https://patch.msgid.link/20260601-mm-uaf-fix-v2-1-3c942a707bce@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: e78dcb1f7ec2 ("usb: gadget: f_fs: Fix Use-After-Free in AIO error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/function/f_fs.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -842,9 +842,15 @@ static void ffs_user_copy_worker(struct
unsigned long flags;
if (io_data->read && ret > 0) {
- kthread_use_mm(io_data->mm);
- ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
- kthread_unuse_mm(io_data->mm);
+ if (mmget_not_zero(io_data->mm)) {
+ kthread_use_mm(io_data->mm);
+ ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
+ kthread_unuse_mm(io_data->mm);
+ mmput(io_data->mm);
+ } else {
+ ret = -EFAULT;
+ }
+ mmdrop(io_data->mm);
}
io_data->kiocb->ki_complete(io_data->kiocb, ret);
@@ -1229,16 +1235,20 @@ static ssize_t ffs_epfile_write_iter(str
kiocb->private = p;
- if (p->aio)
+ if (p->aio) {
+ mmgrab(p->mm);
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
+ }
res = ffs_epfile_io(kiocb->ki_filp, p);
if (res == -EIOCBQUEUED)
return res;
- if (p->aio)
+ if (p->aio) {
+ mmdrop(p->mm);
kfree(p);
- else
+ } else {
*from = p->data;
+ }
return res;
}
@@ -1275,14 +1285,17 @@ static ssize_t ffs_epfile_read_iter(stru
kiocb->private = p;
- if (p->aio)
+ if (p->aio) {
+ mmgrab(p->mm);
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
+ }
res = ffs_epfile_io(kiocb->ki_filp, p);
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
+ mmdrop(p->mm);
kfree(p->to_free);
kfree(p);
} else {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0366/1887] usb: gadget: f_fs: Fix Use-After-Free in AIO error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (364 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0365/1887] USB: gadget: ffs: fix mm lifetime handling Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0367/1887] usb: typec: tcpm: fix debug accessory mode detection for sink ports Greg Kroah-Hartman
` (632 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xingyu Jin, Neill Kapron,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Neill Kapron <nkapron@google.com>
[ Upstream commit e78dcb1f7ec271449c54984dc90c62a5ba272de7 ]
In ffs_epfile_write_iter() and ffs_epfile_read_iter(), when ffs_epfile_io()
fails with an error other than -EIOCBQUEUED, the io_data structure (`p`) is
freed. However, for AIO operations, the kiocb cancel function was already
armed and kiocb->private was set to `p`.
If a concurrent cancel operation (such as sys_io_cancel()) executes after
ffs_epfile_io() fails but before the function frees `p`, a Use-After-Free
can occur when the cancellation handler accesses the freed pointer.
To securely fix this race condition, we must properly un-arm the
cancellation. Invoking `kiocb->ki_complete()` does exactly this by
acquiring `ctx->ctx_lock` and safely removing the kiocb from the active
sequence. In doing so, it ensures that a parallel io_cancel can no longer
discover the kiocb, effectively closing the race window.
We then return -EIOCBQUEUED to notify the VFS layer that the kiocb has been
consumed and it should avoid attempting to complete the request again or
triggering subsequent completion handlers.
Fixes: de2080d41b5d ("gadget/function/f_fs.c: close leaks")
Cc: stable@vger.kernel.org
Reported-by: Xingyu Jin <xingyuj@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
Link: https://patch.msgid.link/20260724235100.106011-1-nkapron@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/function/f_fs.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1244,8 +1244,10 @@ static ssize_t ffs_epfile_write_iter(str
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*from = p->data;
}
@@ -1295,9 +1297,11 @@ static ssize_t ffs_epfile_read_iter(stru
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p->to_free);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*to = p->data;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0367/1887] usb: typec: tcpm: fix debug accessory mode detection for sink ports
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (365 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0366/1887] usb: gadget: f_fs: Fix Use-After-Free in AIO error path Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0368/1887] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling Greg Kroah-Hartman
` (631 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Xu Yang, Heikki Krogerus,
Amit Sunil Dhamne, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <xu.yang_2@nxp.com>
[ Upstream commit f6ec9bb4acc7182b25a793ad094a764e1cb819a7 ]
The port in debug accessory mode can be either a source or sink. The
previous tcpm_port_is_debug() function only checked for source port.
Commit 8db73e6a42b6 ("usb: typec: tcpm: allow sink (ufp) to toggle into
accessory mode debug") changed the detection logic to support both roles,
but left some logic in _tcpm_cc_change() unchanged, This causes the state
machine to transition to an incorrect state when operating as a sink in
debug accessory mode. Log as below:
[ 978.637541] CC1: 0 -> 5, CC2: 0 -> 5 [state TOGGLING, polarity 0, connected]
[ 978.637567] state change TOGGLING -> SRC_ATTACH_WAIT [rev1 NONE_AMS]
[ 978.637596] pending state change SRC_ATTACH_WAIT -> DEBUG_ACC_ATTACHED @ 180 ms [rev1 NONE_AMS]
[ 978.647098] CC1: 5 -> 0, CC2: 5 -> 5 [state SRC_ATTACH_WAIT, polarity 0, connected]
[ 978.647115] state change SRC_ATTACH_WAIT -> SRC_ATTACH_WAIT [rev1 NONE_AMS]
It should go to SNK_ATTACH_WAIT instead of SRC_ATTACH_WAIT state.
To fix this, add tcpm_port_is_debug_source() and tcpm_port_is_debug_sink()
helper to explicitly identify the power mode in debug accessory mode.
Update the state transition logic in _tcpm_cc_change() to ensure the state
machine transitions comply with Type-C specification. Also update the logic
in run_state_machine() to keep consistency.
Fixes: 8db73e6a42b6 ("usb: typec: tcpm: allow sink (ufp) to toggle into accessory mode debug")
Cc: stable <stable@kernel.org>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Amit Sunil Dhamne <amitsd@google.com>
Link: https://patch.msgid.link/20260424074009.2979266-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[Backport to 6.12: This tree lacks 8db73e6a42b6 and the associated
sink debug-accessory state-machine support. Retain only the source-debug
macro extraction and source-side call-site updates. Keep
tcpm_port_is_debug() source-only and omit the sink-debug macro and all
sink/audio attachment transitions introduced by the upstream dependency.
This preserves existing detection and state transitions while providing
tcpm_port_is_debug_source() for cd3b9cea675b ("usb: typec: tcpm: constrain
TCPM_SOURCING_VBUS event handling"). No functions are added.]
Stable-dep-of: cd3b9cea675b ("usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -522,9 +522,12 @@ static const char * const pd_rev[] = {
(tcpm_cc_is_source((port)->cc2) && \
!tcpm_cc_is_source((port)->cc1)))
-#define tcpm_port_is_debug(port) \
+#define tcpm_port_is_debug_source(port) \
(tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2))
+#define tcpm_port_is_debug(port) \
+ tcpm_port_is_debug_source(port)
+
#define tcpm_port_is_audio(port) \
(tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_audio((port)->cc2))
@@ -4023,7 +4026,7 @@ static void run_state_machine(struct tcp
tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
break;
case SRC_ATTACH_WAIT:
- if (tcpm_port_is_debug(port))
+ if (tcpm_port_is_debug_source(port))
tcpm_set_state(port, DEBUG_ACC_ATTACHED,
PD_T_CC_DEBOUNCE);
else if (tcpm_port_is_audio(port))
@@ -5035,7 +5038,7 @@ static void _tcpm_cc_change(struct tcpm_
switch (port->state) {
case TOGGLING:
- if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
+ if (tcpm_port_is_debug_source(port) || tcpm_port_is_audio(port) ||
tcpm_port_is_source(port))
tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
else if (tcpm_port_is_sink(port))
@@ -5043,7 +5046,7 @@ static void _tcpm_cc_change(struct tcpm_
break;
case SRC_UNATTACHED:
case ACC_UNATTACHED:
- if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
+ if (tcpm_port_is_debug_source(port) || tcpm_port_is_audio(port) ||
tcpm_port_is_source(port))
tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
break;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0368/1887] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (366 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0367/1887] usb: typec: tcpm: fix debug accessory mode detection for sink ports Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0369/1887] xen/netfront: drop RX packets with a short Ethernet header Greg Kroah-Hartman
` (630 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Amit Sunil Dhamne,
Badhri Jagan Sridharan, Heikki Krogerus, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <amitsd@google.com>
[ Upstream commit cd3b9cea675bbfebc223f007dc2f4e79524fa54c ]
When a sink detach occurs while waiting for TX send status, the old
TCPM_SOURCING_VBUS event along with TCPM_VBUS_EVENT and TCPM_CC_EVENT
can be queued in port->pd_events. Because TCPM_SOURCING_VBUS is
evaluated after TCPM_VBUS_EVENT and TCPM_CC_EVENT in
tcpm_pd_event_handler(), a stale TCPM_SOURCING_VBUS event can override
the detach handling and incorrectly set port->vbus_source and
port->vbus_present to true.
Add a state guard to check that the port is either operating as a
Source (tcpm_port_is_source(port)) or in a Fast Role Swap (FRS) state
up to FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED before processing
TCPM_SOURCING_VBUS. Otherwise, discard and log the event.
Log snippet for error condition before fix:
[72792.204955] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[72792.204960] sourcing vbus
[72792.204962] VBUS on
[72792.204970] AMS POWER_NEGOTIATION start
[72792.204974] cc:=4
[72792.205319] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[72792.205325] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[72792.205332] PD TX, header: 0x11a1
[72792.216911] PD TX complete, status: 2
[72792.216957] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
[72792.218005] VBUS off
[72792.218013] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[72792.218020] VBUS VSAFE0V
[72792.218024] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [rev3 POWER_NEGOTIATION]
[72792.218458] CC1: 2 -> 0, CC2: 0 -> 0 [state SNK_UNATTACHED, polarity 0, disconnected]
[72792.218467] VBUS on --> VBUS left on
[72792.218980] disable vbus discharge ret:0
[72792.235193] Start toggling
After fix:
[ 1195.291691] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[ 1195.291698] sourcing vbus
[ 1195.291700] VBUS on
[ 1195.291707] AMS POWER_NEGOTIATION start
[ 1195.291710] cc:=4
[ 1195.291758] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[ 1195.291794] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[ 1195.291798] PD TX, header: 0x11a1
[ 1195.297056] PD TX complete, status: 2
[ 1195.297092] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
[ 1195.297177] VBUS off
[ 1195.297184] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[ 1195.297227] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_SEND_CAPABILITIES, polarity 0, disconnected]
[ 1195.307469] cc:=2
[ 1195.307544] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[ 1195.307555] Discarding sourcing vbus! Invalid state SRC_SEND_CAPABILITIES
[ 1195.957636] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [delayed 650 ms]
[ 1195.957732] disable vbus discharge ret:0
[ 1195.970196] Start toggling
[ 1195.970468] VBUS off
[ 1196.051637] VBUS off
[ 1196.051642] VBUS VSAFE0V
Fixes: 8dc4bd073663 ("usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS)")
Cc: stable <stable@kernel.org>
Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260827-sourcing-vbus-v1-1-9be1aca991a0@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -5549,16 +5549,32 @@ static void tcpm_pd_event_handler(struct
}
}
if (events & TCPM_SOURCING_VBUS) {
- tcpm_log(port, "sourcing vbus");
/*
* In fast role swap case TCPC autonomously sources vbus. Set vbus_source
- * true as TCPM wouldn't have called tcpm_set_vbus.
+ * true conditionally as TCPM wouldn't have called tcpm_set_vbus.
+ * If TCPM calls tcpm_set_vbus to source vbus, vbus_source would already
+ * be true.
*
- * When vbus is sourced on the command on TCPM i.e. TCPM called
- * tcpm_set_vbus to source vbus, vbus_source would already be true.
+ * When TCPM_FRS_EVENT and TCPM_SOURCING_VBUS arrive simultaneously,
+ * handling TCPM_FRS_EVENT above transitions the state to AMS_START
+ * with upcoming_state FR_SWAP_SEND.
*/
- port->vbus_source = true;
- _tcpm_pd_vbus_on(port);
+
+ if (tcpm_port_is_source(port) ||
+ tcpm_port_is_debug_source(port) ||
+ (port->state == AMS_START && port->upcoming_state == FR_SWAP_SEND) ||
+ port->state == FR_SWAP_SEND ||
+ port->state == FR_SWAP_SEND_TIMEOUT ||
+ port->state == FR_SWAP_SNK_SRC_TRANSITION_TO_OFF ||
+ port->state == FR_SWAP_SNK_SRC_NEW_SINK_READY ||
+ port->state == FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED) {
+ tcpm_log(port, "sourcing vbus");
+ port->vbus_source = true;
+ _tcpm_pd_vbus_on(port);
+ } else {
+ tcpm_log(port, "Discarding sourcing vbus! Invalid state %s",
+ tcpm_states[port->state]);
+ }
}
spin_lock(&port->pd_event_lock);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0369/1887] xen/netfront: drop RX packets with a short Ethernet header
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (367 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0368/1887] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0370/1887] smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions Greg Kroah-Hartman
` (629 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
commit 089e58805c452e52179482b1025a8e309a57f801 upstream.
handle_incoming_queue() pulls pull_to bytes into the head before
calling eth_type_trans(). pull_to is the length of the first RX slot,
capped at RX_COPY_THRESHOLD, and that length comes from the backend.
Nothing checks it against ETH_HLEN.
If the first slot is shorter than ETH_HLEN and more slots follow, the
head ends up shorter than an Ethernet header while skb->len is longer,
and eth_type_trans() BUG()s in __skb_pull(). If the whole packet is
shorter than ETH_HLEN, eth_type_trans() reads the header past the end
of the data instead.
Pull at least ETH_HLEN, and drop the packet if that fails, which also
drops packets too short to hold an Ethernet header. This also checks
the return value of the pull, which was ignored.
Fixes: 0d160211965b ("xen: add virtual network device driver")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Link: https://patch.msgid.link/20261007-b4-xen-netfront-short-head-v1-1-12d7113a7e4e@toxicpanda.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/xen-netfront.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1233,8 +1233,16 @@ static int handle_incoming_queue(struct
while ((skb = __skb_dequeue(rxq)) != NULL) {
int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
- if (pull_to > skb_headlen(skb))
- __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+ /* pull_to comes from the first slot's length, which the
+ * backend controls. Make sure the head holds at least an
+ * Ethernet header for eth_type_trans().
+ */
+ if (!pskb_may_pull(skb, max(pull_to, ETH_HLEN))) {
+ kfree_skb(skb);
+ packets_dropped++;
+ queue->info->netdev->stats.rx_errors++;
+ continue;
+ }
/* Ethernet work: Delayed to here as it peeks the header. */
skb->protocol = eth_type_trans(skb, queue->info->netdev);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0370/1887] smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (368 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0369/1887] xen/netfront: drop RX packets with a short Ethernet header Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0371/1887] bpf: Fix accesses to uninit stack slots Greg Kroah-Hartman
` (628 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Namjae Jeon,
Paulo Alcantara, Bjoern Doebel, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
[ Upstream commit b8e5dc4f95e5484159b343903f302eb6d783f2e6 ]
When a file has the setuid or setgid bit set and is written to, the VFS
strips those bits and issues a setattr with ATTR_KILL_SUID/ATTR_KILL_SGID
together with an ATTR_MODE carrying the already-cleared mode.
Both cifs_setattr_unix() and cifs_setattr_nounix() unconditionally dropped
ATTR_MODE in that case:
/* skip mode change if it's just for clearing setuid/setgid */
if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
attrs->ia_valid &= ~ATTR_MODE;
This is fine for the default mount, where the mode is only emulated via
the DOS read-only attribute and cannot represent the setuid/setgid bits
anyway. However, with the "cifsacl" or "modefromsid" mount options the
mode is stored on the server through an ACL (id_mode_to_cifs_acl()), with
the SMB3.1.1 POSIX extensions the mode is sent to the server directly,
and with the SMB1 Unix extensions (cifs_setattr_unix) the mode is sent
via CIFSSMBUnixSetPathInfo(). In all those cases dropping ATTR_MODE means
the cleared mode is never pushed to the server, so the setuid/setgid bit
survives the write.
This is a security issue: on local filesystems the setuid bit is stripped
when a file is written, but over these cifs.ko mounts the bit persists on
the server, potentially allowing an unexpected privilege escalation on
subsequent execution.
Fix this in two places:
1. cifs_setattr_nounix(): only take the "skip mode change" shortcut
when the mode is emulated via the DOS read-only attribute (i.e.
neither cifsacl/modefromsid nor the SMB3.1.1 POSIX extensions are
in effect), so that the cleared mode is propagated to the server
in the ACL / POSIX cases.
2. cifs_setattr_unix(): this function is only called when Unix
extensions are in effect, so the mode is always stored on the
server. Remove the shortcut entirely so that the cleared mode is
always pushed.
Fixes: d32c4f2626ac ("CIFS: ignore mode change if it's just for clearing setuid/setgid bits")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Backport note for 6.1: no sbflags local exists here, so test
cifs_sb->mnt_cifs_flags directly (same flag bits). Drop the upstream
posix_extensions clause: 6.1 lacks d413eabff18d ("fs/smb/client:
implement chmod() for SMB3 POSIX Extensions"), so cifs_setattr_nounix()
has no POSIX ATTR_MODE branch; match its CIFS_ACL/MODE_FROM_SID check. ]
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Assisted-by: opencode:kimi-k3
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/inode.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 5d21cb051a602..9da26e43ea322 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -2827,9 +2827,13 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
goto out;
}
- /* skip mode change if it's just for clearing setuid/setgid */
- if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
- attrs->ia_valid &= ~ATTR_MODE;
+ /*
+ * This function is only called when Unix extensions are in effect,
+ * so the mode is always sent to and stored on the server. Do not
+ * skip the mode change when clearing setuid/setgid bits: dropping
+ * ATTR_MODE here would leave those bits set on the server after a
+ * write, which is a security issue.
+ */
args = kmalloc(sizeof(*args), GFP_KERNEL);
if (args == NULL) {
@@ -3015,8 +3019,22 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
- /* skip mode change if it's just for clearing setuid/setgid */
- if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+ /*
+ * Skip the mode change if it is only being done to clear the
+ * setuid/setgid bits *and* the mode is emulated via the DOS
+ * read-only attribute (the default, non-ACL case), which cannot
+ * represent the setuid/setgid bits anyway.
+ *
+ * When the mode is instead stored on the server - i.e. with the
+ * cifsacl or modefromsid mount options (via an ACL) - the cleared
+ * mode must be pushed to the server. Dropping ATTR_MODE here
+ * would leave the setuid/setgid bit set on the server after a
+ * write, which is a security issue (the bits are not stripped as
+ * they are on local filesystems).
+ */
+ if ((attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
+ !(cifs_sb->mnt_cifs_flags &
+ (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)))
attrs->ia_valid &= ~ATTR_MODE;
if (attrs->ia_valid & ATTR_MODE) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0371/1887] bpf: Fix accesses to uninit stack slots
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (369 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0370/1887] smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix extensions Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0372/1887] soc: qcom: geni-se: Correct QUP Core ICC vote constants Greg Kroah-Hartman
` (627 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hao Sun, Andrei Matei,
Andrii Nakryiko, Shun Ota, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Matei <andreimatei1@gmail.com>
[ Upstream commit 6b4a64bafd107e521c01eec3453ce94a3fb38529 ]
Privileged programs are supposed to be able to read uninitialized stack
memory (ever since 6715df8d5) but, before this patch, these accesses
were permitted inconsistently. In particular, accesses were permitted
above state->allocated_stack, but not below it. In other words, if the
stack was already "large enough", the access was permitted, but
otherwise the access was rejected instead of being allowed to "grow the
stack". This undesired rejection was happening in two places:
- in check_stack_slot_within_bounds()
- in check_stack_range_initialized()
This patch arranges for these accesses to be permitted. A bunch of tests
that were relying on the old rejection had to change; all of them were
changed to add also run unprivileged, in which case the old behavior
persists. One tests couldn't be updated - global_func16 - because it
can't run unprivileged for other reasons.
This patch also fixes the tracking of the stack size for variable-offset
reads. This second fix is bundled in the same commit as the first one
because they're inter-related. Before this patch, writes to the stack
using registers containing a variable offset (as opposed to registers
with fixed, known values) were not properly contributing to the
function's needed stack size. As a result, it was possible for a program
to verify, but then to attempt to read out-of-bounds data at runtime
because a too small stack had been allocated for it.
Each function tracks the size of the stack it needs in
bpf_subprog_info.stack_depth, which is maintained by
update_stack_depth(). For regular memory accesses, check_mem_access()
was calling update_state_depth() but it was passing in only the fixed
part of the offset register, ignoring the variable offset. This was
incorrect; the minimum possible value of that register should be used
instead.
This tracking is now fixed by centralizing the tracking of stack size in
grow_stack_state(), and by lifting the calls to grow_stack_state() to
check_stack_access_within_bounds() as suggested by Andrii. The code is
now simpler and more convincingly tracks the correct maximum stack size.
check_stack_range_initialized() can now rely on enough stack having been
allocated for the access; this helps with the fix for the first issue.
A few tests were changed to also check the stack depth computation. The
one that fails without this patch is verifier_var_off:stack_write_priv_vs_unpriv.
Fixes: 01f810ace9ed3 ("bpf: Allow variable-offset stack access")
Reported-by: Hao Sun <sunhao.th@gmail.com>
Signed-off-by: Andrei Matei <andreimatei1@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20231208032519.260451-3-andreimatei1@gmail.com
Closes: https://lore.kernel.org/bpf/CABWLsev9g8UP_c3a=1qbuZUi20tGoUXoU07FPf-5FLvhOKOY+Q@mail.gmail.com/
[ Resolved conflict in check_stack_write_var_off() by dropping grow_stack_state()
and omitting upstream dynptr logic not present in 6.1.y.
Adapted upstream test changes (progs/verifier_*.c) to 6.1.y's legacy test format
in tools/testing/selftests/bpf/verifier/{basic_stack,raw_stack,var_off}.c.
Omitted tests for features/files not present in 6.1.y (iters.c and verifier_int_ptr.c). ]
Signed-off-by: Shun Ota <shun.ota@miraclelinux.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 66 ++++++++-----------
.../selftests/bpf/progs/test_global_func16.c | 2 +-
.../selftests/bpf/verifier/atomic_cmpxchg.c | 11 ----
.../selftests/bpf/verifier/basic_stack.c | 12 ++--
tools/testing/selftests/bpf/verifier/calls.c | 4 +-
.../selftests/bpf/verifier/raw_stack.c | 8 ++-
.../testing/selftests/bpf/verifier/var_off.c | 57 ++++++++++++----
7 files changed, 89 insertions(+), 71 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e2ce9f664a40a..d7e9b84ff491b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1026,7 +1026,10 @@ static int resize_reference_state(struct bpf_func_state *state, size_t n)
return 0;
}
-static int grow_stack_state(struct bpf_func_state *state, int size)
+/* Possibly update state->allocated_stack to be at least size bytes. Also
+ * possibly update the function's high-water mark in its bpf_subprog_info.
+ */
+static int grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size)
{
size_t old_n = state->allocated_stack / BPF_REG_SIZE, n = size / BPF_REG_SIZE;
@@ -1038,6 +1041,11 @@ static int grow_stack_state(struct bpf_func_state *state, int size)
return -ENOMEM;
state->allocated_stack = size;
+
+ /* update known max for given subprogram */
+ if (env->subprog_info[state->subprogno].stack_depth < size)
+ env->subprog_info[state->subprogno].stack_depth = size;
+
return 0;
}
@@ -3214,9 +3222,6 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
struct bpf_reg_state *reg = NULL;
u32 dst_reg = insn->dst_reg;
- err = grow_stack_state(state, round_up(slot + 1, BPF_REG_SIZE));
- if (err)
- return err;
/* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
* so it's aligned access and [off, off + size) are within stack limits
*/
@@ -3367,11 +3372,6 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
if (value_reg && register_is_null(value_reg))
writing_zero = true;
- err = grow_stack_state(state, round_up(-min_off, BPF_REG_SIZE));
- if (err)
- return err;
-
-
/* Variable offset writes destroy any spilled pointers in range. */
for (i = min_off; i < max_off; i++) {
u8 new_type, *stype;
@@ -4406,20 +4406,6 @@ static int check_ptr_alignment(struct bpf_verifier_env *env,
strict);
}
-static int update_stack_depth(struct bpf_verifier_env *env,
- const struct bpf_func_state *func,
- int off)
-{
- u16 stack = env->subprog_info[func->subprogno].stack_depth;
-
- if (stack >= -off)
- return 0;
-
- /* update known max for given subprogram */
- env->subprog_info[func->subprogno].stack_depth = -off;
- return 0;
-}
-
/* starting from main bpf function walk all instructions of the function
* and recursively walk all callees that given function can call.
* Ignore jump and exit insns.
@@ -4849,13 +4835,14 @@ static int check_ptr_to_map_access(struct bpf_verifier_env *env,
* The minimum valid offset is -MAX_BPF_STACK for writes, and
* -state->allocated_stack for reads.
*/
-static int check_stack_slot_within_bounds(s64 off,
- struct bpf_func_state *state,
- enum bpf_access_type t)
+static int check_stack_slot_within_bounds(struct bpf_verifier_env *env,
+ s64 off,
+ struct bpf_func_state *state,
+ enum bpf_access_type t)
{
int min_valid_off;
- if (t == BPF_WRITE)
+ if (t == BPF_WRITE || env->allow_uninit_stack)
min_valid_off = -MAX_BPF_STACK;
else
min_valid_off = -state->allocated_stack;
@@ -4904,7 +4891,7 @@ static int check_stack_access_within_bounds(
max_off = reg->smax_value + off + access_size;
}
- err = check_stack_slot_within_bounds(min_off, state, type);
+ err = check_stack_slot_within_bounds(env, min_off, state, type);
if (!err && max_off > 0)
err = -EINVAL; /* out of stack access into non-negative offsets */
if (!err && access_size < 0)
@@ -4924,8 +4911,10 @@ static int check_stack_access_within_bounds(
verbose(env, "invalid variable-offset%s stack R%d var_off=%s size=%d\n",
err_extra, regno, tn_buf, access_size);
}
+ return err;
}
- return err;
+
+ return grow_stack_state(env, state, round_up(-min_off, BPF_REG_SIZE));
}
/* check whether memory at (regno + off) is accessible for t = (read | write)
@@ -4940,7 +4929,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
{
struct bpf_reg_state *regs = cur_regs(env);
struct bpf_reg_state *reg = regs + regno;
- struct bpf_func_state *state;
int size, err = 0;
size = bpf_size_to_bytes(bpf_size);
@@ -5084,11 +5072,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
if (err)
return err;
- state = func(env, reg);
- err = update_stack_depth(env, state, off);
- if (err)
- return err;
-
if (t == BPF_READ)
err = check_stack_read(env, regno, off, size,
value_regno);
@@ -5281,7 +5264,8 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
/* When register 'regno' is used to read the stack (either directly or through
* a helper function) make sure that it's within stack boundary and, depending
- * on the access type, that all elements of the stack are initialized.
+ * on the access type and privileges, that all elements of the stack are
+ * initialized.
*
* 'off' includes 'regno->off', but not its dynamic part (if any).
*
@@ -5364,8 +5348,11 @@ static int check_stack_range_initialized(
slot = -i - 1;
spi = slot / BPF_REG_SIZE;
- if (state->allocated_stack <= slot)
- goto err;
+ if (state->allocated_stack <= slot) {
+ verbose(env, "verifier bug: allocated_stack too small");
+ return -EFAULT;
+ }
+
stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
if (*stype == STACK_MISC)
goto mark;
@@ -5389,7 +5376,6 @@ static int check_stack_range_initialized(
goto mark;
}
-err:
if (tnum_is_const(reg->var_off)) {
verbose(env, "invalid%s read from stack R%d off %d+%d size %d\n",
err_extra, regno, min_off, i - min_off, access_size);
@@ -5414,7 +5400,7 @@ static int check_stack_range_initialized(
* helper may write to the entire memory range.
*/
}
- return update_stack_depth(env, state, min_off);
+ return 0;
}
static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
diff --git a/tools/testing/selftests/bpf/progs/test_global_func16.c b/tools/testing/selftests/bpf/progs/test_global_func16.c
index e7206304632e1..e3e64bc472cda 100644
--- a/tools/testing/selftests/bpf/progs/test_global_func16.c
+++ b/tools/testing/selftests/bpf/progs/test_global_func16.c
@@ -13,7 +13,7 @@ __noinline int foo(int (*arr)[10])
}
SEC("cgroup_skb/ingress")
-__failure __msg("invalid indirect read from stack")
+__success
int global_func16(struct __sk_buff *skb)
{
int array[10];
diff --git a/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c b/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c
index b39665f33524f..096219311951d 100644
--- a/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c
+++ b/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c
@@ -83,17 +83,6 @@
.result = REJECT,
.errstr = "!read_ok",
},
-{
- "Can't use cmpxchg on uninit memory",
- .insns = {
- BPF_MOV64_IMM(BPF_REG_0, 3),
- BPF_MOV64_IMM(BPF_REG_2, 4),
- BPF_ATOMIC_OP(BPF_DW, BPF_CMPXCHG, BPF_REG_10, BPF_REG_2, -8),
- BPF_EXIT_INSN(),
- },
- .result = REJECT,
- .errstr = "invalid read from stack",
-},
{
"BPF_W cmpxchg should zero top 32 bits",
.insns = {
diff --git a/tools/testing/selftests/bpf/verifier/basic_stack.c b/tools/testing/selftests/bpf/verifier/basic_stack.c
index f995777dddb3f..fb79c6112df56 100644
--- a/tools/testing/selftests/bpf/verifier/basic_stack.c
+++ b/tools/testing/selftests/bpf/verifier/basic_stack.c
@@ -17,8 +17,10 @@
BPF_EXIT_INSN(),
},
.fixup_map_hash_8b = { 2 },
- .errstr = "invalid indirect read from stack",
- .result = REJECT,
+ .result = ACCEPT,
+ .retval = POINTER_VALUE,
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "invalid indirect read from stack",
},
{
"uninitialized stack2",
@@ -27,8 +29,10 @@
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, -8),
BPF_EXIT_INSN(),
},
- .errstr = "invalid read from stack",
- .result = REJECT,
+ .result = ACCEPT,
+ .retval = POINTER_VALUE,
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "invalid read from stack",
},
{
"invalid fp arithmetic",
diff --git a/tools/testing/selftests/bpf/verifier/calls.c b/tools/testing/selftests/bpf/verifier/calls.c
index a201d2871bfbd..a8ce7f534ba61 100644
--- a/tools/testing/selftests/bpf/verifier/calls.c
+++ b/tools/testing/selftests/bpf/verifier/calls.c
@@ -1501,7 +1501,9 @@
.prog_type = BPF_PROG_TYPE_XDP,
.fixup_map_hash_8b = { 23 },
.result = REJECT,
- .errstr = "invalid read from stack R7 off=-16 size=8",
+ .errstr = "R0 invalid mem access 'scalar'",
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "invalid read from stack R7 off=-16 size=8",
},
{
"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
diff --git a/tools/testing/selftests/bpf/verifier/raw_stack.c b/tools/testing/selftests/bpf/verifier/raw_stack.c
index eb5ed936580bf..36bc7f7b81ea3 100644
--- a/tools/testing/selftests/bpf/verifier/raw_stack.c
+++ b/tools/testing/selftests/bpf/verifier/raw_stack.c
@@ -10,9 +10,11 @@
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
BPF_EXIT_INSN(),
},
- .result = REJECT,
- .errstr = "invalid read from stack R6 off=-8 size=8",
- .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .result = ACCEPT,
+ .retval = POINTER_VALUE,
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "invalid read from stack R6 off=-8 size=8",
+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
},
{
"raw_stack: skb_load_bytes, negative len",
diff --git a/tools/testing/selftests/bpf/verifier/var_off.c b/tools/testing/selftests/bpf/verifier/var_off.c
index b183e26c03f10..5da76d0549866 100644
--- a/tools/testing/selftests/bpf/verifier/var_off.c
+++ b/tools/testing/selftests/bpf/verifier/var_off.c
@@ -58,11 +58,15 @@
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
- .result = REJECT,
- .errstr = "invalid variable-offset read from stack R2",
- .prog_type = BPF_PROG_TYPE_LWT_IN,
+ .result = ACCEPT,
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "R2 variable stack access prohibited for !root",
+ .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
},
{
+/* Check that the maximum stack depth is correctly maintained according to the
+ * maximum possible variable offset.
+ */
"variable-offset stack write, priv vs unpriv",
.insns = {
/* Get an unknown value */
@@ -75,13 +79,43 @@
*/
BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
/* Dereference it for a stack write */
+ BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
- /* Now read from the address we just wrote. This shows
- * that, after a variable-offset write, a priviledged
- * program can read the slots that were in the range of
- * that write (even if the verifier doesn't actually know
- * if the slot being read was really written to or not.
+ BPF_EXIT_INSN(),
+ },
+ /* Variable stack access is rejected for unprivileged.
*/
+ .errstr_unpriv = "R2 variable stack access prohibited for !root",
+ .result_unpriv = REJECT,
+ .result = ACCEPT,
+},
+{
+/* Similar to the previous test, but this time also perform a read from the
+ * address written to with a variable offset. The read is allowed, showing that,
+ * after a variable-offset write, a priviledged program can read the slots that
+ * were in the range of that write (even if the verifier doesn't actually know if
+ * the slot being read was really written to or not.
+ *
+ * Despite this test being mostly a superset, the previous test is also kept for
+ * the sake of it checking the stack depth in the case where there is no read.
+ */
+/* Check that the maximum stack depth is correctly maintained according to the
+ * maximum possible variable offset.
+ */
+ "variable-offset stack write, followed by read",
+ .insns = {
+ /* Get an unknown value */
+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
+ /* Make it small and 8-byte aligned */
+ BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
+ BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
+ /* Add it to fp. We now have either fp-8 or fp-16, but
+ * we don't know which
+ */
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
+ /* Dereference it for a stack write */
+ BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+ /* Now read from the address we just wrote. */
BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_2, 0),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
@@ -233,9 +267,10 @@
BPF_EXIT_INSN(),
},
.fixup_map_hash_8b = { 5 },
- .errstr = "invalid indirect read from stack R2 var_off",
- .result = REJECT,
- .prog_type = BPF_PROG_TYPE_LWT_IN,
+ .result = ACCEPT,
+ .result_unpriv = REJECT,
+ .errstr_unpriv = "R2 variable stack access prohibited for !root",
+ .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
},
{
"indirect variable-offset stack access, priv vs unpriv",
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0372/1887] soc: qcom: geni-se: Correct QUP Core ICC vote constants
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (370 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0371/1887] bpf: Fix accesses to uninit stack slots Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0373/1887] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Greg Kroah-Hartman
` (626 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Viken Dadhaniya,
Konrad Dybcio, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
[ Upstream commit 1cd9b1be5a9c56fd69e3f555b200a1844f9b873e ]
The GENI_TO_CORE ("qup-core") ICC vote selects the QUP Core 2X clock
rate. The CORE_2X_*_MHZ constants are expressed in Bps, but their
values are several orders of magnitude too small. For example, the
50 MHz threshold is represented by 2500 rather than 25000000 Bps.
As a result, clients using these constants can severely under-vote the
QUP Core clock.
Correct the constants to their intended Bps thresholds so that the ICC
provider selects the corresponding QUP Core 2X clock rate. Drop the unused
definitions.
Fixes: 58ffbba6a399 ("soc: qcom: geni: Support for ICC voting")
Cc: stable@kernel.org
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://patch.msgid.link/20260915-correct-icc-bandwidth-vote-constants-v2-1-f78eb611204e@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/qcom-geni-se.h | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index f5672785c0c4a..c54580c480768 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -265,17 +265,12 @@ struct geni_se {
#define QUP_SE_VERSION_2_5 0x20050000
/*
- * Define bandwidth thresholds that cause the underlying Core 2X interconnect
- * clock to run at the named frequency. These baseline values are recommended
- * by the hardware team, and are not dynamically scaled with GENI bandwidth
- * beyond basic on/off.
+ * QUP Core 2X clock votes used by GENI clients through the "qup-core" ICC
+ * path. Values are in Bps and must be converted with Bps_to_icc() before
+ * setting avg_bw.
*/
-#define CORE_2X_19_2_MHZ 960
-#define CORE_2X_50_MHZ 2500
-#define CORE_2X_100_MHZ 5000
-#define CORE_2X_150_MHZ 7500
-#define CORE_2X_200_MHZ 10000
-#define CORE_2X_236_MHZ 16383
+#define CORE_2X_19_2_MHZ 9600000
+#define CORE_2X_50_MHZ 25000000
#define GENI_DEFAULT_BW Bps_to_icc(1000)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0373/1887] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (371 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0372/1887] soc: qcom: geni-se: Correct QUP Core ICC vote constants Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0374/1887] tty: fix saved termios reset race Greg Kroah-Hartman
` (625 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Thinh Nguyen, Jiazi Liu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiazi Liu <jiazi.liu1984@gmail.com>
[ Upstream commit 1ff77cbefe5a653ea12874c213ea4bd0d72c1067 ]
When dwc3_check_event_buf() reads a GEVNTCOUNT value exceeding the
event buffer length, commit 63ccd26cd1f6 ("usb: dwc3: gadget: check
that event count does not exceed event buffer length") returns IRQ_NONE
without writing back GEVNTCOUNT. Since the DWC3 interrupt is
level-triggered, the uncleared IRQ source keeps the line asserted,
causing a tight IRQ storm that accumulates 99,900 unhandled interrupts
and triggers spurious.c:184 BUG -> kernel panic.
The resulting call stack:
__report_bad_irq+0xac/0xc8
note_interrupt+0x340/0x468
handle_irq_event+0xac/0xc0
handle_fasteoi_irq+0x120/0x228
gic_handle_irq+0x68/0x108
...
kernel BUG at kernel/irq/spurious.c:184
To reproduce, write a bogus value exceeding the event buffer length
directly to the GEVNTCOUNT register:
devmem <DWC3_BASE + 0xc40c> 4 0x1004
Write the bogus count back to GEVNTCOUNT to clear the IRQ source,
consistent with the stale event clearing pattern in
dwc3_event_buffers_setup(), and schedule error recovery to
reinitialize the controller.
Fixes: 63ccd26cd1f6 ("usb: dwc3: gadget: check that event count does not exceed event buffer length")
Cc: stable <stable@kernel.org>
Suggested-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Jiazi Liu <jiazi.liu1984@gmail.com>
Link: https://patch.msgid.link/20260915110637.17658-1-jiazi.liu1984@gmail.com
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: changed dwc3_writel() calls to pass dwc->regs instead of dwc. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/dwc3/core.h | 19 +++++++
drivers/usb/dwc3/ep0.c | 9 ++++
drivers/usb/dwc3/gadget.c | 104 +++++++++++++++++++++++++++++++++++++-
3 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 933a208c3aab5..e4e0c40dc51d3 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -42,6 +42,7 @@
#define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2
#define DWC3_ISOC_MAX_RETRIES 5
+#define DWC3_ERR_RECOVERY_MAX 3
#define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */
#define DWC3_EVENT_BUFFERS_SIZE 4096
@@ -817,6 +818,12 @@ enum dwc3_link_state {
DWC3_LINK_STATE_MASK = 0x0f,
};
+enum dwc3_err_state {
+ DWC3_ERR_NONE = 0,
+ DWC3_ERR_RECOVERY,
+ DWC3_ERR_UNRECOVERABLE,
+};
+
/* TRB Length, PCM and Status */
#define DWC3_TRB_SIZE_MASK (0x00ffffff)
#define DWC3_TRB_SIZE_LENGTH(n) ((n) & DWC3_TRB_SIZE_MASK)
@@ -972,6 +979,7 @@ struct dwc3_scratchpad_array {
/**
* struct dwc3 - representation of our controller
* @drd_work: workqueue used for role swapping
+ * @err_recovery_work: workqueue used for controller error recovery
* @ep0_trb: trb which is used for the ctrl_req
* @bounce: address of bounce buffer
* @scratchbuf: address of scratch buffer
@@ -983,6 +991,7 @@ struct dwc3_scratchpad_array {
* @ep0_in_setup: one control transfer is completed and enter setup phase
* @lock: for synchronizing
* @mutex: for mode switching
+ * @connect_mutex: for the pull-up and err_recovery_work
* @dev: pointer to our struct device
* @sysdev: pointer to the DMA-capable device
* @xhci: pointer to our xHCI child
@@ -1041,6 +1050,9 @@ struct dwc3_scratchpad_array {
* @ep0_next_event: hold the next expected event
* @ep0state: state of endpoint zero
* @link_state: link state
+ * @err_state: current error recovery state.
+ * @err_recovery_count: number of consecutive error recovery attempts until
+ * confirmed healthy and reset to 0 on reset event.
* @speed: device speed (super, high, full, low)
* @hwparams: copy of hwparams registers
* @regset: debugfs pointer to regdump file
@@ -1133,6 +1145,7 @@ struct dwc3_scratchpad_array {
*/
struct dwc3 {
struct work_struct drd_work;
+ struct work_struct err_recovery_work;
struct dwc3_trb *ep0_trb;
void *bounce;
void *scratchbuf;
@@ -1149,6 +1162,9 @@ struct dwc3 {
/* mode switching lock */
struct mutex mutex;
+ /* serializes pull-up run/stop vs error recovery */
+ struct mutex connect_mutex;
+
struct device *dev;
struct device *sysdev;
@@ -1265,6 +1281,9 @@ struct dwc3 {
enum dwc3_ep0_next ep0_next_event;
enum dwc3_ep0_state ep0state;
enum dwc3_link_state link_state;
+ enum dwc3_err_state err_state;
+
+ u32 err_recovery_count;
u16 u2sel;
u16 u2pel;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index f30ad37ea8a19..c4aa925bcd7cf 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -198,6 +198,11 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ ret = -ESHUTDOWN;
+ goto out;
+ }
+
if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) {
dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
dep->name);
@@ -269,6 +274,10 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
ret = __dwc3_gadget_ep0_set_halt(ep, value);
spin_unlock_irqrestore(&dwc->lock, flags);
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 25f7ab01c3c3c..cd0532158ba0b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1108,6 +1108,10 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
return 0;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
ret = __dwc3_gadget_ep_enable(dep, DWC3_DEPCFG_ACTION_INIT);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -2006,6 +2010,10 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
ret = __dwc3_gadget_ep_queue(dep, req);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -2238,6 +2246,10 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
ret = __dwc3_gadget_ep_set_halt(dep, value, false);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -2252,6 +2264,10 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
dep->flags |= DWC3_EP_WEDGE;
if (dep->number == 0 || dep->number == 1)
@@ -2373,6 +2389,10 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
int ret;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->err_state != DWC3_ERR_NONE) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -ESHUTDOWN;
+ }
ret = __dwc3_gadget_wakeup(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -2706,10 +2726,13 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
synchronize_irq(dwc->irq_gadget);
+ /* Serialize against dwc3_err_recovery_work() */
+ mutex_lock(&dwc->connect_mutex);
if (!is_on)
ret = dwc3_gadget_soft_disconnect(dwc);
else
ret = dwc3_gadget_soft_connect(dwc);
+ mutex_unlock(&dwc->connect_mutex);
pm_runtime_put(dwc->dev);
@@ -3984,6 +4007,10 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc->suspended = false;
+ /* The controller is recovered. */
+ if (dwc->err_state == DWC3_ERR_NONE)
+ dwc->err_recovery_count = 0;
+
/*
* Ideally, dwc3_reset_gadget() would trigger the function
* drivers to stop any active transfers through ep disable.
@@ -4446,6 +4473,12 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt)
return ret;
}
+static void dwc3_schedule_err_recovery(struct dwc3 *dwc)
+{
+ dwc->err_state = DWC3_ERR_RECOVERY;
+ schedule_work(&dwc->err_recovery_work);
+}
+
static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
{
struct dwc3 *dwc = evt->dwc;
@@ -4479,9 +4512,21 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
return IRQ_NONE;
if (count > evt->length) {
- dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
+ dev_err(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
count, evt->length);
- return IRQ_NONE;
+ /*
+ * This is a fatal error - the driver and controller are out of
+ * sync on which event has been consumed. Reinitializing the
+ * controller is required to recover. Write the bogus count back
+ * to GEVNTCOUNT to clear the IRQ source, consistent with the
+ * stale event clearing in dwc3_event_buffers_setup(), then
+ * schedule error recovery.
+ */
+ spin_lock(&dwc->lock);
+ dwc3_schedule_err_recovery(dwc);
+ spin_unlock(&dwc->lock);
+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
+ return IRQ_HANDLED;
}
evt->count = count;
@@ -4546,6 +4591,57 @@ static void dwc_gadget_release(struct device *dev)
kfree(gadget);
}
+static void dwc3_err_recovery_work(struct work_struct *work)
+{
+ struct dwc3 *dwc = container_of(work, struct dwc3, err_recovery_work);
+ unsigned long flags;
+ int ret;
+
+ /* serializes against dwc3_gadget_pullup() */
+ mutex_lock(&dwc->connect_mutex);
+
+ ret = dwc3_gadget_soft_disconnect(dwc);
+
+ dwc3_disconnect_gadget_sleepable(dwc);
+
+ if (ret)
+ goto err_unrecoverable;
+
+ if (dwc->softconnect) {
+ u32 count;
+ /*
+ * Wait irq to finish before soft_connect resets evt->lpos and
+ * the event buffer registers to avoid racing with
+ * dwc3_process_event_buf().
+ */
+ synchronize_irq(dwc->irq_gadget);
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ count = ++dwc->err_recovery_count;
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ if (count > DWC3_ERR_RECOVERY_MAX)
+ goto err_unrecoverable;
+
+ ret = dwc3_gadget_soft_connect(dwc);
+ if (ret)
+ goto err_unrecoverable;
+ }
+ mutex_unlock(&dwc->connect_mutex);
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ dwc->err_state = DWC3_ERR_NONE;
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return;
+
+err_unrecoverable:
+ dev_err(dwc->dev, "Unable to recover the controller\n");
+ mutex_unlock(&dwc->connect_mutex);
+ spin_lock_irqsave(&dwc->lock, flags);
+ dwc->err_state = DWC3_ERR_UNRECOVERABLE;
+ spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
/**
* dwc3_gadget_init - initializes gadget related registers
* @dwc: pointer to our controller context structure
@@ -4589,6 +4685,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
}
init_completion(&dwc->ep0_in_setup);
+ INIT_WORK(&dwc->err_recovery_work, dwc3_err_recovery_work);
+ mutex_init(&dwc->connect_mutex);
dwc->gadget = kzalloc(sizeof(struct usb_gadget), GFP_KERNEL);
if (!dwc->gadget) {
ret = -ENOMEM;
@@ -4679,6 +4777,8 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
if (!dwc->gadget)
return;
+ cancel_work_sync(&dwc->err_recovery_work);
+ mutex_destroy(&dwc->connect_mutex);
dwc3_enable_susphy(dwc, true);
usb_del_gadget(dwc->gadget);
dwc3_gadget_free_endpoints(dwc);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0374/1887] tty: fix saved termios reset race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (372 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0373/1887] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0375/1887] perf: Require kernel access for text poke events Greg Kroah-Hartman
` (624 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Johan Hovold,
Sasha Levin, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 8df07fe93573e9e548d6645273e9bcb6eb74059e ]
Resetting saved termios state on device registration is needed where a
minor number can be reused for an entirely different device and where
the old settings may prevent the port from even being opened (e.g. when
CLOCAL is not set).
Not all TTY drivers guarantee that the minor number is no longer in use
when registering devices however, something which can lead to a
use-after-free when closing a TTY (and saving its termios) races with
re-registration.
Add a new TTY_DRIVER_RESET_SAVED_TERMIOS flag to request that any saved
termios state is reset on registration and only set it for drivers that
make sure that the minor number is no longer in use.
Fixes: 93857edd9829 ("tty: reset termios state on device registration")
Reported-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://lore.kernel.org/20260926184154.3017929-1-nicoyip.dev@gmail.com
Cc: stable@kernel.org # 4.12
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260930131845.1809256-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: adapted flag handling to use a hexadecimal macro assigned through gb_tty_driver->flags. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/greybus/uart.c | 3 ++-
drivers/tty/tty_io.c | 18 ++++++++++--------
drivers/usb/class/cdc-acm.c | 2 +-
drivers/usb/serial/usb-serial.c | 3 ++-
include/linux/tty_driver.h | 6 ++++++
5 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 074c02f123e20..0bdef38a15d72 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -954,7 +954,8 @@ static int gb_tty_init(void)
gb_tty_driver->minor_start = 0;
gb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
gb_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV |
+ TTY_DRIVER_RESET_SAVED_TERMIOS;
gb_tty_driver->init_termios = tty_std_termios;
gb_tty_driver->init_termios.c_cflag = B9600 | CS8 |
CREAD | HUPCL | CLOCAL;
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index dd5e8a850f6ec..4124603a0b44f 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3272,14 +3272,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
goto err_put;
if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
- /*
- * Free any saved termios data so that the termios state is
- * reset when reusing a minor number.
- */
- tp = driver->termios[index];
- if (tp) {
- driver->termios[index] = NULL;
- kfree(tp);
+ if (driver->flags & TTY_DRIVER_RESET_SAVED_TERMIOS) {
+ /*
+ * Free any saved termios data so that the termios
+ * state is reset when reusing a minor number.
+ */
+ tp = driver->termios[index];
+ if (tp) {
+ driver->termios[index] = NULL;
+ kfree(tp);
+ }
}
retval = tty_cdev_add(driver, devt, index, 1);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index bbb31a074c35e..80e86fa38eabe 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -2119,7 +2119,7 @@ static int __init acm_init(void)
{
int retval;
acm_tty_driver = tty_alloc_driver(ACM_TTY_MINORS, TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV);
+ TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_SAVED_TERMIOS);
if (IS_ERR(acm_tty_driver))
return PTR_ERR(acm_tty_driver);
acm_tty_driver->driver_name = "acm",
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 2b3b7b10f7382..eb3c9f626e5d6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1321,7 +1321,8 @@ static int __init usb_serial_init(void)
int result;
usb_serial_tty_driver = tty_alloc_driver(USB_SERIAL_TTY_MINORS,
- TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
+ TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV |
+ TTY_DRIVER_RESET_SAVED_TERMIOS);
if (IS_ERR(usb_serial_tty_driver))
return PTR_ERR(usb_serial_tty_driver);
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index ff5791373cf96..1e5241b823856 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -542,6 +542,11 @@ static inline void tty_set_operations(struct tty_driver *driver,
* Do not create numbered ``/dev`` nodes. For example, create
* ``/dev/ttyprintk`` and not ``/dev/ttyprintk0``. Applicable only when a
* driver for a single tty device is being allocated.
+ *
+ * TTY_DRIVER_RESET_SAVED_TERMIOS
+ * Reset any saved termios settings on device registration when reusing a
+ * minor number. Must only be set by drivers that guarantee that the minor
+ * number is no longer in use.
*/
#define TTY_DRIVER_INSTALLED 0x0001
#define TTY_DRIVER_RESET_TERMIOS 0x0002
@@ -551,6 +556,7 @@ static inline void tty_set_operations(struct tty_driver *driver,
#define TTY_DRIVER_HARDWARE_BREAK 0x0020
#define TTY_DRIVER_DYNAMIC_ALLOC 0x0040
#define TTY_DRIVER_UNNUMBERED_NODE 0x0080
+#define TTY_DRIVER_RESET_SAVED_TERMIOS 0x0200
/* tty driver types */
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0375/1887] perf: Require kernel access for text poke events
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (373 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0374/1887] tty: fix saved termios reset race Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0376/1887] arm64/fpsimd: signal: Forbid non-streaming SVE payload on SME-only systems Greg Kroah-Hartman
` (623 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhengchuan Liang,
Peter Zijlstra (Intel), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengchuan Liang <zcliangcn@gmail.com>
[ Upstream commit 357e8a77a501d96c9517f01f4a211eed5e9c9184 ]
Perf events with exclude_kernel=1 can be opened without kernel perf
access. However, exclude_kernel does not suppress text-poke sideband
records. Every PERF_RECORD_TEXT_POKE is marked PERF_RECORD_MISC_KERNEL
and contains a raw kernel instruction address.
An unprivileged task can therefore open and mmap a task-local software
event with text_poke=1. Both opening a count-only tracepoint event and
configuring UDP GRO for ESP-in-UDP cause updates to inline static calls;
the observer receives the relocated addresses of the modified instructions.
For a known kernel image, any such address reveals the runtime kernel
text base despite KASLR.
Call perf_allow_kernel() whenever attr.text_poke is set, regardless of
exclude_kernel. Events that neither monitor kernel execution nor request
text-poke records retain their existing permissions.
Fixes: e17d43b93e54 ("perf: Add perf text poke event")
Assisted-by: LLM
Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/99131354c41e23188f778b92f90363775b482395.1790573390.git.zcliangcn@gmail.com
[ sashal: adjusted context around the simpler exclude_kernel check that calls perf_allow_kernel(&attr) ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 013c3a4afb8a3..a64e0254e803c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -12458,7 +12458,7 @@ SYSCALL_DEFINE5(perf_event_open,
if (err)
return err;
- if (!attr.exclude_kernel) {
+ if (!attr.exclude_kernel || attr.text_poke) {
err = perf_allow_kernel(&attr);
if (err)
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0376/1887] arm64/fpsimd: signal: Forbid non-streaming SVE payload on SME-only systems
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (374 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0375/1887] perf: Require kernel access for text poke events Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0377/1887] arm64: errata: Factor out broken AMU const counter cap Greg Kroah-Hartman
` (622 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Rutland, Mark Brown,
Catalin Marinas, Will Deacon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <mark.rutland@arm.com>
[ Upstream commit e060d9069b49fe55f38057dfe592068014652671 ]
When system_supports_sme() is true but system_supports_sve() is false,
restoring a specifically crafted SVE signal context can result in the
task erroneously having non-streaming SVE state. Subsequent attempts to
manipulate the task's FPSIMD/SVE/SME state can result in a variety of
problems, including fatal EL1 UNDEFs.
In such configurations, the kernel always creates an SVE signal context
when delivering a signal, and this can only be in one of two states:
(1) SVE_SIG_FLAG_SM is set, and an SVE payload is present containing
streaming mode SVE state. The recorded VL is the task's live
streaming VL.
(2) SVE_SIG_FLAG_SM is clear, and an SVE payload is not present. The
FPSIMD context contains the non-streaming mode FPSIMD state. The
recorded VL is 0.
Currently restore_sve_fpsimd_context() correctly rejects cases where
SVE_SIG_FLAG_SM is set and an SVE payload is not present, but fails to
reject cases where SVE_SIG_FLAG_SM is clear and an SVE payload is
present. Consequently, restore_sve_fpsimd_context() can place the task
in a state where it has non-streaming SVE state even when this is not
supported by HW.
For example, this can cause a later EL1 UNDEF when the kernel attempts to
restore the task's ZCR_EL1 value:
| # ./sme-sigcontext-to-sve
| Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP
| Modules linked in:
| CPU: 0 UID: 0 PID: 131 Comm: sme-sigcontext- Not tainted 7.3.0-rc1 #1 PREEMPT
| Hardware name: linux,dummy-virt (DT)
| pstate: 61402009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : fpsimd_restore_current_state+0x258/0x458
| lr : exit_to_user_mode_loop+0xb8/0x188
| sp : ffff80008056be40
| x29: ffff80008056be40 x28: fff00000c1670000 x27: 0000000000000000
| x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
| x23: ffff80008056bec0 x22: 0000000000000008 x21: 0000000000000040
| x20: 0000000000000081 x19: 0000000008800010 x18: 0000000000000000
| x17: 0000fffffd412570 x16: 0000000000001000 x15: 0000fffffd4123b0
| x14: 0000fffffd412780 x13: 0000fffffd412be8 x12: 0000000047435300
| x11: 0000fffffd412570 x10: 0000000000000000 x9 : 0000000045585401
| x8 : fff00000c18a6c44 x7 : 0000000000000000 x6 : 0000000000000002
| x5 : 0000000000000002 x4 : ffff800080568000 x3 : 0000000000000001
| x2 : 0000000008800010 x1 : fff00000c1670000 x0 : 0000000008800000
| Call trace:
| fpsimd_restore_current_state+0x258/0x458 (P)
| exit_to_user_mode_loop+0xb8/0x188
| el0_svc+0x1cc/0x1d0
| el0t_64_sync_handler+0xa0/0xe4
| el0t_64_sync+0x198/0x19c
| Code: d5384101 f9400020 53175c03 36b80de0 (d5381202)
| ---[ end trace 0000000000000000 ]---
| Kernel panic - not syncing: Oops - Undefined instruction: Fatal exception in interrupt
| Kernel Offset: 0x291fb1000000 from 0xffff800080000000
| PHYS_OFFSET: 0x40000000
| CPU features: 0x0,00000000,0052802f,ffb88f43,3afcf73f
| Memory Limit: none
Rework restore_sve_fpsimd_context() to reject cases where
SVE_SIG_FLAG_SM is clear and an SVE payload is not present. As
parse_user_sigframe() rejects SVE signal frames when neither SVE nor SME
are supported, it isn't necessary for restore_sve_fpsimd_context() to
handle the case where neither are supported.
Fixes: 7dde62f0687c ("arm64/signal: Always accept SVE signal frames on SME only systems")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
[ sashal: Used the copied sve.head.size instead of the unavailable user->sve_size field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/signal.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 9fd7f78d11d1e..b00bf1a415400 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -271,22 +271,37 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
unsigned int vl, vq;
struct user_fpsimd_state fpsimd;
struct sve_context sve;
+ bool fpsimd_only;
if (__copy_from_user(&sve, user->sve, sizeof(sve)))
return -EFAULT;
+ fpsimd_only = (sve.head.size <= sizeof(*user->sve));
+
if (sve.flags & SVE_SIG_FLAG_SM) {
if (!system_supports_sme())
return -EINVAL;
+ /*
+ * Streaming SVE state is always preserved with an SVE payload.
+ * Only accept streaming state which has an SVE payload.
+ */
+ if (fpsimd_only)
+ return -EINVAL;
+
vl = task_get_sme_vl(current);
} else {
/*
- * A SME only system use SVE for streaming mode so can
- * have a SVE formatted context with a zero VL and no
- * payload data.
+ * Non-streaming SVE state may be preserved without an SVE
+ * payload, in which case all state is saved in the FPSIMD
+ * context.
+ *
+ * On SME-only systems, non-streaming (FPSIMD-only) state is
+ * always preserved without an SVE payload, and with VL==0. On
+ * such systems, only accept non-streaming state without an SVE
+ * payload.
*/
- if (!system_supports_sve() && !system_supports_sme())
+ if (!system_supports_sve() && !fpsimd_only)
return -EINVAL;
vl = task_get_sve_vl(current);
@@ -295,7 +310,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (sve.vl != vl)
return -EINVAL;
- if (sve.head.size <= sizeof(*user->sve)) {
+ if (fpsimd_only) {
clear_thread_flag(TIF_SVE);
current->thread.svcr &= ~SVCR_SM_MASK;
current->thread.fp_type = FP_STATE_FPSIMD;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0377/1887] arm64: errata: Factor out broken AMU const counter cap
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (375 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0376/1887] arm64/fpsimd: signal: Forbid non-streaming SVE payload on SME-only systems Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0378/1887] arm64: errata: Add Cortex-A725 erratum 3821522 workaround Greg Kroah-Hartman
` (621 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Beata Michalska, Vladimir Murzin,
Will Deacon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beata Michalska <beata.michalska@arm.com>
[ Upstream commit 573371caf7aea8582212da81dcead2c3f48fac4b ]
Move the workaround from the erratum 2457168-specific cpucap to a generic
broken AMU constant-counter one. This keeps the existing Cortex-A510
handling unchanged while allowing other errata with similar AMU constant
counter issue to share the capability bit and call sites.
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
[ Beata: Skipped comment updated on amu_read_core_const_ctrs, as that functionality is not available here. Otherwise unmodified. ]
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/Kconfig | 8 ++++++++
arch/arm64/kernel/cpu_errata.c | 20 ++++++++++++++------
arch/arm64/kernel/cpufeature.c | 2 +-
arch/arm64/kernel/topology.c | 2 +-
arch/arm64/tools/cpucaps | 2 +-
5 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9cb8867eb1205..370bde2b2b07b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -966,9 +966,17 @@ config ARM64_ERRATUM_1902691
If unsure, say Y.
+config ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
+ bool
+ # Targeting errata affecting AMEVCNTR01, the AMU constant counter.
+ # On affected CPUs the counter may not increment at the expected rate,
+ # making it unreliable. As a result, AMU users should treat it as
+ # unavailable rather than relying on misleading counter values.
+
config ARM64_ERRATUM_2457168
bool "Cortex-A510: 2457168: workaround for AMEVCNTR01 incrementing incorrectly"
depends on ARM64_AMU_EXTN
+ select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
default y
help
This option adds the workaround for ARM Cortex-A510 erratum 2457168.
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cff85a371c353..518e3b6877b53 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -275,6 +275,16 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
};
#endif
+#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
+static const struct midr_range workaround_amu_constcnt_list[] = {
+#ifdef CONFIG_ARM64_ERRATUM_2457168
+ /* Cortex-A510 r0p0-r1p1 */
+ MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
+#endif
+ {}
+};
+#endif /* CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT */
+
#ifdef CONFIG_CAVIUM_ERRATUM_23154
static const struct midr_range cavium_erratum_23154_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_THUNDERX),
@@ -737,14 +747,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
},
#endif
-#ifdef CONFIG_ARM64_ERRATUM_2457168
+#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
{
- .desc = "ARM erratum 2457168",
- .capability = ARM64_WORKAROUND_2457168,
+ .desc = "Broken AMU AMEVCNTR01 (const counter)",
+ .capability = ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
-
- /* Cortex-A510 r0p0-r1p1 */
- CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1)
+ CAP_MIDR_RANGE_LIST(workaround_amu_constcnt_list)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2038923
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 547c47358133c..467737615bf31 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1907,7 +1907,7 @@ static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
cpumask_set_cpu(smp_processor_id(), &amu_cpus);
/* 0 reference values signal broken/disabled counters */
- if (!this_cpu_has_cap(ARM64_WORKAROUND_2457168))
+ if (!this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT))
update_freq_counters_refs();
}
}
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 817d788cd8666..d61d1afdee158 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -273,7 +273,7 @@ static void cpu_read_constcnt(void *val)
* the counter is disabled. A return value of 0 at counter read is
* properly handled as an error case by the users of the counter.
*/
- *(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_2457168) ?
+ *(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT) ?
0UL : read_constcnt();
}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index f5c9a4f5f7226..f609e8d939378 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -69,7 +69,6 @@ WORKAROUND_1902691
WORKAROUND_2038923
WORKAROUND_2064142
WORKAROUND_2077057
-WORKAROUND_2457168
WORKAROUND_2658417
WORKAROUND_AMPERE_AC03_CPU_38
WORKAROUND_TRBE_OVERWRITE_FILL_MODE
@@ -88,3 +87,4 @@ WORKAROUND_REPEAT_TLBI
WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+WORKAROUND_BROKEN_AMU_CONSTCNT
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0378/1887] arm64: errata: Add Cortex-A725 erratum 3821522 workaround
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (376 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0377/1887] arm64: errata: Factor out broken AMU const counter cap Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0379/1887] iio: buffer: serialize buffer teardown with mode claims Greg Kroah-Hartman
` (620 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Beata Michalska, Vladimir Murzin,
Will Deacon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beata Michalska <beata.michalska@arm.com>
[ Upstream commit 45f7304679875eb000d67e194090ee7abd05c89c ]
Cortex-A725 erratum 3821522 affects the CNT_CYCLES event, which can
incur a significant increment error when a CPU enters and subsequently
exits WFE or WFI, and may no longer track the system counter
frequency.
The AMEVCNTR01_EL0 counter is used as the AMU constant counter for
frequency invariance and CPPC FFH feedback counters. Wire the affected
Cortex-A725 range into the shared broken AMU constant-counter capability
so the affected counter is treated as unavailable by returning zero in
the AMU counter paths. This prevents the broken counter from being used
as a reference source.
The erratum can also affect PMUv3 users of the CNT_CYCLES event,
but this workaround intentionally does not change PMU event handling.
Hiding or rejecting the PMU event from the erratum code would change
the perf-visible PMU event interface, including raw event selection,
and would need a separate PMU-specific approach rather than being
folded into the AMU reference-counter workaround.
Cc: stable@vger.kernel.org
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/arm64/silicon-errata.rst | 2 ++
arch/arm64/Kconfig | 22 ++++++++++++++++++++++
arch/arm64/kernel/cpu_errata.c | 4 ++++
arch/arm64/kernel/topology.c | 9 +++++----
4 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index fe7b90ac52d7b..74ae9e4f637a7 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -155,6 +155,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A725 | #3821522 | ARM64_ERRATUM_3821522 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #4193791 | ARM64_ERRATUM_4118414 |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 370bde2b2b07b..1b8ee28f23830 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -991,6 +991,28 @@ config ARM64_ERRATUM_2457168
If unsure, say Y.
+config ARM64_ERRATUM_3821522
+ bool "Cortex-A725: 3821522: workaround for possible CNT_CYCLES increment error due to WFE/WFI"
+ depends on ARM64_AMU_EXTN
+ select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
+ default y
+ help
+ This option adds the workaround for ARM Cortex-A725 erratum 3821522.
+
+ On affected A725 cores, the CNT_CYCLES event may incur a significant
+ increment error when entering and subsequently exiting WFx.
+ As a result, the CNT_CYCLES may diverge from the system counter
+ frequency at which it is expected to increment.
+ This renders the AMU counter AMEVCNTR01, that implements CNT_CYCLES,
+ being unreliable and unsuitable for use.
+
+ Since there is no hardware workaround, reads of the affected CNT_CYCLES
+ counter return 0 in the relevant paths. This causes users of the counter
+ to treat it as unavailable and is functionally equivalent to firmware
+ disabling the affected counter.
+
+ If unsure, say Y.
+
config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
bool
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 518e3b6877b53..660b3ff16ebc6 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -280,6 +280,10 @@ static const struct midr_range workaround_amu_constcnt_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_2457168
/* Cortex-A510 r0p0-r1p1 */
MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_3821522
+ /* Cortex-A725 r0p0 - r0p2 */
+ MIDR_RANGE(MIDR_CORTEX_A725, 0, 0, 0, 2),
#endif
{}
};
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index d61d1afdee158..61df0918585ba 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -268,10 +268,11 @@ static void cpu_read_corecnt(void *val)
static void cpu_read_constcnt(void *val)
{
/*
- * Return 0 if the current CPU is affected by erratum 2457168. A value
- * of 0 is also returned if the current CPU does not support AMUs or if
- * the counter is disabled. A return value of 0 at counter read is
- * properly handled as an error case by the users of the counter.
+ * Return 0 if the current CPU is affected by a HW erratum.
+ * A value of 0 is also returned if the current CPU does not
+ * support AMUs or if the counter is disabled. A return
+ * value of 0 at counter read is properly handled as an error
+ * case by the users of the counter.
*/
*(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT) ?
0UL : read_constcnt();
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0379/1887] iio: buffer: serialize buffer teardown with mode claims
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (377 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0378/1887] arm64: errata: Add Cortex-A725 erratum 3821522 workaround Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0380/1887] KVM: arm64: Dont use the VMA to size stage-2 block mappings for VM_PFNMAP Greg Kroah-Hartman
` (619 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron, Jinseob Kim,
Joshua Crofts, Nuno Sá, Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinseob Kim <kimjinseob88@gmail.com>
commit 84bb0fc46ccf6a545b8fdf57cda83770186ed8dd upstream.
Buffer-mode claims hold mlock to guarantee that the device remains in
buffer mode until the claim is released. Normal buffer updates take
info_exist_lock followed by mlock in iio_update_buffers().
However, iio_device_unregister() disables and deactivates all buffers
without taking mlock. This can invalidate buffer state, including
active_scan_mask, while a buffer-mode claim is held.
Take mlock in iio_disable_all_buffers() so that unregister honors the
mode-claim lifetime guarantee. The info_exist_lock -> mlock ordering
matches iio_update_buffers().
Fixes: 0a8565425afd ("iio: core: introduce iio_device_{claim|release}_buffer_mode() APIs")
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Jinseob Kim <kimjinseob88@gmail.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ Backport by Jinseob Kim to 6.1.y: mlock is still in struct iio_dev,
so use indio_dev->mlock instead of iio_dev_opaque->mlock. ]
Signed-off-by: Jinseob Kim <kimjinseob88@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/industrialio-buffer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index af02e52183bec..37ea4a2d85f85 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -1291,6 +1291,8 @@ EXPORT_SYMBOL_GPL(iio_update_buffers);
void iio_disable_all_buffers(struct iio_dev *indio_dev)
{
+ guard(mutex)(&indio_dev->mlock);
+
iio_disable_buffers(indio_dev);
iio_buffer_deactivate_all(indio_dev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0380/1887] KVM: arm64: Dont use the VMA to size stage-2 block mappings for VM_PFNMAP
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (378 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0379/1887] iio: buffer: serialize buffer teardown with mode claims Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0381/1887] fsverity: add dependency on 64K or smaller pages Greg Kroah-Hartman
` (618 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mostafa Saleh, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <smostafa@google.com>
[ Upstream commit 71cc2c67fb8f8d5aa8154eb482e9846d2214f11b ]
get_vma_page_shift() derives the stage-2 block size for VM_PFNMAP VMAs
from the VMA layout alone, which does not necessarily match what
stage-1 maps for that VMA.
Upstream commit 71cc2c67fb8f ("KVM: arm64: Use stage-1 leaf size for
VM_PFNMAP") drops that calculation and lets transparent_hugepage_adjust()
derive the mapping size from the stage-1 leaf instead. The second part
is not applicable here: in this kernel transparent_hugepage_adjust()
takes a reference on the backing struct page, which is not safe for
MMIO, and stage-1 has no huge PFNMAP before v6.12 anyway. Only drop the
VMA-based calculation, so VM_PFNMAP VMAs are mapped at PAGE_SIZE.
Fixes: 2aa53d68cee6 ("KVM: arm64: Try stage2 block mapping for host device MMIO")
Cc: stable@vger.kernel.org
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/mmu.c | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 54ccdcc2dbdf7..2ccc623796429 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1077,32 +1077,11 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
return PAGE_SIZE;
}
-static int get_vma_page_shift(struct vm_area_struct *vma, unsigned long hva)
+static int get_vma_page_shift(struct vm_area_struct *vma)
{
- unsigned long pa;
-
if (is_vm_hugetlb_page(vma) && !(vma->vm_flags & VM_PFNMAP))
return huge_page_shift(hstate_vma(vma));
- if (!(vma->vm_flags & VM_PFNMAP))
- return PAGE_SHIFT;
-
- VM_BUG_ON(is_vm_hugetlb_page(vma));
-
- pa = (vma->vm_pgoff << PAGE_SHIFT) + (hva - vma->vm_start);
-
-#ifndef __PAGETABLE_PMD_FOLDED
- if ((hva & (PUD_SIZE - 1)) == (pa & (PUD_SIZE - 1)) &&
- ALIGN_DOWN(hva, PUD_SIZE) >= vma->vm_start &&
- ALIGN(hva, PUD_SIZE) <= vma->vm_end)
- return PUD_SHIFT;
-#endif
-
- if ((hva & (PMD_SIZE - 1)) == (pa & (PMD_SIZE - 1)) &&
- ALIGN_DOWN(hva, PMD_SIZE) >= vma->vm_start &&
- ALIGN(hva, PMD_SIZE) <= vma->vm_end)
- return PMD_SHIFT;
-
return PAGE_SHIFT;
}
@@ -1214,7 +1193,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
use_read_lock = (fault_status == FSC_PERM && write_fault &&
fault_granule == PAGE_SIZE);
} else {
- vma_shift = get_vma_page_shift(vma, hva);
+ vma_shift = get_vma_page_shift(vma);
}
shared = (vma->vm_flags & VM_SHARED);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0381/1887] fsverity: add dependency on 64K or smaller pages
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (379 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0380/1887] KVM: arm64: Dont use the VMA to size stage-2 block mappings for VM_PFNMAP Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0382/1887] drm/amd/display: check dc_state_create_copy() for NULL in dm_suspend Greg Kroah-Hartman
` (617 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Theodore Tso,
Eric Biggers, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit a300000233a9ff842e2fb450fb9a79f7827a586d upstream.
Currently, all filesystems that support fsverity (ext4, f2fs, and btrfs)
cache the Merkle tree in the pagecache at a 64K aligned offset after the
end of the file data. This offset needs to be a multiple of the page
size, which is guaranteed only when the page size is 64K or smaller.
64K was chosen to be the "largest reasonable page size". But it isn't
the largest *possible* page size: the hexagon and powerpc ports of Linux
support 256K pages, though that configuration is rarely used.
For now, just disable support for FS_VERITY in these odd configurations
to ensure it isn't used in cases where it would have incorrect behavior.
Fixes: 671e67b47e9f ("fs-verity: add Kconfig and the helper functions for hashing")
Reported-by: Christoph Hellwig <hch@lst.de>
Closes: https://lore.kernel.org/r/20260119063349.GA643@lst.de
Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20260221204525.30426-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/verity/Kconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/verity/Kconfig b/fs/verity/Kconfig
index aad1f1d998b9d..6882f85e0a111 100644
--- a/fs/verity/Kconfig
+++ b/fs/verity/Kconfig
@@ -2,6 +2,9 @@
config FS_VERITY
bool "FS Verity (read-only file-based authenticity protection)"
+ # Filesystems cache the Merkle tree at a 64K aligned offset in the
+ # pagecache. That approach assumes the page size is at most 64K.
+ depends on !PAGE_SIZE_256KB
select CRYPTO
select CRYPTO_HASH_INFO
# SHA-256 is implied as it's intended to be the default hash algorithm.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0382/1887] drm/amd/display: check dc_state_create_copy() for NULL in dm_suspend
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (380 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0381/1887] fsverity: add dependency on 64K or smaller pages Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0383/1887] drm/amdgpu: reset VI ASIC on MacBookPro15,1 Greg Kroah-Hartman
` (616 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, George Zhang, Jiangshan Yi,
Dan Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
[ Upstream commit 015e72cde567d2450e282c2790773463156b2d0a ]
dc_state_create_copy() can return NULL on allocation failure.
dm_suspend() only conditionally skips dm_gpureset_toggle_interrupts()
and continues execution, returning success. dm_resume() then
dereferences the NULL cached_dc_state in link_enc_cfg_copy() and the
following dc_state->stream_count loop, crashing during GPU reset
recovery.
Return -ENOMEM immediately if the copy fails, so the caller aborts
suspend instead of leaving a NULL cached state for resume.
Fixes: 8092aa3ab8f7 ("drm/amd/display: Add null checker before passing variables")
Reviewed-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 84b6d7932fdd2857795a257f9f258562a3cddcab)
Cc: stable@vger.kernel.org
[ sashal: Adapted context from dc_state_create_copy() to the existing dc_copy_state() call. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index deaf98957cb76..86282119252bd 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2645,9 +2645,14 @@ static int dm_suspend(void *handle)
dc_allow_idle_optimizations(adev->dm.dc, false);
dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
+ if (!dm->cached_dc_state) {
+ drm_err(adev_to_drm(adev),
+ "Failed to allocate cached DC state during suspend\n");
+ mutex_unlock(&dm->dc_lock);
+ return -ENOMEM;
+ }
- if (dm->cached_dc_state)
- dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
+ dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
amdgpu_dm_commit_zero_streams(dm->dc);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0383/1887] drm/amdgpu: reset VI ASIC on MacBookPro15,1
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (381 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0382/1887] drm/amd/display: check dc_state_create_copy() for NULL in dm_suspend Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0384/1887] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Greg Kroah-Hartman
` (615 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frederick Morlock, Andre Eikmeyer,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Eikmeyer <dev@deq.rocks>
[ Upstream commit a5be7ad8f5f0e067613e9197638f216f46252946 ]
After S3, reloading amdgpu on MacBookPro15,1 systems with a Radeon Pro
555X or 560X fails while loading the SMU firmware. The existing SMC
register check does not request a reset because the registers do not
reliably reflect the stale SMU state on these machines.
Frederick Morlock found that forcing a VI ASIC reset allows the driver to
initialize again. This patch limits his workaround to the exact PCI
device, Apple subsystem device and revision combinations used by these
two GPUs, leaving other VI hardware unchanged.
Suggested-by: Frederick Morlock <me@freddy.us>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: a22e5e4f2ebb ("drm/amdgpu: reset VI ASIC on MacBookPro14,3")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/vi.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 1bfd7b49fe9c3..c6f77e5207be6 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1432,10 +1432,30 @@ static uint64_t vi_get_pcie_replay_count(struct amdgpu_device *adev)
return (nak_r + nak_g);
}
+struct vi_reset_quirk {
+ u16 device;
+ u16 subsystem_vendor;
+ u16 subsystem_device;
+ u8 revision;
+};
+
+static const struct vi_reset_quirk vi_reset_quirks[] = {
+ { 0x67ef, PCI_VENDOR_ID_APPLE, 0x0190, 0xe3 }, /* Radeon Pro 555X */
+ { 0x67ef, PCI_VENDOR_ID_APPLE, 0x018f, 0xc2 }, /* Radeon Pro 560X */
+};
+
static bool vi_need_reset_on_init(struct amdgpu_device *adev)
{
+ unsigned int i;
u32 clock_cntl, pc;
+ for (i = 0; i < ARRAY_SIZE(vi_reset_quirks); i++)
+ if (adev->pdev->device == vi_reset_quirks[i].device &&
+ adev->pdev->subsystem_vendor == vi_reset_quirks[i].subsystem_vendor &&
+ adev->pdev->subsystem_device == vi_reset_quirks[i].subsystem_device &&
+ adev->pdev->revision == vi_reset_quirks[i].revision)
+ return true;
+
if (adev->flags & AMD_IS_APU)
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0384/1887] drm/amdgpu: reset VI ASIC on MacBookPro14,3
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (382 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0383/1887] drm/amdgpu: reset VI ASIC on MacBookPro15,1 Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0385/1887] usb: ohci-spear: Remove unnecessary NULL check before clk_disable_unprepare() Greg Kroah-Hartman
` (614 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Alex Deucher,
Francisco Beltrán Millalén, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
[ Upstream commit a22e5e4f2ebbdbb962cc3233094d189c4dfaa051 ]
On a MacBookPro14,3 with a Radeon Pro 555 (Polaris11), the framebuffer
is at MC address 0 when amdgpu loads after a cold boot, as the firmware
leaves it (MC_VM_FB_LOCATION = 0x007f0000), while the VBIOS ASIC_Init
table places it at 0xF4_0000_0000 (0xf47ff400). amdgpu reads the
location once, at init, so after a re-POST (S3 resume or GPU reset)
the framebuffer has moved and the driver keeps programming the old
one: the SMU is handed a table that was never written and the GPU
does not come back, which leaves the internal panel black.
Resetting the ASIC on load makes ASIC_Init run before the driver reads
the location, so the driver uses the VBIOS placement from the start and
every later re-POST puts the framebuffer back where it already is.
Add the Radeon Pro 555 used in this machine to the existing VI reset
quirk table.
Tested on a MacBookPro14,3 on 6.18.49 with the quirk table backported
(the kernel also carries unrelated local PCI and ACPI patches for this
machine). The framebuffer is at 0x000000F400000000 after both cold and
warm boot, and the GPU survived 9 S3 cycles (lid close and rtcwake, one
of them with the lid closed for about 7.5 minutes and a USB-C disk
attached), each followed by a few minutes of 3D load; no ring timeouts
or VM faults were reported. The reset adds about 0.23 s to amdgpu init.
Suggested-by: Christian König <christian.koenig@amd.com>
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b6b1d97218518003107d4446fac278fa3e0a19a0)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/vi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index c6f77e5207be6..4ad7db4e414db 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1442,6 +1442,7 @@ struct vi_reset_quirk {
static const struct vi_reset_quirk vi_reset_quirks[] = {
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x0190, 0xe3 }, /* Radeon Pro 555X */
{ 0x67ef, PCI_VENDOR_ID_APPLE, 0x018f, 0xc2 }, /* Radeon Pro 560X */
+ { 0x67ef, PCI_VENDOR_ID_APPLE, 0x017a, 0xc7 }, /* Radeon Pro 555 */
};
static bool vi_need_reset_on_init(struct amdgpu_device *adev)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0385/1887] usb: ohci-spear: Remove unnecessary NULL check before clk_disable_unprepare()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (383 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0384/1887] drm/amdgpu: reset VI ASIC on MacBookPro14,3 Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0386/1887] usb: ohci-spear: disable controller wakeup on removal Greg Kroah-Hartman
` (613 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chen Ni, Alan Stern, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni <nichen@iscas.ac.cn>
[ Upstream commit a891b9aebcc7406fe2f439d184bac3948fb08645 ]
clk_disable_unprepare() already checks NULL by using IS_ERR_OR_NULL.
Remove unneeded NULL check for clk here.
Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20250617042050.1930940-1-nichen@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: b1b0f8bdbbc8 ("usb: ohci-spear: disable controller wakeup on removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/ohci-spear.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 196951a27f3f2..0f646c35ca737 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -104,8 +104,7 @@ static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
struct spear_ohci *sohci_p = to_spear_ohci(hcd);
usb_remove_hcd(hcd);
- if (sohci_p->clk)
- clk_disable_unprepare(sohci_p->clk);
+ clk_disable_unprepare(sohci_p->clk);
usb_put_hcd(hcd);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0386/1887] usb: ohci-spear: disable controller wakeup on removal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (384 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0385/1887] usb: ohci-spear: Remove unnecessary NULL check before clk_disable_unprepare() Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0387/1887] USB: dwc2: shut down wakeup timer before freeing HCD state Greg Kroah-Hartman
` (612 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
Alan Stern, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit b1b0f8bdbbc891a4ee7f3b1a878c633e02b7bbeb ]
Probe enables controller wakeup after the OHCI core marks controllers with
RemoteWakeupConnected as wakeup-capable. Removal does not undo this, so the
wakeup source can remain attached after driver unbind.
Disable controller wakeup after removing the HCD.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: a6eeeb9f45b5 ("USB: Update USB default wakeup settings")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260915012011.61874-4-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/ohci-spear.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 0f646c35ca737..47f590bdc1aa0 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -104,6 +104,7 @@ static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
struct spear_ohci *sohci_p = to_spear_ohci(hcd);
usb_remove_hcd(hcd);
+ device_wakeup_disable(hcd->self.controller);
clk_disable_unprepare(sohci_p->clk);
usb_put_hcd(hcd);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0387/1887] USB: dwc2: shut down wakeup timer before freeing HCD state
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (385 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0386/1887] usb: ohci-spear: disable controller wakeup on removal Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0388/1887] usb: typec: ucsi: acpi: Assume UCSI 1.2 on Acer Nitro ANV15-41 Greg Kroah-Hartman
` (611 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Runyu Xiao, Thinh Nguyen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
[ Upstream commit fd772af9512cdecb83de34a461801533828e77fd ]
dwc2_wakeup_detected() accesses the DWC2 host state and can rearm the
wakeup timer. dwc2_hcd_free() currently deletes the timer only after
freeing host-owned state, and timer_delete() does not synchronize a
callback or prevent it from being queued again.
Stop and shut down the timer in dwc2_hcd_release(), before the HCD
resources are freed. This covers both the HCD initialization error path
and normal HCD removal.
Fixes: 7359d482eb4d ("staging: HCD files for the DWC2 driver")
Cc: stable <stable@kernel.org>
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20260904065323.4047026-1-runyu.xiao@seu.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: adapted timer_delete() removal to the existing del_timer() call ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/dwc2/hcd.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index e0f84726f4b1d..5e71094a22b2f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5082,14 +5082,13 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg)
}
cancel_work_sync(&hsotg->phy_reset_work);
-
- del_timer(&hsotg->wkp_timer);
}
static void dwc2_hcd_release(struct dwc2_hsotg *hsotg)
{
/* Turn off all host-specific interrupts */
dwc2_disable_host_interrupts(hsotg);
+ timer_shutdown_sync(&hsotg->wkp_timer);
dwc2_hcd_free(hsotg);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0388/1887] usb: typec: ucsi: acpi: Assume UCSI 1.2 on Acer Nitro ANV15-41
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (386 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0387/1887] USB: dwc2: shut down wakeup timer before freeing HCD state Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0389/1887] tty: tty_port: restore TTY_IO_ERROR on activation failure Greg Kroah-Hartman
` (610 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Pannarat Wiriyaarritham,
Heikki Krogerus, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pannarat Wiriyaarritham <pannarat.wiriyaarritham@danielcorp.dev>
[ Upstream commit 8c51ea651d043c786c37668c51624bd6b338a0ef ]
The Acer Nitro ANV15-41 exposes a functional UCSI ACPI PPM but
reports a UCSI VERSION value of zero.
ucsi_register() rejects a zero version with -ENODEV, leaving the
system without registered USB Type-C connectors.
The PPM works correctly when using the UCSI 1.2 layout. With UCSI
1.2 assumed, both Type-C connectors register correctly and USB Power
Delivery negotiation works.
Add a DMI-specific UCSI operation for the Acer Nitro ANV15-41 that
substitutes UCSI 1.2 only when firmware reports a zero version.
Preserve any valid non-zero firmware version.
Tested on an Acer Nitro ANV15-41 with BIOS V1.51.
Fixes: c1b0bc2dabfa ("usb: typec: Add support for UCSI interface")
Cc: stable <stable@kernel.org>
Assisted-by: LLM
Signed-off-by: Pannarat Wiriyaarritham <pannarat.wiriyaarritham@danielcorp.dev>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260910023338.31816-1-pannarat.wiriyaarritham@danielcorp.dev
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: Adapted the dedicated read_version() callback to the generic read() interface with offset and length checks. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi_acpi.c | 32 ++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 03c820fe5b0c4..eeb457ff255e4 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -106,6 +106,31 @@ static const struct ucsi_operations ucsi_acpi_ops = {
.async_write = ucsi_acpi_async_write
};
+static int ucsi_acer_read(struct ucsi *ucsi, unsigned int offset,
+ void *val, size_t val_len)
+{
+ struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+ u16 *version = val;
+ int ret;
+
+ ret = ucsi_acpi_read(ucsi, offset, val, val_len);
+ if (ret)
+ return ret;
+
+ if (offset == UCSI_VERSION && val_len == sizeof(*version) && !*version) {
+ dev_warn(ua->dev, "UCSI version is zero, assuming 1.2\n");
+ *version = 0x0120;
+ }
+
+ return 0;
+}
+
+static const struct ucsi_operations ucsi_acer_ops = {
+ .read = ucsi_acer_read,
+ .sync_write = ucsi_acpi_sync_write,
+ .async_write = ucsi_acpi_async_write
+};
+
static int
ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len)
{
@@ -173,6 +198,13 @@ static const struct ucsi_operations ucsi_dell_ops = {
};
static const struct dmi_system_id ucsi_acpi_quirks[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Nitro ANV15-41"),
+ },
+ .driver_data = (void *)&ucsi_acer_ops,
+ },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0389/1887] tty: tty_port: restore TTY_IO_ERROR on activation failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (387 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0388/1887] usb: typec: ucsi: acpi: Assume UCSI 1.2 on Acer Nitro ANV15-41 Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0390/1887] tty: serial: max3100: shut down timer before freeing port Greg Kroah-Hartman
` (609 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Johan Hovold, Sasha Levin, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 56964f6a31238fb41d5830bb42520c5b10ff7d8f ]
Make sure to restore the TTY_IO_ERROR flag if activation fails to
prevent I/O attempts on a port that is gone or powered down.
This specifically avoids issues like kernel panic due to unclocked
accesses or NULL-pointer dereferences when accessing powered down or
deregistered ports when a TTY ioctl races with hangup and open.
Note that the flag is set again in tty_port_close() but not restoring it
on activation failure leaves a window where drivers fail to handle the
ioctl-hangup race.
Fixes: a9a37ec33a1b ("tty: tty_port: Move the IO_ERROR clear")
Cc: stable <stable@kernel.org> # 2.6.33
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260908084000.218528-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: Adapted to the existing braced error block with explicit mutex_unlock(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/tty_port.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 494500c453ccb..6f3b4eeb44b38 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -783,6 +783,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
int retval = port->ops->activate(port, tty);
if (retval) {
+ set_bit(TTY_IO_ERROR, &tty->flags);
mutex_unlock(&port->mutex);
return retval;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0390/1887] tty: serial: max3100: shut down timer before freeing port
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (388 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0389/1887] tty: tty_port: restore TTY_IO_ERROR on activation failure Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0391/1887] serial: fix TIOCMIWAIT race Greg Kroah-Hartman
` (608 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Sasha Levin, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit db0949bbd06db0a75b4b1076f1e25194be7d956a ]
max3100_shutdown() stops the polling timer but returns early during
system suspend. If the SPI device is unbound before resume, the serial
core does not call max3100_shutdown() again, so max3100_remove() frees
the port while the timer remains armed. max3100_timeout() may then
access the freed port and re-arm the timer.
Add final timer teardown to max3100_remove() and use
timer_shutdown_sync() to prevent a racing callback from re-arming it.
Also free the IRQ and destroy the workqueue there before freeing the
port. Keep timer_delete_sync() in max3100_shutdown() so that a
subsequent open() can re-arm the timer.
The workqueue is created before request_irq() and destroyed on both
request_irq() failure and normal shutdown. Its presence at remove thus
identifies the IRQ left registered when suspend bypasses shutdown.
Free the IRQ before destroying the workqueue, in both
max3100_shutdown() and max3100_remove(), and cancel the pending work
in between. free_irq() waits for a running interrupt handler to
finish and no new handler can start afterwards, so a racing handler
cannot queue work on a workqueue that is being destroyed; the
force_end_work check in max3100_dowork() only narrows that window, as
a handler delayed between the check and queue_work() could still run
after the teardown has cleared the workqueue pointer. Cancelling the
work also keeps destroy_workqueue() from waiting on a queued work item
in case remove() ever runs while the freezable workqueue is still
frozen, e.g. device removal during the resume window, before
workqueues are thawed.
This issue was found by an in-house static analysis tool.
Fixes: 7831d56b0a35 ("tty: MAX3100")
Cc: stable@kernel.org # 6.2+
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260927055957.561030-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: Changed free_irq() calls to use s->irq instead of the uart_port IRQ field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/max3100.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index 67803242a70c2..4ba444460753c 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -568,11 +568,11 @@ static void max3100_shutdown(struct uart_port *port)
del_timer_sync(&s->timer);
if (s->workqueue) {
+ free_irq(s->irq, s);
+ cancel_work_sync(&s->work);
destroy_workqueue(s->workqueue);
s->workqueue = NULL;
}
- if (s->irq)
- free_irq(s->irq, s);
/* set shutdown mode to save power */
if (s->max3100_hw_suspend)
@@ -831,6 +831,15 @@ static void max3100_remove(struct spi_device *spi)
if (max3100s[i] == s) {
dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i);
uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port);
+
+ s->force_end_work = 1;
+ timer_shutdown_sync(&s->timer);
+ if (s->workqueue) {
+ free_irq(s->irq, s);
+ cancel_work_sync(&s->work);
+ destroy_workqueue(s->workqueue);
+ s->workqueue = NULL;
+ }
kfree(max3100s[i]);
max3100s[i] = NULL;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0391/1887] serial: fix TIOCMIWAIT race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (389 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0390/1887] tty: serial: max3100: shut down timer before freeing port Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0392/1887] drm/amd/display: Mark DCE 6.4 as not APU Greg Kroah-Hartman
` (607 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, stable, Johan Hovold,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 40adffec8c0090533dfaa863ced7901b60bbf1dc ]
The task state must be updated before checking the wakeup condition to
avoid missing a racing modem status update.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: sashiko-bot@kernel.org
Link: https://lore.kernel.org/r/20260904115542.E20D11F00A3D@smtp.kernel.org
Cc: stable@kernel.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260910130816.642699-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: adjusted context for direct spinlock calls instead of uart_port locking helpers ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/serial_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 2704eb8af5880..dafbd24b91484 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1222,12 +1222,12 @@ static int uart_wait_modem_status(struct uart_state *state, unsigned long arg)
add_wait_queue(&port->delta_msr_wait, &wait);
for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
spin_lock_irq(&uport->lock);
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
spin_unlock_irq(&uport->lock);
- set_current_state(TASK_INTERRUPTIBLE);
-
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0392/1887] drm/amd/display: Mark DCE 6.4 as not APU
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (390 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0391/1887] serial: fix TIOCMIWAIT race Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0393/1887] mtd: spinand: fix NULL pointer dereference with no ECC engine Greg Kroah-Hartman
` (606 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Timur Kristóf,
Mario Limonciello, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <timur.kristof@gmail.com>
[ Upstream commit 3a52d587d1fc8e8bf94ba1b07374f7ec91aaffb4 ]
DCE 6.4 is found in Oland chips, which were advertised
as low-end gaming GPUs in 2013~2015 and then have been
sold as low-end workstation GPUs until 2017~2019.
These are not APUs.
Fixes: 7c15fd86aaec ("drm/amd/display: dc/dce: add initial DCE6 support (v10)")
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260923122033.1046651-3-timur.kristof@gmail.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1072aa811ea1e61d5f763e4ec1bc6d24bb61f14a)
Cc: stable@vger.kernel.org
[ sashal: Adjusted context in dce64_construct() because the debug and configuration default assignments are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
index 8db9f75144662..556c453666a74 100644
--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
@@ -1355,7 +1355,6 @@ static bool dce64_construct(
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 40;
dc->caps.max_cursor_size = 64;
- dc->caps.is_apu = true;
/*************************************************
* Create resources *
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0393/1887] mtd: spinand: fix NULL pointer dereference with no ECC engine
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (391 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0392/1887] drm/amd/display: Mark DCE 6.4 as not APU Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0394/1887] wifi: mac80211: shut down RX BA session timer on teardown Greg Kroah-Hartman
` (605 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nuno Sá, Miquel Raynal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sá <nuno.sa@analog.com>
[ Upstream commit b890e6163761ddb580cc74f43e15f8bbde15647e ]
When "nand-no-ecc-engine" is set in DT, nanddev_get_ecc_engine() takes
the NAND_ECC_ENGINE_TYPE_NONE path and returns success while leaving
nand->ecc.engine NULL. The SPI-NAND code nevertheless dereferences it
unconditionally to test for a pipelined engine, so probing such a
device oopses immediately.
Rather than open-coding the test three times, add a
nand_ecc_is_pipelined() helper to the NAND core that folds the NULL
check into the integration comparison, and use it everywhere. Future
callers then cannot reintroduce the problem.
Fixes: f9d7c7265bcf ("mtd: spinand: Create direct mapping descriptors for ECC operations")
Cc: stable@vger.kernel.org
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
[ sashal: replaced the new nand_ecc_is_pipelined() helper with an inline NULL check in spinand_create_dirmap() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/spi/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 39f9826342966..15c54d61cedbd 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -884,7 +884,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand,
spinand->dirmaps[plane].rdesc = desc;
- if (nand->ecc.engine->integration != NAND_ECC_ENGINE_INTEGRATION_PIPELINED) {
+ if (!nand->ecc.engine ||
+ nand->ecc.engine->integration != NAND_ECC_ENGINE_INTEGRATION_PIPELINED) {
spinand->dirmaps[plane].wdesc_ecc = spinand->dirmaps[plane].wdesc;
spinand->dirmaps[plane].rdesc_ecc = spinand->dirmaps[plane].rdesc;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0394/1887] wifi: mac80211: shut down RX BA session timer on teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (392 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0393/1887] mtd: spinand: fix NULL pointer dereference with no ECC engine Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0395/1887] wifi: mac80211: keep fallback association elements alive Greg Kroah-Hartman
` (604 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Li, Johannes Berg, Sasha Levin,
stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
[ Upstream commit e588e83e5c7a0f6d7a77dbbb58927c8c8cfd598e ]
Tearing down an RX BA session can leave the session timer queued on a
freed tid_rx. Later timer-wheel processing and the timer callback itself
then run against freed memory.
An RX BAR handler can dereference tid_rx under RCU before teardown
unpublishes it and stay in its read-side critical section while teardown
deletes the session timer. The stale handler can then rearm the timer
after timer_delete_sync() returns and before the RCU callback frees
tid_rx.
Use timer_shutdown_sync() so rearm attempts become ineffective once
teardown starts. Keep reorder_timer unchanged: teardown marks the session
removed under reorder_lock and its release path checks that state before
rearming. session_timer has no equivalent guard because
ieee80211_rx_h_ctrl() rearms it before taking reorder_lock.
Fixes: a87f736d942c ("mac80211: use RCU for RX aggregation")
Cc: stable@kernel.org # 5.15+
Assisted-by: LLM sparse kasan
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: Adapted the timer_delete_sync() replacement to the existing del_timer_sync() call. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/agg-rx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 9414d3bbd65f6..acb295bdb71cb 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -103,7 +103,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
if (!tid_rx)
return;
- del_timer_sync(&tid_rx->session_timer);
+ timer_shutdown_sync(&tid_rx->session_timer);
/* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */
spin_lock_bh(&tid_rx->reorder_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0395/1887] wifi: mac80211: keep fallback association elements alive
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (393 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0394/1887] wifi: mac80211: shut down RX BA session timer on teardown Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0396/1887] USB: serial: return errors from break handling Greg Kroah-Hartman
` (603 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Zhao Li, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
[ Upstream commit a10a2f80476d166fd81c361ec0319493671b694e ]
Associating to a non-transmitted MBSSID profile reads freed memory while
determining the operating channel and applying HT capabilities.
When an association response omits WMM, HT, or VHT information,
ieee80211_assoc_config_link() parses the cached BSS IEs and copies the
missing element pointers out of that fallback parse. For a
non-transmitted MBSSID profile those pointers refer to merged-profile
storage owned by the parse object, and the fallback block frees that
object at its end. The copied pointers are used afterwards to determine
the operating channel, configure bandwidth, and apply HT capabilities.
Keep the fallback parse result alive until association setup finishes.
Fixes: 5023b14cf4df ("mac80211: support profile split between elements")
Cc: stable@kernel.org
Assisted-by: LLM sparse kasan
[reorder variable declaration]
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: adjusted context for the existing conn_flags-based VHT check ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mlme.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 32f24dca40ab5..56120762c7fbf 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4023,6 +4023,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
bool is_s1g = cbss->channel->band == NL80211_BAND_S1GHZ;
const struct cfg80211_bss_ies *bss_ies = NULL;
+ struct ieee802_11_elems *bss_elems = NULL;
struct ieee80211_supported_band *sband;
struct ieee802_11_elems *elems;
u16 capab_info;
@@ -4059,7 +4060,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
(!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT) &&
(!elems->vht_cap_elem || !elems->vht_operation)))) {
const struct cfg80211_bss_ies *ies;
- struct ieee802_11_elems *bss_elems;
rcu_read_lock();
ies = rcu_dereference(cbss->ies);
@@ -4115,8 +4115,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
sdata_info(sdata,
"AP bug: VHT operation missing from AssocResp\n");
}
-
- kfree(bss_elems);
}
/*
@@ -4343,6 +4341,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
ret = true;
out:
kfree(elems);
+ kfree(bss_elems);
kfree(bss_ies);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0396/1887] USB: serial: return errors from break handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (394 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0395/1887] wifi: mac80211: keep fallback association elements alive Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0397/1887] USB: serial: report unsupported break signalling Greg Kroah-Hartman
` (602 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Corey Minyard, Johan Hovold,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 6ff58ae17fd9523246a260434133ed9ab7f56df2 ]
Start propagating errors to user space when setting the break state
fails.
This will be used by follow-on changes to also report when a driver or
device does not support break control.
Tested-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Stable-dep-of: ae0e61d95677 ("USB: serial: fix ioctl hangup race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/serial/ark3116.c | 7 +++--
drivers/usb/serial/belkin_sa.c | 12 ++++++---
drivers/usb/serial/ch341.c | 37 +++++++++++++++++----------
drivers/usb/serial/cp210x.c | 8 +++---
drivers/usb/serial/digi_acceleport.c | 7 ++---
drivers/usb/serial/f81232.c | 4 ++-
drivers/usb/serial/f81534.c | 4 ++-
drivers/usb/serial/ftdi_sio.c | 10 +++++---
drivers/usb/serial/io_edgeport.c | 6 +++--
drivers/usb/serial/io_ti.c | 9 +++++--
drivers/usb/serial/keyspan.c | 5 +++-
drivers/usb/serial/keyspan_pda.c | 8 ++++--
drivers/usb/serial/mct_u232.c | 6 ++---
drivers/usb/serial/mos7720.c | 9 ++++---
drivers/usb/serial/mos7840.c | 7 ++---
drivers/usb/serial/mxuport.c | 6 ++---
drivers/usb/serial/pl2303.c | 14 ++++++----
drivers/usb/serial/quatech2.c | 8 ++++--
drivers/usb/serial/ti_usb_3410_5052.c | 10 +++++---
drivers/usb/serial/upd78f0730.c | 7 +++--
drivers/usb/serial/usb-serial.c | 2 +-
drivers/usb/serial/usb_debug.c | 13 +++++++---
drivers/usb/serial/whiteheat.c | 7 ++---
drivers/usb/serial/xr_serial.c | 4 +--
include/linux/usb/serial.h | 2 +-
25 files changed, 140 insertions(+), 72 deletions(-)
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 9452291f17033..67a07cc007f09 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -433,10 +433,11 @@ static int ark3116_tiocmset(struct tty_struct *tty,
return 0;
}
-static void ark3116_break_ctl(struct tty_struct *tty, int break_state)
+static int ark3116_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct ark3116_private *priv = usb_get_serial_port_data(port);
+ int ret;
/* LCR is also used for other things: protect access */
mutex_lock(&priv->hw_lock);
@@ -446,9 +447,11 @@ static void ark3116_break_ctl(struct tty_struct *tty, int break_state)
else
priv->lcr &= ~UART_LCR_SBC;
- ark3116_write_reg(port->serial, UART_LCR, priv->lcr);
+ ret = ark3116_write_reg(port->serial, UART_LCR, priv->lcr);
mutex_unlock(&priv->hw_lock);
+
+ return ret;
}
static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 0c7f7d090483c..cda3295d68cf1 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -46,7 +46,7 @@ static void belkin_sa_process_read_urb(struct urb *urb);
static void belkin_sa_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
const struct ktermios *old_termios);
-static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
+static int belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
static int belkin_sa_tiocmget(struct tty_struct *tty);
static int belkin_sa_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
@@ -402,13 +402,19 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
+static int belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
+ int ret;
- if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
+ ret = BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0);
+ if (ret < 0) {
dev_err(&port->dev, "Set break_ctl %d\n", break_state);
+ return ret;
+ }
+
+ return 0;
}
static int belkin_sa_tiocmget(struct tty_struct *tty)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 6e1b87e673046..612bea504d7a8 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -562,12 +562,12 @@ static void ch341_set_termios(struct tty_struct *tty,
* TCSBRKP. Due to how the simulation is implemented the duration can't be
* controlled. The duration is always about (1s / 46bd * 9bit) = 196ms.
*/
-static void ch341_simulate_break(struct tty_struct *tty, int break_state)
+static int ch341_simulate_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned long now, delay;
- int r;
+ int r, r2;
if (break_state != 0) {
dev_dbg(&port->dev, "enter break state requested\n");
@@ -599,7 +599,7 @@ static void ch341_simulate_break(struct tty_struct *tty, int break_state)
*/
priv->break_end = jiffies + (11 * HZ / CH341_MIN_BPS);
- return;
+ return 0;
}
dev_dbg(&port->dev, "leave break state requested\n");
@@ -615,17 +615,22 @@ static void ch341_simulate_break(struct tty_struct *tty, int break_state)
schedule_timeout_interruptible(delay);
}
+ r = 0;
restore:
/* Restore original baud rate */
- r = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate,
- priv->lcr);
- if (r < 0)
+ r2 = ch341_set_baudrate_lcr(port->serial->dev, priv, priv->baud_rate,
+ priv->lcr);
+ if (r2 < 0) {
dev_err(&port->dev,
"restoring original baud rate of %u failed: %d\n",
- priv->baud_rate, r);
+ priv->baud_rate, r2);
+ return r2;
+ }
+
+ return r;
}
-static void ch341_break_ctl(struct tty_struct *tty, int break_state)
+static int ch341_break_ctl(struct tty_struct *tty, int break_state)
{
const uint16_t ch341_break_reg =
((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK;
@@ -635,17 +640,17 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
uint16_t reg_contents;
uint8_t break_reg[2];
- if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) {
- ch341_simulate_break(tty, break_state);
- return;
- }
+ if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK)
+ return ch341_simulate_break(tty, break_state);
r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,
ch341_break_reg, 0, break_reg, 2);
if (r) {
dev_err(&port->dev, "%s - USB control read error (%d)\n",
__func__, r);
- return;
+ if (r > 0)
+ r = -EIO;
+ return r;
}
dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n",
__func__, break_reg[0], break_reg[1]);
@@ -663,9 +668,13 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
reg_contents = get_unaligned_le16(break_reg);
r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
ch341_break_reg, reg_contents);
- if (r < 0)
+ if (r < 0) {
dev_err(&port->dev, "%s - USB control write error (%d)\n",
__func__, r);
+ return r;
+ }
+
+ return 0;
}
static int ch341_tiocmset(struct tty_struct *tty,
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index d3e92c0faf41c..233c25af0204e 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -39,7 +39,7 @@ static int cp210x_tiocmget(struct tty_struct *);
static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int);
static int cp210x_tiocmset_port(struct usb_serial_port *port,
unsigned int, unsigned int);
-static void cp210x_break_ctl(struct tty_struct *, int);
+static int cp210x_break_ctl(struct tty_struct *, int);
static int cp210x_attach(struct usb_serial *);
static void cp210x_disconnect(struct usb_serial *);
static void cp210x_release(struct usb_serial *);
@@ -1430,7 +1430,7 @@ static int cp210x_tiocmget(struct tty_struct *tty)
return result;
}
-static void cp210x_break_ctl(struct tty_struct *tty, int break_state)
+static int cp210x_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
u16 state;
@@ -1439,9 +1439,11 @@ static void cp210x_break_ctl(struct tty_struct *tty, int break_state)
state = BREAK_OFF;
else
state = BREAK_ON;
+
dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
state == BREAK_OFF ? "off" : "on");
- cp210x_write_u16_reg(port, CP210X_SET_BREAK, state);
+
+ return cp210x_write_u16_reg(port, CP210X_SET_BREAK, state);
}
#ifdef CONFIG_GPIOLIB
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 1bfd64425b259..62a75be78dfc6 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -217,7 +217,7 @@ static void digi_rx_unthrottle(struct tty_struct *tty);
static void digi_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
const struct ktermios *old_termios);
-static void digi_break_ctl(struct tty_struct *tty, int break_state);
+static int digi_break_ctl(struct tty_struct *tty, int break_state);
static int digi_tiocmget(struct tty_struct *tty);
static int digi_tiocmset(struct tty_struct *tty, unsigned int set,
unsigned int clear);
@@ -846,7 +846,7 @@ static void digi_set_termios(struct tty_struct *tty,
}
-static void digi_break_ctl(struct tty_struct *tty, int break_state)
+static int digi_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
unsigned char buf[4];
@@ -855,7 +855,8 @@ static void digi_break_ctl(struct tty_struct *tty, int break_state)
buf[1] = 2; /* length */
buf[2] = break_state ? 1 : 0;
buf[3] = 0; /* pad */
- digi_write_inb_command(port, buf, 4, 0);
+
+ return digi_write_inb_command(port, buf, 4, 0);
}
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
index 5e689fb2b7aaa..f397a68bdb53c 100644
--- a/drivers/usb/serial/f81232.c
+++ b/drivers/usb/serial/f81232.c
@@ -447,7 +447,7 @@ static void f81534a_process_read_urb(struct urb *urb)
tty_flip_buffer_push(&port->port);
}
-static void f81232_break_ctl(struct tty_struct *tty, int break_state)
+static int f81232_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct f81232_private *priv = usb_get_serial_port_data(port);
@@ -466,6 +466,8 @@ static void f81232_break_ctl(struct tty_struct *tty, int break_state)
dev_err(&port->dev, "set break failed: %d\n", status);
mutex_unlock(&priv->lock);
+
+ return status;
}
static int f81232_find_clk(speed_t baudrate)
diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 4083ae961be43..ef126cd3d94fb 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -656,7 +656,7 @@ static int f81534_set_port_config(struct usb_serial_port *port,
return status;
}
-static void f81534_break_ctl(struct tty_struct *tty, int break_state)
+static int f81534_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct f81534_port_private *port_priv = usb_get_serial_port_data(port);
@@ -675,6 +675,8 @@ static void f81534_break_ctl(struct tty_struct *tty, int break_state)
dev_err(&port->dev, "set break failed: %d\n", status);
mutex_unlock(&port_priv->lcr_mutex);
+
+ return status;
}
static int f81534_update_mctrl(struct usb_serial_port *port, unsigned int set,
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8c54dcc746a98..0b54f64e27fdd 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -2550,11 +2550,12 @@ static void ftdi_process_read_urb(struct urb *urb)
tty_flip_buffer_push(&port->port);
}
-static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
+static int ftdi_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
u16 value;
+ int ret;
/* break_state = -1 to turn on break, and 0 to turn off break */
/* see drivers/char/tty_io.c to see it used */
@@ -2565,19 +2566,22 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
else
value = priv->last_set_data_value;
- if (usb_control_msg(port->serial->dev,
+ ret = usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0),
FTDI_SIO_SET_DATA_REQUEST,
FTDI_SIO_SET_DATA_REQUEST_TYPE,
value, priv->channel,
- NULL, 0, WDR_TIMEOUT) < 0) {
+ NULL, 0, WDR_TIMEOUT);
+ if (ret < 0) {
dev_err(&port->dev, "%s FAILED to enable/disable break state (state was %d)\n",
__func__, break_state);
+ return ret;
}
dev_dbg(&port->dev, "%s break state is %d - urb is %d\n", __func__,
break_state, value);
+ return 0;
}
static bool ftdi_tx_empty(struct usb_serial_port *port)
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index c5ada8debfd61..ab29c867956bb 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -1564,12 +1564,12 @@ static int edge_ioctl(struct tty_struct *tty,
* SerialBreak
* this function sends a break to the port
*****************************************************************************/
-static void edge_break(struct tty_struct *tty, int break_state)
+static int edge_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial);
- int status;
+ int status = 0;
if (!edge_serial->is_epic ||
edge_serial->epic_descriptor.Supports.IOSPChase) {
@@ -1601,6 +1601,8 @@ static void edge_break(struct tty_struct *tty, int break_state)
dev_dbg(&port->dev, "%s - error sending break set/clear command.\n",
__func__);
}
+
+ return status;
}
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 69f7240568470..45184faf02bce 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2432,7 +2432,7 @@ static int edge_tiocmget(struct tty_struct *tty)
return result;
}
-static void edge_break(struct tty_struct *tty, int break_state)
+static int edge_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
@@ -2441,10 +2441,15 @@ static void edge_break(struct tty_struct *tty, int break_state)
if (break_state == -1)
bv = 1; /* On */
+
status = ti_do_config(edge_port, UMPC_SET_CLR_BREAK, bv);
- if (status)
+ if (status) {
dev_dbg(&port->dev, "%s - error %d sending break set/clear command.\n",
__func__, status);
+ return status;
+ }
+
+ return 0;
}
static void edge_heartbeat_schedule(struct edgeport_serial *edge_serial)
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 26c2cc372ed31..bb4f047381ff4 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -599,7 +599,7 @@ struct keyspan_port_private {
#include "keyspan_usa67msg.h"
-static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
+static int keyspan_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct keyspan_port_private *p_priv;
@@ -611,7 +611,10 @@ static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
else
p_priv->break_on = 0;
+ /* FIXME: return errors */
keyspan_send_setup(port, 0);
+
+ return 0;
}
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 264efa6ce8e49..b3964f20b2547 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -323,7 +323,7 @@ static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
return baud;
}
-static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
+static int keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
@@ -339,9 +339,13 @@ static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
4, /* set break */
USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
value, 0, NULL, 0, 2000);
- if (result < 0)
+ if (result < 0) {
dev_dbg(&port->dev, "%s - error %d from usb_control_msg\n",
__func__, result);
+ return result;
+ }
+
+ return 0;
}
static void keyspan_pda_set_termios(struct tty_struct *tty,
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 3c1351bb7ca3d..be63f5f374047 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -47,7 +47,7 @@ static void mct_u232_read_int_callback(struct urb *urb);
static void mct_u232_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
const struct ktermios *old_termios);
-static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
+static int mct_u232_break_ctl(struct tty_struct *tty, int break_state);
static int mct_u232_tiocmget(struct tty_struct *tty);
static int mct_u232_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
@@ -683,7 +683,7 @@ static void mct_u232_set_termios(struct tty_struct *tty,
spin_unlock_irqrestore(&priv->lock, flags);
} /* mct_u232_set_termios */
-static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
+static int mct_u232_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct mct_u232_private *priv = usb_get_serial_port_data(port);
@@ -697,7 +697,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
lcr |= MCT_U232_SET_BREAK;
spin_unlock_irqrestore(&priv->lock, flags);
- mct_u232_set_line_ctrl(port, lcr);
+ return mct_u232_set_line_ctrl(port, lcr);
} /* mct_u232_break_ctl */
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 1d1f85fabc284..23544074eb1c3 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -996,7 +996,7 @@ static void mos7720_close(struct usb_serial_port *port)
mos7720_port->open = 0;
}
-static void mos7720_break(struct tty_struct *tty, int break_state)
+static int mos7720_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
unsigned char data;
@@ -1007,7 +1007,7 @@ static void mos7720_break(struct tty_struct *tty, int break_state)
mos7720_port = usb_get_serial_port_data(port);
if (mos7720_port == NULL)
- return;
+ return -ENODEV;
if (break_state == -1)
data = mos7720_port->shadowLCR | UART_LCR_SBC;
@@ -1015,8 +1015,9 @@ static void mos7720_break(struct tty_struct *tty, int break_state)
data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
mos7720_port->shadowLCR = data;
- write_mos_reg(serial, port->port_number, MOS7720_LCR,
- mos7720_port->shadowLCR);
+
+ return write_mos_reg(serial, port->port_number, MOS7720_LCR,
+ mos7720_port->shadowLCR);
}
/*
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 26f287180f8ab..f90b427e4c3f9 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -787,7 +787,7 @@ static void mos7840_close(struct usb_serial_port *port)
* mos7840_break
* this function sends a break to the port
*****************************************************************************/
-static void mos7840_break(struct tty_struct *tty, int break_state)
+static int mos7840_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port = usb_get_serial_port_data(port);
@@ -801,8 +801,9 @@ static void mos7840_break(struct tty_struct *tty, int break_state)
/* FIXME: no locking on shadowLCR anywhere in driver */
mos7840_port->shadowLCR = data;
dev_dbg(&port->dev, "%s mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR);
- mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
- mos7840_port->shadowLCR);
+
+ return mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
+ mos7840_port->shadowLCR);
}
/*****************************************************************************
diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
index 3030d53e8b1fe..8d20928ce54c9 100644
--- a/drivers/usb/serial/mxuport.c
+++ b/drivers/usb/serial/mxuport.c
@@ -1238,7 +1238,7 @@ static void mxuport_close(struct usb_serial_port *port)
}
/* Send a break to the port. */
-static void mxuport_break_ctl(struct tty_struct *tty, int break_state)
+static int mxuport_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
@@ -1252,8 +1252,8 @@ static void mxuport_break_ctl(struct tty_struct *tty, int break_state)
dev_dbg(&port->dev, "%s - clearing break\n", __func__);
}
- mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_BREAK,
- enable, port->port_number);
+ return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_BREAK,
+ enable, port->port_number);
}
static int mxuport_resume(struct usb_serial *serial)
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 103994af4bff3..1ba2287d4d456 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -174,7 +174,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define PL2303_HXN_FLOWCTRL_RTS_CTS 0x18
#define PL2303_HXN_FLOWCTRL_XON_XOFF 0x0c
-static void pl2303_set_break(struct usb_serial_port *port, bool enable);
+static int pl2303_set_break(struct usb_serial_port *port, bool enable);
enum pl2303_type {
TYPE_H,
@@ -1063,7 +1063,7 @@ static int pl2303_carrier_raised(struct usb_serial_port *port)
return 0;
}
-static void pl2303_set_break(struct usb_serial_port *port, bool enable)
+static int pl2303_set_break(struct usb_serial_port *port, bool enable)
{
struct usb_serial *serial = port->serial;
u16 state;
@@ -1080,15 +1080,19 @@ static void pl2303_set_break(struct usb_serial_port *port, bool enable)
result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
0, NULL, 0, 100);
- if (result)
+ if (result) {
dev_err(&port->dev, "error sending break = %d\n", result);
+ return result;
+ }
+
+ return 0;
}
-static void pl2303_break_ctl(struct tty_struct *tty, int state)
+static int pl2303_break_ctl(struct tty_struct *tty, int state)
{
struct usb_serial_port *port = tty->driver_data;
- pl2303_set_break(port, state);
+ return pl2303_set_break(port, state);
}
static void pl2303_update_line_status(struct usb_serial_port *port,
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index dcd2938095bbb..cf2ab7cb80f0e 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -762,7 +762,7 @@ static int qt2_tiocmset(struct tty_struct *tty,
return update_mctrl(port_priv, set, clear);
}
-static void qt2_break_ctl(struct tty_struct *tty, int break_state)
+static int qt2_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct qt2_port_private *port_priv;
@@ -775,10 +775,14 @@ static void qt2_break_ctl(struct tty_struct *tty, int break_state)
status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL,
val, port_priv->device_port);
- if (status < 0)
+ if (status < 0) {
dev_warn(&port->dev,
"%s - failed to send control message: %i\n", __func__,
status);
+ return status;
+ }
+
+ return 0;
}
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index b99f78224846d..0fba25abf671c 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -319,7 +319,7 @@ static void ti_set_termios(struct tty_struct *tty,
static int ti_tiocmget(struct tty_struct *tty);
static int ti_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
-static void ti_break(struct tty_struct *tty, int break_state);
+static int ti_break(struct tty_struct *tty, int break_state);
static void ti_interrupt_callback(struct urb *urb);
static void ti_bulk_in_callback(struct urb *urb);
static void ti_bulk_out_callback(struct urb *urb);
@@ -1071,7 +1071,7 @@ static int ti_tiocmset(struct tty_struct *tty,
}
-static void ti_break(struct tty_struct *tty, int break_state)
+static int ti_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct ti_port *tport = usb_get_serial_port_data(port);
@@ -1083,8 +1083,12 @@ static void ti_break(struct tty_struct *tty, int break_state)
tport->tp_uart_base_addr + TI_UART_OFFSET_LCR,
TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0);
- if (status)
+ if (status) {
dev_dbg(&port->dev, "%s - error setting break, %d\n", __func__, status);
+ return status;
+ }
+
+ return 0;
}
static int ti_get_port_from_code(unsigned char code)
diff --git a/drivers/usb/serial/upd78f0730.c b/drivers/usb/serial/upd78f0730.c
index c47439bd90fa6..46952182e04f7 100644
--- a/drivers/usb/serial/upd78f0730.c
+++ b/drivers/usb/serial/upd78f0730.c
@@ -238,12 +238,13 @@ static int upd78f0730_tiocmset(struct tty_struct *tty,
return res;
}
-static void upd78f0730_break_ctl(struct tty_struct *tty, int break_state)
+static int upd78f0730_break_ctl(struct tty_struct *tty, int break_state)
{
struct upd78f0730_port_private *private;
struct usb_serial_port *port = tty->driver_data;
struct upd78f0730_set_dtr_rts request;
struct device *dev = &port->dev;
+ int res;
private = usb_get_serial_port_data(port);
@@ -258,8 +259,10 @@ static void upd78f0730_break_ctl(struct tty_struct *tty, int break_state)
request.opcode = UPD78F0730_CMD_SET_DTR_RTS;
request.params = private->line_signals;
- upd78f0730_send_ctl(port, &request, sizeof(request));
+ res = upd78f0730_send_ctl(port, &request, sizeof(request));
mutex_unlock(&private->lock);
+
+ return res;
}
static void upd78f0730_dtr_rts(struct usb_serial_port *port, int on)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index eb3c9f626e5d6..d0f9db08125e0 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -538,7 +538,7 @@ static int serial_break(struct tty_struct *tty, int break_state)
dev_dbg(&port->dev, "%s\n", __func__);
if (port->serial->type->break_ctl)
- port->serial->type->break_ctl(tty, break_state);
+ return port->serial->type->break_ctl(tty, break_state);
return 0;
}
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 406cb326e8124..5a8869cd95d52 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -47,12 +47,19 @@ MODULE_DEVICE_TABLE(usb, id_table_combined);
/* This HW really does not support a serial break, so one will be
* emulated when ever the break state is set to true.
*/
-static void usb_debug_break_ctl(struct tty_struct *tty, int break_state)
+static int usb_debug_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
+ int ret;
+
if (!break_state)
- return;
- usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE);
+ return 0;
+
+ ret = usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static void usb_debug_process_read_urb(struct urb *urb)
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 7f82d40753ee0..ca48e90a8e81f 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -87,7 +87,7 @@ static void whiteheat_set_termios(struct tty_struct *tty,
static int whiteheat_tiocmget(struct tty_struct *tty);
static int whiteheat_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
-static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
+static int whiteheat_break_ctl(struct tty_struct *tty, int break_state);
static struct usb_serial_driver whiteheat_fake_device = {
.driver = {
@@ -449,10 +449,11 @@ static void whiteheat_set_termios(struct tty_struct *tty,
firm_setup_port(tty);
}
-static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
+static int whiteheat_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
- firm_set_break(port, break_state);
+
+ return firm_set_break(port, break_state);
}
diff --git a/drivers/usb/serial/xr_serial.c b/drivers/usb/serial/xr_serial.c
index f3811e060a441..60fae9d012a61 100644
--- a/drivers/usb/serial/xr_serial.c
+++ b/drivers/usb/serial/xr_serial.c
@@ -503,7 +503,7 @@ static void xr_dtr_rts(struct usb_serial_port *port, int on)
xr_tiocmset_port(port, 0, TIOCM_DTR | TIOCM_RTS);
}
-static void xr_break_ctl(struct tty_struct *tty, int break_state)
+static int xr_break_ctl(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
struct xr_data *data = usb_get_serial_port_data(port);
@@ -517,7 +517,7 @@ static void xr_break_ctl(struct tty_struct *tty, int break_state)
dev_dbg(&port->dev, "Turning break %s\n", state == 0 ? "off" : "on");
- xr_set_reg_uart(port, type->tx_break, state);
+ return xr_set_reg_uart(port, type->tx_break, state);
}
/* Tx and Rx clock mask values obtained from section 3.3.4 of datasheet */
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 9c5550c4c4275..0950aa3166773 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -278,7 +278,7 @@ struct usb_serial_driver {
int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss);
void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port,
const struct ktermios *old);
- void (*break_ctl)(struct tty_struct *tty, int break_state);
+ int (*break_ctl)(struct tty_struct *tty, int break_state);
unsigned int (*chars_in_buffer)(struct tty_struct *tty);
void (*wait_until_sent)(struct tty_struct *tty, long timeout);
bool (*tx_empty)(struct usb_serial_port *port);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0397/1887] USB: serial: report unsupported break signalling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (395 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0396/1887] USB: serial: return errors from break handling Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0398/1887] USB: serial: fix ioctl hangup race Greg Kroah-Hartman
` (601 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Corey Minyard, Johan Hovold,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit c9d934053d9e850bc901b6425eacb5fe3d4b1738 ]
Instead of returning success when a driver does not support break
signalling, return an error to let user space know and to avoid waiting
when break is not supported.
Tested-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Stable-dep-of: ae0e61d95677 ("USB: serial: fix ioctl hangup race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/serial/usb-serial.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index d0f9db08125e0..9ecc108c2d275 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -540,7 +540,7 @@ static int serial_break(struct tty_struct *tty, int break_state)
if (port->serial->type->break_ctl)
return port->serial->type->break_ctl(tty, break_state);
- return 0;
+ return -ENOTTY;
}
static int serial_proc_show(struct seq_file *m, void *v)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0398/1887] USB: serial: fix ioctl hangup race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (396 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0397/1887] USB: serial: report unsupported break signalling Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0399/1887] mtd: block2mtd: Fix divide error when erase_size is zero Greg Kroah-Hartman
` (600 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nick Bowler,
syzbot+473d7477c523b41d4046, Johan Hovold, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit ae0e61d95677efa778379853e495d748e6efbf95 ]
The tty ioctls can race with hangup and end up calling into a tty driver
for a device that is already gone or powered down.
Serialise the callbacks using the tty port mutex and add the missing
checks to make sure the port has not been hung up before accessing port
driver data or hardware.
This specifically avoids dereferencing a NULL-pointer if a device is
disconnected during lengthy break signalling.
Note that TIOCGICOUNT and TIOCMIWAIT do not access port driver data or
hardware and are therefore not affected by the race.
Fixes: f34d7a5b7010 ("tty: The big operations rework")
Reported-by: Nick Bowler <nbowler@draconx.ca>
Link: https://lore.kernel.org/all/CADyTPExB2kYOOwkO0JqGhKaYVDqO9uS9WCw0J=MCTdVhcGOogA@mail.gmail.com/
Reported-by: syzbot+473d7477c523b41d4046@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/6a9087a4.4d659fcc.734b4.0013.GAE@google.com
Cc: stable@vger.kernel.org # 2.6.26
Signed-off-by: Johan Hovold <johan@kernel.org>
[ sashal: Omitted XR driver hunks because the RS-485 ioctl helpers are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/serial/generic.c | 10 +++-
drivers/usb/serial/usb-serial.c | 94 ++++++++++++++++++++++++++-------
2 files changed, 83 insertions(+), 21 deletions(-)
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 15b6dee3a8e50..64890f6d78e03 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -268,6 +268,7 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
unsigned int bps;
unsigned long period;
unsigned long expire;
@@ -287,7 +288,14 @@ void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
__func__, jiffies_to_msecs(timeout),
jiffies_to_msecs(period));
expire = jiffies + timeout;
- while (!port->serial->type->tx_empty(port)) {
+ for (;;) {
+ mutex_lock(&tport->mutex);
+ if (tty_io_error(tty) || port->serial->type->tx_empty(port)) {
+ mutex_unlock(&tport->mutex);
+ break;
+ }
+ mutex_unlock(&tport->mutex);
+
schedule_timeout_interruptible(period);
if (signal_pending(current))
break;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 9ecc108c2d275..9c6e6618e1694 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -403,17 +403,13 @@ static unsigned int serial_chars_in_buffer(struct tty_struct *tty)
static void serial_wait_until_sent(struct tty_struct *tty, int timeout)
{
struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = port->serial;
dev_dbg(&port->dev, "%s\n", __func__);
if (!port->serial->type->wait_until_sent)
return;
- mutex_lock(&serial->disc_mutex);
- if (!serial->disconnected)
- port->serial->type->wait_until_sent(tty, timeout);
- mutex_unlock(&serial->disc_mutex);
+ port->serial->type->wait_until_sent(tty, timeout);
}
static void serial_throttle(struct tty_struct *tty)
@@ -441,8 +437,13 @@ static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss)
struct usb_serial_port *port = tty->driver_data;
struct tty_port *tport = &port->port;
unsigned int close_delay, closing_wait;
+ int ret = 0;
mutex_lock(&tport->mutex);
+ if (tty_io_error(tty)) {
+ ret = -EIO;
+ goto out_unlock;
+ }
close_delay = jiffies_to_msecs(tport->close_delay) / 10;
closing_wait = tport->closing_wait;
@@ -455,10 +456,10 @@ static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss)
if (port->serial->type->get_serial)
port->serial->type->get_serial(tty, ss);
-
+out_unlock:
mutex_unlock(&tport->mutex);
- return 0;
+ return ret;
}
static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss)
@@ -474,6 +475,10 @@ static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss)
closing_wait = msecs_to_jiffies(closing_wait * 10);
mutex_lock(&tport->mutex);
+ if (tty_io_error(tty)) {
+ ret = -EIO;
+ goto out_unlock;
+ }
if (!capable(CAP_SYS_ADMIN)) {
if (close_delay != tport->close_delay ||
@@ -501,6 +506,7 @@ static int serial_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
int retval = -ENOIOCTLCMD;
dev_dbg(&port->dev, "%s - cmd 0x%04x\n", __func__, cmd);
@@ -511,8 +517,21 @@ static int serial_ioctl(struct tty_struct *tty,
retval = port->serial->type->tiocmiwait(tty, arg);
break;
default:
- if (port->serial->type->ioctl)
+ if (!port->serial->type->ioctl)
+ break;
+
+ if (cmd == TIOCSRS485)
+ down_write(&tty->termios_rwsem);
+
+ mutex_lock(&tport->mutex);
+ if (tty_io_error(tty))
+ retval = -EIO;
+ else
retval = port->serial->type->ioctl(tty, cmd, arg);
+ mutex_unlock(&tport->mutex);
+
+ if (cmd == TIOCSRS485)
+ up_write(&tty->termios_rwsem);
}
return retval;
@@ -522,25 +541,40 @@ static void serial_set_termios(struct tty_struct *tty,
const struct ktermios *old)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
dev_dbg(&port->dev, "%s\n", __func__);
- if (port->serial->type->set_termios)
- port->serial->type->set_termios(tty, port, old);
- else
+ if (!port->serial->type->set_termios) {
tty_termios_copy_hw(&tty->termios, old);
+ return;
+ }
+
+ mutex_lock(&tport->mutex);
+ if (!tty_io_error(tty))
+ port->serial->type->set_termios(tty, port, old);
+ mutex_unlock(&tport->mutex);
}
static int serial_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
+ int ret;
dev_dbg(&port->dev, "%s\n", __func__);
- if (port->serial->type->break_ctl)
- return port->serial->type->break_ctl(tty, break_state);
+ if (!port->serial->type->break_ctl)
+ return -ENOTTY;
- return -ENOTTY;
+ mutex_lock(&tport->mutex);
+ if (tty_io_error(tty))
+ ret = -EIO;
+ else
+ ret = port->serial->type->break_ctl(tty, break_state);
+ mutex_unlock(&tport->mutex);
+
+ return ret;
}
static int serial_proc_show(struct seq_file *m, void *v)
@@ -581,24 +615,44 @@ static int serial_proc_show(struct seq_file *m, void *v)
static int serial_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
+ int ret;
dev_dbg(&port->dev, "%s\n", __func__);
- if (port->serial->type->tiocmget)
- return port->serial->type->tiocmget(tty);
- return -ENOTTY;
+ if (!port->serial->type->tiocmget)
+ return -ENOTTY;
+
+ mutex_lock(&tport->mutex);
+ if (tty_io_error(tty))
+ ret = -EIO;
+ else
+ ret = port->serial->type->tiocmget(tty);
+ mutex_unlock(&tport->mutex);
+
+ return ret;
}
static int serial_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
struct usb_serial_port *port = tty->driver_data;
+ struct tty_port *tport = &port->port;
+ int ret;
dev_dbg(&port->dev, "%s\n", __func__);
- if (port->serial->type->tiocmset)
- return port->serial->type->tiocmset(tty, set, clear);
- return -ENOTTY;
+ if (!port->serial->type->tiocmset)
+ return -ENOTTY;
+
+ mutex_lock(&tport->mutex);
+ if (tty_io_error(tty))
+ ret = -EIO;
+ else
+ ret = port->serial->type->tiocmset(tty, set, clear);
+ mutex_unlock(&tport->mutex);
+
+ return ret;
}
static int serial_get_icount(struct tty_struct *tty,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0399/1887] mtd: block2mtd: Fix divide error when erase_size is zero
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (397 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0398/1887] USB: serial: fix ioctl hangup race Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0400/1887] mtd: spinand: Enable QE on all dies Greg Kroah-Hartman
` (599 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b320a4d5f65a61dbbf89,
Jörn Engel, Pei Xiao, Miquel Raynal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <xiaopei01@kylinos.cn>
[ Upstream commit b5965c4221165045e19736794ca5f48ae3d67142 ]
The erase size is parsed from the "block2mtd" module parameter and can
be set to zero. add_device() then evaluates
if (size % erase_size)
with a zero divisor, which triggers a divide error:
divide error: 0000 [#1] PREEMPT SMP PTI
RIP: 0010:add_device drivers/mtd/devices/block2mtd.c:296 [inline]
RIP: 0010:block2mtd_setup2+0x592/0xda0 drivers/mtd/devices/block2mtd.c:459
Call Trace:
block2mtd_setup+0x27/0xe0 drivers/mtd/devices/block2mtd.c:476
param_attr_store+0x214/0x310 kernel/params.c:589
module_attr_store+0x65/0x90 kernel/params.c:904
kernfs_fop_write_iter+0x3a4/0x540 fs/kernfs/file.c:345
...
Reject a zero erase size before performing the modulo operation so the
existing "erasesize must be a divisor of device size" error path
reports the invalid argument and frees the device.
Fixes: ea6d833a3fdd ("mtd: block2mtd: check device size")
Reported-by: syzbot+b320a4d5f65a61dbbf89@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/lkml/6a7b58ba.ac361c09.22ff0a.0045.GAE@google.com/
Suggested-by: Jörn Engel <joern@barelysecure.org>
Cc: stable@vger.kernel.org
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
[ sashal: Replaced the upstream local size variable with the existing direct dev->blkdev->bd_inode->i_size expression. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/devices/block2mtd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4cd37ec45762b..9175196110c6d 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -272,7 +272,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
goto err_free_block2mtd;
}
- if ((long)dev->blkdev->bd_inode->i_size % erase_size) {
+ if (!erase_size || (long)dev->blkdev->bd_inode->i_size % erase_size) {
pr_err("erasesize must be a divisor of device size\n");
goto err_free_block2mtd;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0400/1887] mtd: spinand: Enable QE on all dies
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (398 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0399/1887] mtd: block2mtd: Fix divide error when erase_size is zero Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0401/1887] wifi: mac80211: account proxy paths against the mesh path limit Greg Kroah-Hartman
` (598 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Han Xu, Miquel Raynal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Xu <han.xu@nxp.com>
[ Upstream commit 63d6cace2c4a7f36c1cb44f1bb5e0f3ef19e5c7f ]
The QUAD ENABLE (QE) bit is stored in a per-die configuration
register on some SPI-NAND devices. When a device contains multiple
dies, updating the QE bit only on the currently selected die can
leave the remaining dies operating in non-quad mode.
Iterate over all targets and update the QE setting on each die
during initialization to ensure consistent quad I/O operation
across the entire device.
Tested on ISSI IS38SMW04G8B.
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
Cc: stable@vger.kernel.org
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
[ sashal: adapted spinand_init_quad_enable() to use its internally computed enable flag instead of a parameter ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/spi/core.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 15c54d61cedbd..17d9c5ea26701 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -179,7 +179,10 @@ static int spinand_init_cfg_cache(struct spinand_device *spinand)
static int spinand_init_quad_enable(struct spinand_device *spinand)
{
+ struct nand_device *nand = spinand_to_nand(spinand);
+ unsigned int target;
bool enable = false;
+ int ret;
if (!(spinand->flags & SPINAND_HAS_QE_BIT))
return 0;
@@ -189,8 +192,22 @@ static int spinand_init_quad_enable(struct spinand_device *spinand)
spinand->op_templates.update_cache->data.buswidth == 4)
enable = true;
- return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE,
- enable ? CFG_QUAD_ENABLE : 0);
+ /*
+ * QE is a per-die setting on some devices. Program each target
+ * individually when enabling or disabling quad I/O mode.
+ */
+ for (target = 0; target < nand->memorg.ntargets; target++) {
+ ret = spinand_select_target(spinand, target);
+ if (ret)
+ return ret;
+
+ ret = spinand_upd_cfg(spinand, CFG_QUAD_ENABLE,
+ enable ? CFG_QUAD_ENABLE : 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int spinand_ecc_enable(struct spinand_device *spinand,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0401/1887] wifi: mac80211: account proxy paths against the mesh path limit
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (399 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0400/1887] mtd: spinand: Enable QE on all dies Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0402/1887] bnxt_en: fix DMA mapping length for padded small packets Greg Kroah-Hartman
` (597 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zhao Li, Johannes Berg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
[ Upstream commit a5f35d4b112af1415ff06bd501c8cc26cc08aa8b ]
Proxy-path churn can drive the interface path counter negative and let
later mesh path additions exceed MESH_MAX_MPATHS.
mesh_path_free_rcu() decrements the interface mpaths counter for entries
from both the mesh and proxy path tables, but mpp_path_add() never
reserves a slot in that counter. Removing or expiring a proxy path
therefore returns a slot that was never charged.
mesh_path_add() uses the same counter to enforce MESH_MAX_MPATHS, so once
it falls below the number of installed paths the limit no longer holds.
Reserve the shared quota before allocating a proxy path and release it on
every unsuccessful addition. Mesh and proxy paths now share one
1024-entry budget, so mpp_path_add() can return -ENOSPC at that limit.
Fixes: ece1a2e7e860 ("mac80211: Remove mesh paths when an interface is removed")
Cc: stable@vger.kernel.org
Assisted-by: LLM sparse kasan
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260916113649.28315-3-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: Omitted the mesh_fast_tx_flush_addr() else branch because the helper is unavailable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mesh_pathtbl.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index a0ef296e3e4f3..f2970f33f96c5 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -449,10 +449,15 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
if (is_multicast_ether_addr(dst))
return -ENOTSUPP;
+ if (!atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS))
+ return -ENOSPC;
+
new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
- if (!new_mpath)
+ if (!new_mpath) {
+ atomic_dec(&sdata->u.mesh.mpaths);
return -ENOMEM;
+ }
memcpy(new_mpath->mpp, mpp, ETH_ALEN);
tbl = &sdata->u.mesh.mpp_paths;
@@ -465,8 +470,10 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
hlist_add_head_rcu(&new_mpath->walk_list, &tbl->walk_head);
spin_unlock_bh(&tbl->walk_lock);
- if (ret)
+ if (ret) {
kfree(new_mpath);
+ atomic_dec(&sdata->u.mesh.mpaths);
+ }
sdata->u.mesh.mpp_paths_generation++;
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0402/1887] bnxt_en: fix DMA mapping length for padded small packets
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (400 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0401/1887] wifi: mac80211: account proxy paths against the mesh path limit Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0403/1887] tty: port: fix tty_port_tty_vhangup() race Greg Kroah-Hartman
` (596 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Fleischmann, Eric Dumazet,
Michael Chan, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit a51d233ccd4889aadb71dace863525cc2b00271e ]
Stefan Fleischmann reported Intel IOMMU DMA Read faults on BCM57412
NetXtreme-E NICs when transmitting packets on VLAN/macvlan interfaces:
DMAR: [DMA Read NO_PASID] Request device [18:00.0] fault addr 0xfc499000
[fault reason 0x06] PTE Read access is not set
bnxt_en 0000:18:00.0 eno1np0: Abandoning msg {0xb4 0x41a} len: 0 due to firmware status: 0x2000001
...
NETDEV WATCHDOG: eno1np0 (bnxt_en): transmit queue 0 timed out
The fault address (0xfc499000) is on an exact 4KB page boundary,
pointing to a DMA read buffer overrun.
In bnxt_start_xmit(), packets smaller than BNXT_MIN_PKT_SIZE (52 bytes),
such as 42-byte untagged ARP frames, are padded:
if (length < BNXT_MIN_PKT_SIZE) {
pad = BNXT_MIN_PKT_SIZE - length;
if (skb_pad(skb, pad))
goto tx_kick_pending;
length = BNXT_MIN_PKT_SIZE;
}
mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE);
...
dma_unmap_len_set(tx_buf, len, len);
However, 'len' was initialized earlier to skb_headlen(skb) (e.g. 42 bytes)
and is left unadjusted after padding. Consequently, dma_map_single() and
dma_unmap_len_set() map and track only 42 bytes.
Later, the hardware TX buffer descriptor is programmed with the padded length:
txbd->tx_bd_len_flags_type =
cpu_to_le32(((len + pad) << TX_BD_LEN_SHIFT) | flags |
TX_BD_FLAGS_PACKET_END);
The NIC DMA engine is thus instructed to read 52 bytes from a region where
only 42 bytes were DMA-mapped. If skb->data ends near the boundary of a 4KB
page (within 'pad' bytes of the next page), the hardware DMA read overruns
into the unmapped adjacent page, triggering an IOMMU fault.
This issue was exposed after commit 447cbe95ebb9 ("vlan: fix skb_under_panic
and races when toggling HW VLAN offload") because reserving extra VLAN
headroom rounded LL_RESERVED_SPACE from 48 up to 64 bytes, shifting skb->data
offsets and potentially causing small frames to land right against page
boundaries.
Fix this by using skb_put_padto(skb, BNXT_MIN_PKT_SIZE) in
bnxt_start_xmit(), before skb_shinfo(skb)->nr_frags is sampled,
because padding might linearize the skb.
This ensures skb->len and skb_headlen(skb) reflect the padded size so
that dma_map_single() maps the full buffer and the descriptor length is
consistent. This also removes the temporary 'pad' variable and masking logic.
The padding is done after the SW USO branch, otherwise
bnxt_sw_udp_gso_xmit() would account the padding as UDP payload
and send it in extra segments.
Note that SW USO segments are still not padded: with IPv4, a segment
carrying less than 10 bytes of UDP payload (small gso_size, or a short
last segment) is sent as a frame shorter than BNXT_MIN_PKT_SIZE.
This is a separate issue, left for a followup patch.
Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.")
Cc: stable@vger.kernel.org
Reported-by: Stefan Fleischmann <sfle@kth.se>
Closes: https://lore.kernel.org/netdev/20261004122616.56714cbd@nargothrond/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20261007051747.455273-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 8d7eda5cafe2d..3179412d7b33b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -392,7 +392,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct netdev_queue *txq;
int i;
dma_addr_t mapping;
- unsigned int length, pad = 0;
+ unsigned int length;
u32 len, free_size, vlan_tag_flags, cfa_action, flags;
u16 prod, last_frag;
struct pci_dev *pdev = bp->pdev;
@@ -411,6 +411,14 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
txr = &bp->tx_ring[bp->tx_ring_map[i]];
prod = txr->tx_prod;
+ /* Must be done before skb_shinfo(skb)->nr_frags is sampled,
+ * because skb_put_padto() might linearize the skb.
+ */
+ if (skb_put_padto(skb, BNXT_MIN_PKT_SIZE)) {
+ /* SKB already freed. */
+ goto tx_kick_pending;
+ }
+
free_size = bnxt_tx_avail(bp, txr);
if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
/* We must have raced with NAPI cleanup */
@@ -539,14 +547,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
normal_tx:
- if (length < BNXT_MIN_PKT_SIZE) {
- pad = BNXT_MIN_PKT_SIZE - length;
- if (skb_pad(skb, pad))
- /* SKB already freed. */
- goto tx_kick_pending;
- length = BNXT_MIN_PKT_SIZE;
- }
-
mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&pdev->dev, mapping)))
@@ -618,10 +618,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
}
- flags &= ~TX_BD_LEN;
- txbd->tx_bd_len_flags_type =
- cpu_to_le32(((len + pad) << TX_BD_LEN_SHIFT) | flags |
- TX_BD_FLAGS_PACKET_END);
+ txbd->tx_bd_len_flags_type |= cpu_to_le32(TX_BD_FLAGS_PACKET_END);
netdev_tx_sent_queue(txq, skb->len);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0403/1887] tty: port: fix tty_port_tty_vhangup() race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (401 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0402/1887] bnxt_en: fix DMA mapping length for padded small packets Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0404/1887] wifi: mac80211: keep paired old chanctx alive Greg Kroah-Hartman
` (595 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5fabc1ae99ff40690d84,
Johan Hovold, Ting-Han Hou, Sasha Levin, stable
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit b48820de8c1a596c5b99775524dfce73c6576c5d ]
Drivers rely on tty_port_tty_vhangup() to synchronously hang up their
ports before tearing down resources as part of deregistration (e.g. on
physical disconnect).
If tty_port_tty_vhangup() races with another hangup it may however
return before the port has been shut down. This is in turn can lead to
use-after-free and NULL-pointer dereferences in racing ioctls (including
a synchronous hangup) and in processing of racing asynchronous hangups
(carrier loss).
Add the missing serialisation to tty_port_tty_vhangup() and
tty_port_hangup() so that the former does not return until the port has
been shut down also when there is a racing hangup.
Note that serial core does not use tty_port_hangup(), but it already
holds the port mutex when clearing port->tty and shutting down the port
in uart_hangup().
Fixes: 7ca0ff9ab321 ("tty: Add a full port_close function")
Cc: stable@kernel.org # 2.6.32: 2b5eac0f8c6e: tty: introduce and use tty_port_tty_vhangup() helper
Cc: stable@kernel.org # 2.6.32
Reported-by: syzbot+5fabc1ae99ff40690d84@syzkaller.appspotmail.com
Link: https://lore.kernel.org/6a944641.4d659fcc.734b4.003c.GAE@google.com
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260910125114.640880-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ Ting-Han: use mutex_lock()/spin_lock_irqsave() instead of guard(),
scoped_guard() and the tty_port_tty class, matching the existing code
in this version of tty_port.c ]
Assisted-by: LLM
Signed-off-by: Ting-Han Hou <ue081723@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/tty_port.c | 74 +++++++++++++++++++++++++++-------------
include/linux/tty_port.h | 22 ++----------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 6f3b4eeb44b38..82f7ddf449c0b 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -350,21 +350,12 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
}
EXPORT_SYMBOL(tty_port_tty_set);
-/**
- * tty_port_shutdown - internal helper to shutdown the device
- * @port: tty port to be shut down
- * @tty: the associated tty
- *
- * It is used by tty_port_hangup() and tty_port_close(). Its task is to
- * shutdown the device if it was initialized (note consoles remain
- * functioning). It lowers DTR/RTS (if @tty has HUPCL set) and invokes
- * @port->ops->shutdown().
- */
-static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
+static void tty_port_shutdown_locked(struct tty_port *port, struct tty_struct *tty)
{
- mutex_lock(&port->mutex);
+ lockdep_assert_held(&port->mutex);
+
if (port->console)
- goto out;
+ return;
if (tty_port_initialized(port)) {
tty_port_set_initialized(port, 0);
@@ -378,7 +369,22 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
if (port->ops->shutdown)
port->ops->shutdown(port);
}
-out:
+}
+
+/**
+ * tty_port_shutdown - internal helper to shutdown the device
+ * @port: tty port to be shut down
+ * @tty: the associated tty
+ *
+ * It is used by tty_port_hangup() and tty_port_close(). Its task is to
+ * shutdown the device if it was initialized (note consoles remain
+ * functioning). It lowers DTR/RTS (if @tty has HUPCL set) and invokes
+ * @port->ops->shutdown().
+ */
+static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
+{
+ mutex_lock(&port->mutex);
+ tty_port_shutdown_locked(port, tty);
mutex_unlock(&port->mutex);
}
@@ -396,6 +402,7 @@ void tty_port_hangup(struct tty_port *port)
struct tty_struct *tty;
unsigned long flags;
+ mutex_lock(&port->mutex);
spin_lock_irqsave(&port->lock, flags);
port->count = 0;
tty = port->tty;
@@ -404,26 +411,47 @@ void tty_port_hangup(struct tty_port *port)
port->tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
tty_port_set_active(port, 0);
- tty_port_shutdown(port, tty);
+ tty_port_shutdown_locked(port, tty);
+ mutex_unlock(&port->mutex);
tty_kref_put(tty);
wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->delta_msr_wait);
}
EXPORT_SYMBOL(tty_port_hangup);
-void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async)
+/**
+ * tty_port_tty_hangup - helper to hang up a tty asynchronously
+ * @port: tty port
+ * @check_clocal: hang only ttys with %CLOCAL unset?
+ */
+void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
{
struct tty_struct *tty = tty_port_tty_get(port);
- if (tty && (!check_clocal || !C_CLOCAL(tty))) {
- if (async)
- tty_hangup(tty);
- else
- tty_vhangup(tty);
- }
+ if (tty && (!check_clocal || !C_CLOCAL(tty)))
+ tty_hangup(tty);
tty_kref_put(tty);
}
-EXPORT_SYMBOL_GPL(__tty_port_tty_hangup);
+EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
+
+/**
+ * tty_port_tty_vhangup - helper to hang up a tty synchronously
+ * @port: tty port
+ */
+void tty_port_tty_vhangup(struct tty_port *port)
+{
+ struct tty_struct *tty;
+
+ mutex_lock(&port->mutex);
+ tty = tty_port_tty_get(port);
+ mutex_unlock(&port->mutex);
+
+ if (tty) {
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
+}
+EXPORT_SYMBOL_GPL(tty_port_tty_vhangup);
/**
* tty_port_tty_wakeup - helper to wake up a tty
diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h
index 1ec146b8d0f42..660edf9e741a1 100644
--- a/include/linux/tty_port.h
+++ b/include/linux/tty_port.h
@@ -234,7 +234,8 @@ int tty_port_carrier_raised(struct tty_port *port);
void tty_port_raise_dtr_rts(struct tty_port *port);
void tty_port_lower_dtr_rts(struct tty_port *port);
void tty_port_hangup(struct tty_port *port);
-void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async);
+void tty_port_tty_hangup(struct tty_port *port, bool check_clocal);
+void tty_port_tty_vhangup(struct tty_port *port);
void tty_port_tty_wakeup(struct tty_port *port);
int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty,
struct file *filp);
@@ -253,23 +254,4 @@ static inline int tty_port_users(struct tty_port *port)
return port->count + port->blocked_open;
}
-/**
- * tty_port_tty_hangup - helper to hang up a tty asynchronously
- * @port: tty port
- * @check_clocal: hang only ttys with %CLOCAL unset?
- */
-static inline void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
-{
- __tty_port_tty_hangup(port, check_clocal, true);
-}
-
-/**
- * tty_port_tty_vhangup - helper to hang up a tty synchronously
- * @port: tty port
- */
-static inline void tty_port_tty_vhangup(struct tty_port *port)
-{
- __tty_port_tty_hangup(port, false, false);
-}
-
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0404/1887] wifi: mac80211: keep paired old chanctx alive
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (402 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0403/1887] tty: port: fix tty_port_tty_vhangup() race Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0405/1887] wifi: mac80211: count only matching reservations in reserved switch Greg Kroah-Hartman
` (594 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 3412e9a800786d1dec4a58367db1cba275e7ef11 ]
An in-place replacement keeps reciprocal replace_ctx pointers between
the old WILL_BE_REPLACED chanctx and the new REPLACES_OTHER chanctx.
However, the early free paths only consider assigned and reserved link
users when deciding whether to free the old chanctx.
That lets the old chanctx be freed too early while the replacement
partner still points back to it, either when the last assigned link is
released or when that link successfully reassigns to another existing
context. Later unreserve and switch-finalization paths can then follow a
stale replace_ctx pointer.
Keep a paired old chanctx alive until the replacement pair has been torn
down. Apply the same check to both __ieee80211_link_release_channel()
and ieee80211_link_use_reserved_reassign(). If the replacement is later
abandoned, ieee80211_link_unreserve_chanctx() already tears down the
pairing before freeing the old chanctx once no users remain.
Fixes: 5bcae31d9cb1 ("mac80211: implement multi-vif in-place reservations")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Link: https://patch.msgid.link/b9b582b0db3814f641648b8886bb50f9d68f93ac.1785730815.git.zhilinz@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: replaced ieee80211_chanctx_has_replace_partner() calls with inline checks ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/chan.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 26e692a853d9b..81a6852cfb264 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1062,6 +1062,7 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
{
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_chanctx *ctx = link->reserved_chanctx;
+ struct ieee80211_chanctx *old_ctx = NULL;
lockdep_assert_held(&sdata->local->chanctx_mtx);
@@ -1076,6 +1077,7 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
if (WARN_ON(!ctx->replace_ctx))
return -EINVAL;
+ old_ctx = ctx->replace_ctx;
WARN_ON(ctx->replace_ctx->replace_state !=
IEEE80211_CHANCTX_WILL_BE_REPLACED);
WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
@@ -1086,6 +1088,10 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
list_del_rcu(&ctx->list);
kfree_rcu(ctx, rcu_head);
+
+ if (ieee80211_chanctx_refcount(sdata->local,
+ old_ctx) == 0)
+ ieee80211_free_chanctx(sdata->local, old_ctx);
} else {
ieee80211_free_chanctx(sdata->local, ctx);
}
@@ -1317,7 +1323,9 @@ ieee80211_link_use_reserved_reassign(struct ieee80211_link_data *link)
ieee80211_check_fast_xmit_iface(sdata);
- if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
+ if (ieee80211_chanctx_refcount(local, old_ctx) == 0 &&
+ !(old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED &&
+ old_ctx->replace_ctx))
ieee80211_free_chanctx(local, old_ctx);
ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL);
@@ -1797,7 +1805,9 @@ static void __ieee80211_link_release_channel(struct ieee80211_link_data *link)
}
ieee80211_assign_link_chanctx(link, NULL);
- if (ieee80211_chanctx_refcount(local, ctx) == 0)
+ if (ieee80211_chanctx_refcount(local, ctx) == 0 &&
+ !(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED &&
+ ctx->replace_ctx))
ieee80211_free_chanctx(local, ctx);
link->radar_required = false;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0405/1887] wifi: mac80211: count only matching reservations in reserved switch
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (403 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0404/1887] wifi: mac80211: keep paired old chanctx alive Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0406/1887] fs: Free any excess xarray nodes in clear_inode() Greg Kroah-Hartman
` (593 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 437f3727b4fd715266c296435c116288f82666fd ]
ieee80211_vif_use_reserved_switch() validates a replacement by counting
assigned links on ctx->replace_ctx and treating reservations too
broadly. A link can still be assigned to the old channel context while
holding a reservation that belongs to a different replacement
operation.
That can make the current replacement appear complete too early. If
another link finalizes first, the function can free the
WILL_BE_REPLACED chanctx while the unmatched link and driver still use
it, leading to a use-after-free in later beacon generation.
Require an in-place reservation to point at the current replacement
context, and require the reserved and assigned contexts to be the
matching replacement pair, before counting or moving the link.
Fixes: 5bcae31d9cb1 ("mac80211: implement multi-vif in-place reservations")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Link: https://patch.msgid.link/4b6c4b8648ab1920c38a40be32c0b1a2797b4ac6.1785726007.git.zhilinz@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: Adapted iter.link accesses to direct link pointers in list-based loops. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/chan.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 81a6852cfb264..5838d391421e4 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1389,7 +1389,8 @@ ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link)
}
static bool
-ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
+ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link,
+ struct ieee80211_chanctx *ctx)
{
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_chanctx *old_ctx, *new_ctx;
@@ -1399,6 +1400,9 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
new_ctx = link->reserved_chanctx;
old_ctx = ieee80211_link_get_chanctx(link);
+ if (new_ctx != ctx)
+ return false;
+
if (!old_ctx)
return false;
@@ -1411,6 +1415,12 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
return false;
+ if (new_ctx->replace_ctx != old_ctx)
+ return false;
+
+ if (old_ctx->replace_ctx != new_ctx)
+ return false;
+
return true;
}
@@ -1460,7 +1470,7 @@ static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
list_for_each_entry(link, &ctx->reserved_links,
reserved_chanctx_list) {
- if (!ieee80211_link_has_in_place_reservation(link))
+ if (!ieee80211_link_has_in_place_reservation(link, ctx))
continue;
old_ctx = ieee80211_link_get_chanctx(link);
@@ -1569,7 +1579,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
list_for_each_entry(link, &ctx->replace_ctx->assigned_links,
assigned_chanctx_list) {
n_assigned++;
- if (link->reserved_chanctx) {
+ if (ieee80211_link_has_in_place_reservation(link, ctx)) {
n_reserved++;
if (link->reserved_ready)
n_ready++;
@@ -1590,7 +1600,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
ctx->conf.radar_enabled = false;
list_for_each_entry(link, &ctx->reserved_links,
reserved_chanctx_list) {
- if (ieee80211_link_has_in_place_reservation(link) &&
+ if (ieee80211_link_has_in_place_reservation(link, ctx) &&
!link->reserved_ready)
return -EAGAIN;
@@ -1664,7 +1674,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
struct ieee80211_bss_conf *link_conf = link->conf;
u32 changed = 0;
- if (!ieee80211_link_has_in_place_reservation(link))
+ if (!ieee80211_link_has_in_place_reservation(link, ctx))
continue;
rcu_assign_pointer(link_conf->chanctx_conf,
@@ -1717,7 +1727,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
*/
list_for_each_entry_safe(link, link_tmp, &ctx->reserved_links,
reserved_chanctx_list) {
- if (WARN_ON(ieee80211_link_has_in_place_reservation(link)))
+ if (WARN_ON(ieee80211_link_has_in_place_reservation(link,
+ ctx)))
continue;
if (WARN_ON(link->reserved_chanctx != ctx))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0406/1887] fs: Free any excess xarray nodes in clear_inode()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (404 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0405/1887] wifi: mac80211: count only matching reservations in reserved switch Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0407/1887] mm/hugetlb: fix avoid_reserve to allow taking folio from subpool Greg Kroah-Hartman
` (592 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rik van Riel, Zi Yan, Jinjiang Tu,
Dave Jones, Matthew Wilcox (Oracle), Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit ee3f011250104129893d8e9599147e457d4d7280 ]
For many years we've had a hard to hit leak of xarray nodes. Hugh
documented it well in commit 786b31121a2c. Recently people and
syzbot have found ways to force it to happen with madvise. Rather
than fix the leaks where they happen, just call xa_destroy() which
has the side-effect of cycling the i_pages lock.
Cc: Rik van Riel <riel@surriel.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Link: https://lore.kernel.org/all/20260121062243.1893129-1-tujinjiang@huawei.com/
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Link: https://patch.msgid.link/20260623192850.1595958-1-willy@infradead.org
Reviewed-by: Rik van Riel <riel@surriel.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/fs/inode.c b/fs/inode.c
index 0036d5c68fd41..5c46e7bb931db 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -642,21 +642,18 @@ void dump_mapping(const struct address_space *mapping)
void clear_inode(struct inode *inode)
{
/*
- * We have to cycle the i_pages lock here because reclaim can be in the
- * process of removing the last page (in __filemap_remove_folio())
- * and we must not free the mapping under it.
+ * We have to cycle the i_pages lock here because reclaim
+ * can be in the process of removing the last page (in
+ * __filemap_remove_folio()) and we must not free the mapping
+ * under it. We also remove nodes which are empty; these
+ * can occur in two different ways. The first is that radix
+ * tree expansion can fail partway and the second is that THP
+ * collapse_file() can allocate some temporary nodes and not
+ * clean them up.
*/
- xa_lock_irq(&inode->i_data.i_pages);
+ xa_destroy(&inode->i_data.i_pages);
+
BUG_ON(inode->i_data.nrpages);
- /*
- * Almost always, mapping_empty(&inode->i_data) here; but there are
- * two known and long-standing ways in which nodes may get left behind
- * (when deep radix-tree node allocation failed partway; or when THP
- * collapse_file() failed). Until those two known cases are cleaned up,
- * or a cleanup function is called here, do not BUG_ON(!mapping_empty),
- * nor even WARN_ON(!mapping_empty).
- */
- xa_unlock_irq(&inode->i_data.i_pages);
BUG_ON(!list_empty(&inode->i_data.private_list));
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0407/1887] mm/hugetlb: fix avoid_reserve to allow taking folio from subpool
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (405 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0406/1887] fs: Free any excess xarray nodes in clear_inode() Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0408/1887] KVM: SVM: Use the active VMCBs MSR bitmap when checking if MSR is intercepted Greg Kroah-Hartman
` (591 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peter Xu, Ackerley Tng,
Oscar Salvador, Breno Leitao, Muchun Song, Naoya Horiguchi,
Rik van Riel, Roman Gushchin, Andrew Morton, Karl Mehltretter,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Xu <peterx@redhat.com>
commit 58db7c5fbe7daa42098d4965133a864f98ba90ba upstream.
Patch series "mm/hugetlb: Refactor hugetlb allocation resv accounting",
v2.
This is a follow up on Ackerley's series here as replacement:
https://lore.kernel.org/r/cover.1728684491.git.ackerleytng@google.com
The goal of this series is to cleanup hugetlb resv accounting, especially
during folio allocation, to decouple a few things:
- Hugetlb folios v.s. Hugetlbfs: IOW, the hope is in the future hugetlb
folios can be allocated completely without hugetlbfs.
- Decouple VMA v.s. hugetlb folio allocations: allocating a hugetlb folio
should not always require a hugetlbfs VMA. For example, either it got
allocated from the inode level (see hugetlbfs_fallocate() where it used
a pesudo VMA for allocation), or it can be allocated by other kernel
subsystems.
It paves way for other users to allocate hugetlb folios out of either
system reservations, or subpools (instead of hugetlbfs, as a file system).
For longer term, this prepares hugetlb as a separate concept versus
hugetlbfs, so that hugetlb folios can be allocated by not only hugetlbfs
and other things.
Tests I've done:
- I had a reproducer in patch 1 for the bug I found, this will start to
work after patch 1 or the whole set applied.
- Hugetlb regression tests (on x86_64 2MBs), includes:
- All vmtests on hugetlbfs
- libhugetlbfs test suite (which may fail some tests, but no new failures
will be introduced by this series, so all such failures happen before
this series so shouldn't be relevant).
This patch (of 7):
Since commit 04f2cbe35699 ("hugetlb: guarantee that COW faults for a
process that called mmap(MAP_PRIVATE) on hugetlbfs will succeed"),
avoid_reserve was introduced for a special case of CoW on hugetlb private
mappings, and only if the owner VMA is trying to allocate yet another
hugetlb folio that is not reserved within the private vma reserved map.
Later on, in commit d85f69b0b533 ("mm/hugetlb: alloc_huge_page handle
areas hole punched by fallocate"), alloc_huge_page() enforced to not
consume any global reservation as long as avoid_reserve=true. This
operation doesn't look correct, because even if it will enforce the
allocation to not use global reservation at all, it will still try to take
one reservation from the spool (if the subpool existed). Then since the
spool reserved pages take from global reservation, it'll also take one
reservation globally.
Logically it can cause global reservation to go wrong.
I wrote a reproducer below, trigger this special path, and every run of
such program will cause global reservation count to increment by one, until
it hits the number of free pages:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#define MSIZE (2UL << 20)
int main(int argc, char *argv[])
{
const char *path;
int *buf;
int fd, ret;
pid_t child;
if (argc < 2) {
printf("usage: %s <hugetlb_file>\n", argv[0]);
return -1;
}
path = argv[1];
fd = open(path, O_RDWR | O_CREAT, 0666);
if (fd < 0) {
perror("open failed");
return -1;
}
ret = fallocate(fd, 0, 0, MSIZE);
if (ret != 0) {
perror("fallocate");
return -1;
}
buf = mmap(NULL, MSIZE, PROT_READ|PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
perror("mmap() failed");
return -1;
}
/* Allocate a page */
*buf = 1;
child = fork();
if (child == 0) {
/* child doesn't need to do anything */
exit(0);
}
/* Trigger CoW from owner */
*buf = 2;
munmap(buf, MSIZE);
close(fd);
unlink(path);
return 0;
}
It can only reproduce with a sub-mount when there're reserved pages on the
spool, like:
# sysctl vm.nr_hugepages=128
# mkdir ./hugetlb-pool
# mount -t hugetlbfs -o min_size=8M,pagesize=2M none ./hugetlb-pool
Then run the reproducer on the mountpoint:
# ./reproducer ./hugetlb-pool/test
Fix it by taking the reservation from spool if available. In general,
avoid_reserve is IMHO more about "avoid vma resv map", not spool's.
I copied stable, however I have no intention for backporting if it's not a
clean cherry-pick, because private hugetlb mapping, and then fork() on top
is too rare to hit.
Link: https://lkml.kernel.org/r/20250107204002.2683356-1-peterx@redhat.com
Link: https://lkml.kernel.org/r/20250107204002.2683356-2-peterx@redhat.com
Fixes: d85f69b0b533 ("mm/hugetlb: alloc_huge_page handle areas hole punched by fallocate")
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Tested-by: Ackerley Tng <ackerleytng@google.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Cc: Breno Leitao <leitao@debian.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Karl Mehltretter: The upstream changes map directly to this stable tree's
page-based HugeTLB helpers. The backport retains this stable tree's direct
-ENOSPC return instead of importing the later out_end_reservation path;
the functional changes otherwise match upstream. ]
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 22 +++-------------------
1 file changed, 3 insertions(+), 19 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index a44a6602659cf..cfe083798f3b4 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1397,8 +1397,7 @@ static unsigned long available_huge_pages(struct hstate *h)
static struct page *dequeue_huge_page_vma(struct hstate *h,
struct vm_area_struct *vma,
- unsigned long address, int avoid_reserve,
- long chg)
+ unsigned long address, long chg)
{
struct page *page = NULL;
struct mempolicy *mpol;
@@ -1414,10 +1413,6 @@ static struct page *dequeue_huge_page_vma(struct hstate *h,
if (!vma_has_reserves(vma, chg) && !available_huge_pages(h))
goto err;
- /* If reserves cannot be used, ensure enough pages are in the pool */
- if (avoid_reserve && !available_huge_pages(h))
- goto err;
-
gfp_mask = htlb_alloc_mask(h);
nid = huge_node(vma, address, gfp_mask, &mpol, &nodemask);
@@ -1431,7 +1426,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h,
if (!page)
page = dequeue_huge_page_nodemask(h, gfp_mask, nid, nodemask);
- if (page && !avoid_reserve && vma_has_reserves(vma, chg)) {
+ if (page && vma_has_reserves(vma, chg)) {
SetHPageRestoreReserve(page);
h->resv_huge_pages--;
}
@@ -3114,17 +3109,6 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
vma_end_reservation(h, vma, addr);
return ERR_PTR(-ENOSPC);
}
-
- /*
- * Even though there was no reservation in the region/reserve
- * map, there could be reservations associated with the
- * subpool that can be used. This would be indicated if the
- * return value of hugepage_subpool_get_pages() is zero.
- * However, if avoid_reserve is specified we still avoid even
- * the subpool reservations.
- */
- if (avoid_reserve)
- gbl_chg = 1;
}
/* If this allocation is not consuming a reservation, charge it now.
@@ -3147,7 +3131,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
* from the global free pool (global change). gbl_chg == 0 indicates
* a reservation exists for the allocation.
*/
- page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg);
+ page = dequeue_huge_page_vma(h, vma, addr, gbl_chg);
if (!page) {
spin_unlock_irq(&hugetlb_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0408/1887] KVM: SVM: Use the active VMCBs MSR bitmap when checking if MSR is intercepted
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (406 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0407/1887] mm/hugetlb: fix avoid_reserve to allow taking folio from subpool Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0409/1887] wifi: mac80211: set info->band for 802.3 encap offload frames Greg Kroah-Hartman
` (590 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 9e06bbb9ade7cdf28d4a3b5b14e5812881c8df85 ]
Use the MSR permission bitmap of the active VMCB instead of assuming that
KVM is always using vmcb02's bitmap when L2 is active, as KVM uses msrpm02
if and only if L1 wants to intercept MSR accesses, i.e. if and only if KVM
needs to merge msprm01 with msrpm12.
Don't bother tracking the virtual address of the bitmap that's being used,
as __va() is cheap on x86, and caching the virtual address would introduce
yet another source of potentially stale information.
Fixes: b2ac58f90540 ("KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL")
Cc: stable@vger.kernel.org
Reported-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260826195833.844526-1-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ sashal: adapted direct svm access to to_svm(vcpu) for the existing msr_write_intercepted() signature ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/svm.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 88979fefaa284..488e954a4483a 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -732,17 +732,7 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
u32 offset;
u32 *msrpm;
- /*
- * For non-nested case:
- * If the L01 MSR bitmap does not intercept the MSR, then we need to
- * save it.
- *
- * For nested case:
- * If the L02 MSR bitmap does not intercept the MSR, then we need to
- * save it.
- */
- msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm:
- to_svm(vcpu)->msrpm;
+ msrpm = __va(__sme_clr(to_svm(vcpu)->vmcb->control.msrpm_base_pa));
offset = svm_msrpm_offset(msr);
bit_write = 2 * (msr & 0x0f) + 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0409/1887] wifi: mac80211: set info->band for 802.3 encap offload frames
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (407 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0408/1887] KVM: SVM: Use the active VMCBs MSR bitmap when checking if MSR is intercepted Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0410/1887] smb: client: discard post-EOF pagecache when extending a file via zero range Greg Kroah-Hartman
` (589 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrea Pesaresi, Felix Fietkau,
Johannes Berg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 4febc02cd02f021f2b6d0768332be643ef14a12d ]
Unlike the 802.11 TX paths, ieee80211_8023_xmit() does not set
info->band from the channel context on non-MLD interfaces. It stays at
0, so ieee80211_get_tx_rates() uses the wrong band for these frames.
Set it the same way as ieee80211_build_hdr(): drop the frame if there is
no channel context, and leave the band at 0 on MLD interfaces.
Reported-by: Andrea Pesaresi <andreapesaresi82@gmail.com>
Fixes: 50ff477a8639 ("mac80211: add 802.11 encapsulation offloading support")
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260926120216.4054712-1-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ sashal: Adapted helper usage to direct valid_links checks and single-packet kfree_skb() cleanup. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tx.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 00e8eda67f130..51cf8c4e0e90a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4545,6 +4545,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_tx_info *info;
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_chanctx_conf *chanctx_conf;
struct tid_ampdu_tx *tid_tx;
u8 tid;
@@ -4602,6 +4603,16 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
sdata = container_of(sdata->bss,
struct ieee80211_sub_if_data, u.ap);
+ /* MLD transmissions must not rely on the band */
+ if (!sdata->vif.valid_links) {
+ chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+ if (unlikely(!chanctx_conf)) {
+ kfree_skb(skb);
+ return;
+ }
+ info->band = chanctx_conf->def.chan->band;
+ }
+
info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP;
info->control.vif = &sdata->vif;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0410/1887] smb: client: discard post-EOF pagecache when extending a file via zero range
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (408 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0409/1887] wifi: mac80211: set info->band for 802.3 encap offload frames Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0411/1887] iio: adc: ad_sigma_delta: fix use-after-free on unbind Greg Kroah-Hartman
` (588 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Namjae Jeon,
Paulo Alcantara, Christian Brauner, Matthew Wilcox,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
[ Upstream commit da4fe97fb6c730d9c94a115c7bfa6f98e0d578d0 ]
smb3_zero_range() removed the pagecache only for the range being zeroed,
so when it extends the file the folio straddling the old EOF - which may
hold data dirtied past EOF through an mmap - was never dropped and became
visible as file content once the file was extended.
Lower the discard boundary to the smaller of the zero-range offset and the
old EOF.
Fixes: 72c419d9b073 ("cifs: fix smb3_zero_range so it can expand the file-size when required")
Reviewed-by: David Howells <dhowells@redhat.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
[ sashal: Adjusted context because smb3_zero_range() lacks netfs_wait_for_outstanding_io(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 973a46daa37b3..3278591b3647b 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3542,8 +3542,11 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
/*
* We zero the range through ioctl, so we need remove the page caches
* first, otherwise the data may be inconsistent with the server.
+ *
+ * Start at the old EOF when extending so the folio straddling it, which
+ * may hold data written past EOF through an mmap, is dropped too.
*/
- truncate_pagecache_range(inode, offset, offset + len - 1);
+ truncate_pagecache_range(inode, min(offset, i_size), offset + len - 1);
/* if file not oplocked can't be sure whether asking to extend size */
rc = -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0411/1887] iio: adc: ad_sigma_delta: fix use-after-free on unbind
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (409 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0410/1887] smb: client: discard post-EOF pagecache when extending a file via zero range Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0412/1887] iio: adc: aspeed: Simplify with dev_err_probe Greg Kroah-Hartman
` (587 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Nuno Sá,
Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 9ee8306121495d2a25aa5d1bfd519f2748786b83 ]
ad_sd_buffer_postenable() allocates sigma_delta->samples_buf with
devm_krealloc() at runtime, so its devres entry sits after all
probe-time entries of the driver. devm resources are released in
reverse allocation order, which means unbind frees samples_buf before
iio_device_unregister() disables the buffers and detaches the trigger
pollfunc. The data ready IRQ is still enabled at that point, so
ad_sd_trigger_handler() can still run and memcpy() incoming samples
into the freed samples_buf.
Fix this by preallocating the buffer in
devm_ad_sd_setup_buffer_and_trigger(), before the triggered buffer and
the IRQ are set up, so it is freed only after iio_device_unregister()
has drained the trigger handler via free_irq(). Size it for the worst
case of all sequencer slots being active; ad_sd_validate_scan_mask()
already caps the number of active channels at num_slots.
This issue was found by an in-house static analysis tool.
Fixes: 8bea9af887de ("iio: adc: ad_sigma_delta: Add sequencer support")
Cc: stable@vger.kernel.org
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ sashal: adapted buffer allocation to the unconditional buffer setup code. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/ad_sigma_delta.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index 914274ed899ec..45e0f638c0ed1 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -343,9 +343,8 @@ EXPORT_SYMBOL_NS_GPL(ad_sigma_delta_single_conversion, IIO_AD_SIGMA_DELTA);
static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
{
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
- unsigned int i, slot, samples_buf_size;
+ unsigned int i, slot;
unsigned int channel;
- uint8_t *samples_buf;
int ret;
if (sigma_delta->num_slots == 1) {
@@ -378,15 +377,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
return ret;
}
- samples_buf_size = ALIGN(slot * indio_dev->channels[0].scan_type.storagebits / 8, 8);
- samples_buf_size += sizeof(int64_t);
- samples_buf = devm_krealloc(&sigma_delta->spi->dev, sigma_delta->samples_buf,
- samples_buf_size, GFP_KERNEL);
- if (!samples_buf)
- return -ENOMEM;
-
- sigma_delta->samples_buf = samples_buf;
-
spi_bus_lock(sigma_delta->spi->master);
sigma_delta->bus_locked = true;
sigma_delta->keep_cs_asserted = true;
@@ -620,6 +610,7 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de
int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev)
{
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+ unsigned int samples_buf_size;
int ret;
sigma_delta->slots = devm_kcalloc(dev, sigma_delta->num_slots,
@@ -627,6 +618,19 @@ int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indi
if (!sigma_delta->slots)
return -ENOMEM;
+ /*
+ * Worst-case size: all sequencer slots can be active, capped
+ * at num_slots by ad_sd_validate_scan_mask().
+ */
+ samples_buf_size =
+ ALIGN(sigma_delta->num_slots *
+ BITS_TO_BYTES(indio_dev->channels[0].scan_type.storagebits),
+ sizeof(s64));
+ samples_buf_size += sizeof(s64);
+ sigma_delta->samples_buf = devm_kzalloc(dev, samples_buf_size, GFP_KERNEL);
+ if (!sigma_delta->samples_buf)
+ return -ENOMEM;
+
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
&iio_pollfunc_store_time,
&ad_sd_trigger_handler,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0412/1887] iio: adc: aspeed: Simplify with dev_err_probe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (410 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0411/1887] iio: adc: ad_sigma_delta: fix use-after-free on unbind Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0413/1887] iio: adc: aspeed: propagate reset deassert errors Greg Kroah-Hartman
` (586 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Krzysztof Kozlowski,
Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
[ Upstream commit dcc3ac29f46fff6775c0a945afc68fd9dece6d34 ]
Use dev_err_probe() to make error code handling simpler and handle
deferred probe nicely (avoid spamming logs).
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Stable-dep-of: 95e4eb426b4b ("iio: adc: aspeed: propagate reset deassert errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/aspeed_adc.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 998e8bcc06e1d..e6a9d8d77af53 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -549,11 +549,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
return PTR_ERR(data->clk_scaler);
data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
- if (IS_ERR(data->rst)) {
- dev_err(&pdev->dev,
- "invalid or missing reset controller device tree entry");
- return PTR_ERR(data->rst);
- }
+ if (IS_ERR(data->rst))
+ return dev_err_probe(&pdev->dev, PTR_ERR(data->rst),
+ "invalid or missing reset controller device tree entry");
+
reset_control_deassert(data->rst);
ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0413/1887] iio: adc: aspeed: propagate reset deassert errors
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (411 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0412/1887] iio: adc: aspeed: Simplify with dev_err_probe Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0414/1887] iio: adc: max1363: sign-extend bipolar differential channel reads Greg Kroah-Hartman
` (585 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Jonathan Cameron,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 95e4eb426b4bd666fa2f37886c0ddf74a0cc6167 ]
aspeed_adc_probe() continues to register ADC resources after deasserting
the shared reset, even if the reset controller reports a failure.
A failed deassertion leaves the hardware unavailable, so stop probing
before installing the cleanup action and enabling the ADC.
Fixes: edf7550a1f93 ("iio: adc: aspeed: Deassert reset in probe")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/aspeed_adc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index e6a9d8d77af53..4cb2210cb38d7 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -553,7 +553,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(data->rst),
"invalid or missing reset controller device tree entry");
- reset_control_deassert(data->rst);
+ ret = reset_control_deassert(data->rst);
+ if (ret)
+ return ret;
ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
data->rst);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0414/1887] iio: adc: max1363: sign-extend bipolar differential channel reads
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (412 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0413/1887] iio: adc: aspeed: propagate reset deassert errors Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0415/1887] iio: adc: axp288: Add TS bias override for Haier HV103H Greg Kroah-Hartman
` (584 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Andy Shevchenko,
Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
[ Upstream commit 91908c0a78baddc8572aa3ab69e62ee2eb496ba4 ]
MAX1363 differential channels are bipolar, but max1363_read_single_chan()
masks the raw value to the ADC resolution without sign-extending it.
Negative differential readings are therefore reported to userspace as
large positive values (e.g. -1 as 4095 on a 12-bit part).
Sign-extend the masked value from the resolution bit for differential
channels. Single-ended channels are unipolar and are left unchanged.
Fixes: d1325cf45077 ("Staging: IIO: max1363 ADC driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/max1363.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 875f5ff202082..bbb2336006a98 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -408,6 +408,14 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
}
data = rxbuf[0];
}
+
+ /*
+ * Differential channels are bipolar and the device returns the sample
+ * in two's complement, so sign-extend it from the resolution bit.
+ */
+ if (chan->differential)
+ data = sign_extend32(data, st->chip_info->bits - 1);
+
*val = data;
error_ret:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0415/1887] iio: adc: axp288: Add TS bias override for Haier HV103H
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (413 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0414/1887] iio: adc: max1363: sign-extend bipolar differential channel reads Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0416/1887] iio: adc: stm32-adc: fix possible division by zero in processed channel Greg Kroah-Hartman
` (583 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladyslav Ivashchenko, Hans de Goede,
Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladyslav Ivashchenko <cactucatu4eckuu@gmail.com>
[ Upstream commit 0f300db7b7315b2c7ea0e2d4437b88de162d191f ]
The Haier HV103H firmware configures the AXP288 TS pin bias
current to 60 uA. This causes the battery temperature reading to
cross the charging temperature threshold under load, incorrectly
stopping battery charging.
Setting the TS bias current to 80 uA fixes the temperature
measurement and prevents charging from being incorrectly disabled.
Add a DMI quirk to use the 80 uA TS bias current on the Haier
HV103H.
Fixes: 9bcf15f75cac ("iio: adc: axp288: Fix TS-pin handling")
Fixes: 048058399f19 ("iio: adc: axp288: Override TS pin bias current for some models") # Add necessary infrastructure
Signed-off-by: Vladyslav Ivashchenko <cactucatu4eckuu@gmail.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ sashal: Adjusted context to match the existing {} table terminator. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/axp288_adc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c
index 580361bd98492..3ccdfe9dea3f5 100644
--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -204,6 +204,14 @@ static const struct dmi_system_id axp288_adc_ts_bias_override[] = {
},
.driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA,
},
+ {
+ /* Haier HV103H */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Haier"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HV103H"),
+ },
+ .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA,
+ },
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0416/1887] iio: adc: stm32-adc: fix possible division by zero in processed channel
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (414 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0415/1887] iio: adc: axp288: Add TS bias override for Haier HV103H Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0417/1887] iio: cdc: ad7150: fix OF matching and publish module aliases Greg Kroah-Hartman
` (582 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Fabrice Gasnier,
Andy Shevchenko, Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
[ Upstream commit c5de6a6f855fdcf1e0ea549fb227a316db51c405 ]
In case the conversion has failed or returned zero, processing *val
can lead to a division by zero. Need to check for errors, or converted
value is zero, before processing the data. In case the converted value
is zero, e.g. the Vrefint channel, this should be considered as invalid
in all cases.
Fixes: 0e346b2cfa85 ("iio: adc: stm32-adc: add vrefint calibration support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260911161555.244F31F000FF@smtp.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ sashal: Changed iio_device_release_direct() to iio_device_release_direct_mode(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/stm32-adc.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index 6fede34091cc2..6a666d14a609d 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -1372,11 +1372,16 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
ret = stm32_adc_single_conv(indio_dev, chan, val);
else
ret = -EINVAL;
+ iio_device_release_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
- if (mask == IIO_CHAN_INFO_PROCESSED)
+ if (mask == IIO_CHAN_INFO_PROCESSED) {
+ if (*val == 0)
+ return -EINVAL;
*val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val;
+ }
- iio_device_release_direct_mode(indio_dev);
return ret;
case IIO_CHAN_INFO_SCALE:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0417/1887] iio: cdc: ad7150: fix OF matching and publish module aliases
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (415 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0416/1887] iio: adc: stm32-adc: fix possible division by zero in processed channel Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0418/1887] fs/ntfs3: Add more checks in mi_enum_attr (part 2) Greg Kroah-Hartman
` (581 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Jonathan Cameron,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <hppiscas@163.com>
[ Upstream commit 52da294027f53e7084c18dd4b4f73354a40382f3 ]
The OF match entries use positional initializers, which initialize the
name field rather than compatible. Consequently the advertised AD7150,
AD7151 and AD7156 compatible strings do not describe OF compatible
matches. The table is also not exported for module alias generation.
Use designated compatible initializers and publish the OF table. Keep
the existing I2C ID table and its device-variant selection unchanged.
The issue was found by our static-analysis tool.
Fixes: 89f2d5b080bc ("staging:iio:cdc:ad7150: Add of_match_table")
Assisted-by: LLM
Cc: stable@vger.kernel.org
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ sashal: Adjusted context for the OF match-table terminator’s existing {} formatting. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/cdc/ad7150.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c
index ebe112b4618b0..023b4fd09b254 100644
--- a/drivers/iio/cdc/ad7150.c
+++ b/drivers/iio/cdc/ad7150.c
@@ -653,11 +653,13 @@ static const struct i2c_device_id ad7150_id[] = {
MODULE_DEVICE_TABLE(i2c, ad7150_id);
static const struct of_device_id ad7150_of_match[] = {
- { "adi,ad7150" },
- { "adi,ad7151" },
- { "adi,ad7156" },
+ { .compatible = "adi,ad7150" },
+ { .compatible = "adi,ad7151" },
+ { .compatible = "adi,ad7156" },
{}
};
+MODULE_DEVICE_TABLE(of, ad7150_of_match);
+
static struct i2c_driver ad7150_driver = {
.driver = {
.name = "ad7150",
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0418/1887] fs/ntfs3: Add more checks in mi_enum_attr (part 2)
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (416 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0417/1887] iio: cdc: ad7150: fix OF matching and publish module aliases Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0419/1887] fs/ntfs3: Mark inode as bad as soon as error detected in mi_enum_attr() Greg Kroah-Hartman
` (580 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, lei lu, Konstantin Komarov,
Nikita Nagornyi, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Upstream commit a8f659ce14f8f734894227ba2c5ca78c8451501e ]
Add offset check before access to attr->non_res field as mentioned in [1].
[1] https://lore.kernel.org/ntfs3/20241010110005.42792-1-llfamsec@gmail.com/
Suggested-by: lei lu <llfamsec@gmail.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Nikita Nagornyi <nagornyi@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/record.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
index bfb1f4c2f271b..d8d43f6a96fd0 100644
--- a/fs/ntfs3/record.c
+++ b/fs/ntfs3/record.c
@@ -206,7 +206,7 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
return NULL;
if (off >= used || off < MFTRECORD_FIXUP_OFFSET_1 ||
- !IS_ALIGNED(off, 4)) {
+ !IS_ALIGNED(off, 8)) {
return NULL;
}
@@ -230,8 +230,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
off += asize;
}
- /* Can we use the first field (attr->type). */
- /* NOTE: this code also checks attr->size availability. */
+ /*
+ * Can we use the first fields:
+ * attr->type,
+ * attr->size
+ */
if (off + 8 > used) {
static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
return NULL;
@@ -253,10 +256,17 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
asize = le32_to_cpu(attr->size);
+ if (!IS_ALIGNED(asize, 8))
+ return NULL;
+
/* Check overflow and boundary. */
if (off + asize < off || off + asize > used)
return NULL;
+ /* Can we use the field attr->non_res. */
+ if (off + 9 > used)
+ return NULL;
+
/* Check size of attribute. */
if (!attr->non_res) {
/* Check resident fields. */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0419/1887] fs/ntfs3: Mark inode as bad as soon as error detected in mi_enum_attr()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (417 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0418/1887] fs/ntfs3: Add more checks in mi_enum_attr (part 2) Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0420/1887] fs/ntfs3: fix KMSAN uninit-value in ni_create_attr_list Greg Kroah-Hartman
` (579 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+73d8fc29ec7cba8286fa,
Konstantin Komarov, Nikita Nagornyi, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Upstream commit 2afd4d267e6dbaec8d3ccd4f5396cb84bc67aa2e ]
Extended the `mi_enum_attr()` function interface with an additional
parameter, `struct ntfs_inode *ni`, to allow marking the inode
as bad as soon as an error is detected.
Reported-by: syzbot+73d8fc29ec7cba8286fa@syzkaller.appspotmail.com
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Backport to 6.1.y: passed `ni` to an extra `mi_find_attr()` caller
that mainline had refactored differently. `mi_find_attr()`'s `name_len`
argument is kept as 6.1.y's `size_t`. Kept 6.1.y's last resident fields
check in `mi_enum_attr()` but replaced `return NULL` with `goto out`. ]
Signed-off-by: Nikita Nagornyi <nagornyi@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/attrib.c | 11 ++++---
fs/ntfs3/frecord.c | 59 ++++++++++++++++++----------------
fs/ntfs3/ntfs_fs.h | 21 ++++++------
fs/ntfs3/record.c | 79 ++++++++++++++++++++++++----------------------
4 files changed, 90 insertions(+), 80 deletions(-)
diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index f4573d276a2cc..db4f2dffed950 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -815,7 +815,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
if (err)
goto out;
- attr = mi_find_attr(mi, NULL, type, name, name_len, &le->id);
+ attr = mi_find_attr(ni, mi, NULL, type, name, name_len,
+ &le->id);
if (!attr) {
err = -EINVAL;
goto bad_inode;
@@ -1166,7 +1167,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
goto out;
}
- attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0,
+ attr = mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0,
&le->id);
if (!attr) {
err = -EINVAL;
@@ -1786,7 +1787,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
goto out;
}
- attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0,
+ attr = mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0,
&le->id);
if (!attr) {
err = -EINVAL;
@@ -2031,8 +2032,8 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
}
/* Look for required attribute. */
- attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL,
- 0, &le->id);
+ attr = mi_find_attr(ni, mi, NULL, ATTR_DATA,
+ NULL, 0, &le->id);
if (!attr) {
err = -EINVAL;
goto out;
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index fcdaea02ba04d..17559fca5984c 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -75,7 +75,7 @@ struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni)
{
const struct ATTRIB *attr;
- attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
+ attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO))
: NULL;
}
@@ -89,7 +89,7 @@ struct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni)
{
const struct ATTRIB *attr;
- attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
+ attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO5))
: NULL;
@@ -201,7 +201,8 @@ struct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr,
*mi = &ni->mi;
/* Look for required attribute in primary record. */
- return mi_find_attr(&ni->mi, attr, type, name, name_len, NULL);
+ return mi_find_attr(ni, &ni->mi, attr, type, name, name_len,
+ NULL);
}
/* First look for list entry of required type. */
@@ -217,7 +218,7 @@ struct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr,
return NULL;
/* Look for required attribute. */
- attr = mi_find_attr(m, NULL, type, name, name_len, &le->id);
+ attr = mi_find_attr(ni, m, NULL, type, name, name_len, &le->id);
if (!attr)
goto out;
@@ -258,7 +259,7 @@ struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr,
if (mi)
*mi = &ni->mi;
/* Enum attributes in primary record. */
- return mi_enum_attr(&ni->mi, attr);
+ return mi_enum_attr(ni, &ni->mi, attr);
}
/* Get next list entry. */
@@ -274,7 +275,7 @@ struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr,
*mi = mi2;
/* Find attribute in loaded record. */
- return rec_find_attr_le(mi2, le2);
+ return rec_find_attr_le(ni, mi2, le2);
}
/*
@@ -292,7 +293,8 @@ struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
if (!ni->attr_list.size) {
if (pmi)
*pmi = &ni->mi;
- return mi_find_attr(&ni->mi, NULL, type, name, name_len, NULL);
+ return mi_find_attr(ni, &ni->mi, NULL, type, name, name_len,
+ NULL);
}
le = al_find_ex(ni, NULL, type, name, name_len, NULL);
@@ -318,7 +320,7 @@ struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
if (pmi)
*pmi = mi;
- attr = mi_find_attr(mi, NULL, type, name, name_len, &le->id);
+ attr = mi_find_attr(ni, mi, NULL, type, name, name_len, &le->id);
if (!attr)
return NULL;
@@ -399,7 +401,8 @@ int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
int diff;
if (base_only || type == ATTR_LIST || !ni->attr_list.size) {
- attr = mi_find_attr(&ni->mi, NULL, type, name, name_len, id);
+ attr = mi_find_attr(ni, &ni->mi, NULL, type, name, name_len,
+ id);
if (!attr)
return -ENOENT;
@@ -438,7 +441,7 @@ int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
al_remove_le(ni, le);
- attr = mi_find_attr(mi, NULL, type, name, name_len, id);
+ attr = mi_find_attr(ni, mi, NULL, type, name, name_len, id);
if (!attr)
return -ENOENT;
@@ -486,7 +489,7 @@ ni_ins_new_attr(struct ntfs_inode *ni, struct mft_inode *mi,
name = le->name;
}
- attr = mi_insert_attr(mi, type, name, name_len, asize, name_off);
+ attr = mi_insert_attr(ni, mi, type, name, name_len, asize, name_off);
if (!attr) {
if (le_added)
al_remove_le(ni, le);
@@ -670,7 +673,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
if (err)
return err;
- attr_list = mi_find_attr(&ni->mi, NULL, ATTR_LIST, NULL, 0, NULL);
+ attr_list = mi_find_attr(ni, &ni->mi, NULL, ATTR_LIST, NULL, 0, NULL);
if (!attr_list)
return 0;
@@ -692,7 +695,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
if (!mi)
return 0;
- attr = mi_find_attr(mi, NULL, le->type, le_name(le),
+ attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
le->name_len, &le->id);
if (!attr)
return 0;
@@ -728,7 +731,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
goto out;
}
- attr = mi_find_attr(mi, NULL, le->type, le_name(le),
+ attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
le->name_len, &le->id);
if (!attr) {
/* Should never happened, 'cause already checked. */
@@ -737,7 +740,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
asize = le32_to_cpu(attr->size);
/* Insert into primary record. */
- attr_ins = mi_insert_attr(&ni->mi, le->type, le_name(le),
+ attr_ins = mi_insert_attr(ni, &ni->mi, le->type, le_name(le),
le->name_len, asize,
le16_to_cpu(attr->name_off));
if (!attr_ins) {
@@ -765,7 +768,7 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
if (!mi)
continue;
- attr = mi_find_attr(mi, NULL, le->type, le_name(le),
+ attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
le->name_len, &le->id);
if (!attr)
continue;
@@ -830,7 +833,7 @@ int ni_create_attr_list(struct ntfs_inode *ni)
free_b = 0;
attr = NULL;
- for (; (attr = mi_enum_attr(&ni->mi, attr)); le = Add2Ptr(le, sz)) {
+ for (; (attr = mi_enum_attr(ni, &ni->mi, attr)); le = Add2Ptr(le, sz)) {
sz = le_size(attr->name_len);
le->type = attr->type;
le->size = cpu_to_le16(sz);
@@ -885,7 +888,7 @@ int ni_create_attr_list(struct ntfs_inode *ni)
u32 asize = le32_to_cpu(b->size);
u16 name_off = le16_to_cpu(b->name_off);
- attr = mi_insert_attr(mi, b->type, Add2Ptr(b, name_off),
+ attr = mi_insert_attr(ni, mi, b->type, Add2Ptr(b, name_off),
b->name_len, asize, name_off);
if (!attr)
goto out1;
@@ -908,7 +911,7 @@ int ni_create_attr_list(struct ntfs_inode *ni)
goto out1;
}
- attr = mi_insert_attr(&ni->mi, ATTR_LIST, NULL, 0,
+ attr = mi_insert_attr(ni, &ni->mi, ATTR_LIST, NULL, 0,
lsize + SIZEOF_RESIDENT, SIZEOF_RESIDENT);
if (!attr)
goto out1;
@@ -995,13 +998,13 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le,
mi = rb_entry(node, struct mft_inode, node);
if (is_mft_data &&
- (mi_enum_attr(mi, NULL) ||
+ (mi_enum_attr(ni, mi, NULL) ||
vbo <= ((u64)mi->rno << sbi->record_bits))) {
/* We can't accept this record 'cause MFT's bootstrapping. */
continue;
}
if (is_mft &&
- mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, NULL)) {
+ mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0, NULL)) {
/*
* This child record already has a ATTR_DATA.
* So it can't accept any other records.
@@ -1010,7 +1013,7 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le,
}
if ((type != ATTR_NAME || name_len) &&
- mi_find_attr(mi, NULL, type, name, name_len, NULL)) {
+ mi_find_attr(ni, mi, NULL, type, name, name_len, NULL)) {
/* Only indexed attributes can share same record. */
continue;
}
@@ -1159,7 +1162,7 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
/* Estimate the result of moving all possible attributes away. */
attr = NULL;
- while ((attr = mi_enum_attr(&ni->mi, attr))) {
+ while ((attr = mi_enum_attr(ni, &ni->mi, attr))) {
if (attr->type == ATTR_STD)
continue;
if (attr->type == ATTR_LIST)
@@ -1177,7 +1180,7 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
attr = NULL;
for (;;) {
- attr = mi_enum_attr(&ni->mi, attr);
+ attr = mi_enum_attr(ni, &ni->mi, attr);
if (!attr) {
/* We should never be here 'cause we have already check this case. */
err = -EINVAL;
@@ -1261,7 +1264,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
mi = rb_entry(node, struct mft_inode, node);
- attr = mi_enum_attr(mi, NULL);
+ attr = mi_enum_attr(ni, mi, NULL);
if (!attr) {
mft_min = mi->rno;
@@ -1282,7 +1285,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
ni_remove_mi(ni, mi_new);
}
- attr = mi_find_attr(&ni->mi, NULL, ATTR_DATA, NULL, 0, NULL);
+ attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_DATA, NULL, 0, NULL);
if (!attr) {
err = -EINVAL;
goto out;
@@ -1399,7 +1402,7 @@ int ni_expand_list(struct ntfs_inode *ni)
continue;
/* Find attribute in primary record. */
- attr = rec_find_attr_le(&ni->mi, le);
+ attr = rec_find_attr_le(ni, &ni->mi, le);
if (!attr) {
err = -EINVAL;
goto out;
@@ -3436,7 +3439,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
if (!mi->dirty)
continue;
- is_empty = !mi_enum_attr(mi, NULL);
+ is_empty = !mi_enum_attr(ni, mi, NULL);
if (is_empty)
clear_rec_inuse(mi->mrec);
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 482958c016444..d29fdefb477bf 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -733,23 +733,24 @@ int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi);
void mi_put(struct mft_inode *mi);
int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno);
int mi_read(struct mft_inode *mi, bool is_mft);
-struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr);
-// TODO: id?
-struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr,
- enum ATTR_TYPE type, const __le16 *name,
- size_t name_len, const __le16 *id);
-static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec,
+struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ struct ATTRIB *attr);
+struct ATTRIB *mi_find_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ struct ATTRIB *attr, enum ATTR_TYPE type,
+ const __le16 *name, size_t name_len, const __le16 *id);
+static inline struct ATTRIB *rec_find_attr_le(struct ntfs_inode *ni,
+ struct mft_inode *rec,
struct ATTR_LIST_ENTRY *le)
{
- return mi_find_attr(rec, NULL, le->type, le_name(le), le->name_len,
+ return mi_find_attr(ni, rec, NULL, le->type, le_name(le), le->name_len,
&le->id);
}
int mi_write(struct mft_inode *mi, int wait);
int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
__le16 flags, bool is_mft);
-struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
- const __le16 *name, u8 name_len, u32 asize,
- u16 name_off);
+struct ATTRIB *mi_insert_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ enum ATTR_TYPE type, const __le16 *name,
+ u8 name_len, u32 asize, u16 name_off);
bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi,
struct ATTRIB *attr);
diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
index d8d43f6a96fd0..1393e93fef132 100644
--- a/fs/ntfs3/record.c
+++ b/fs/ntfs3/record.c
@@ -31,7 +31,7 @@ static inline int compare_attr(const struct ATTRIB *left, enum ATTR_TYPE type,
*
* Return: Unused attribute id that is less than mrec->next_attr_id.
*/
-static __le16 mi_new_attt_id(struct mft_inode *mi)
+static __le16 mi_new_attt_id(struct ntfs_inode *ni, struct mft_inode *mi)
{
u16 free_id, max_id, t16;
struct MFT_REC *rec = mi->mrec;
@@ -52,7 +52,7 @@ static __le16 mi_new_attt_id(struct mft_inode *mi)
attr = NULL;
for (;;) {
- attr = mi_enum_attr(mi, attr);
+ attr = mi_enum_attr(ni, mi, attr);
if (!attr) {
rec->next_attr_id = cpu_to_le16(max_id + 1);
mi->dirty = true;
@@ -189,7 +189,8 @@ int mi_read(struct mft_inode *mi, bool is_mft)
return err;
}
-struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ struct ATTRIB *attr)
{
const struct MFT_REC *rec = mi->mrec;
u32 used = le32_to_cpu(rec->used);
@@ -203,11 +204,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
off = le16_to_cpu(rec->attr_off);
if (used > total)
- return NULL;
+ goto out;
if (off >= used || off < MFTRECORD_FIXUP_OFFSET_1 ||
!IS_ALIGNED(off, 8)) {
- return NULL;
+ goto out;
}
/* Skip non-resident records. */
@@ -237,7 +238,7 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
*/
if (off + 8 > used) {
static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
- return NULL;
+ goto out;
}
if (attr->type == ATTR_END) {
@@ -248,41 +249,41 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
/* 0x100 is last known attribute for now. */
t32 = le32_to_cpu(attr->type);
if (!t32 || (t32 & 0xf) || (t32 > 0x100))
- return NULL;
+ goto out;
/* attributes in record must be ordered by type */
if (t32 < prev_type)
- return NULL;
+ goto out;
asize = le32_to_cpu(attr->size);
if (!IS_ALIGNED(asize, 8))
- return NULL;
+ goto out;
/* Check overflow and boundary. */
if (off + asize < off || off + asize > used)
- return NULL;
+ goto out;
/* Can we use the field attr->non_res. */
if (off + 9 > used)
- return NULL;
+ goto out;
/* Check size of attribute. */
if (!attr->non_res) {
/* Check resident fields. */
if (asize < SIZEOF_RESIDENT)
- return NULL;
+ goto out;
t16 = le16_to_cpu(attr->res.data_off);
if (t16 > asize)
- return NULL;
+ goto out;
if (le32_to_cpu(attr->res.data_size) > asize - t16)
- return NULL;
+ goto out;
if (attr->name_len &&
le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) {
- return NULL;
+ goto out;
}
return attr;
@@ -290,71 +291,75 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
/* Check nonresident fields. */
if (attr->non_res != 1)
- return NULL;
+ goto out;
/* Can we use memory including attr->nres.valid_size? */
if (asize < SIZEOF_NONRESIDENT)
- return NULL;
+ goto out;
t16 = le16_to_cpu(attr->nres.run_off);
if (t16 > asize)
- return NULL;
+ goto out;
t32 = sizeof(short) * attr->name_len;
if (t32 && le16_to_cpu(attr->name_off) + t32 > t16)
- return NULL;
+ goto out;
/* Check start/end vcn. */
if (le64_to_cpu(attr->nres.svcn) > le64_to_cpu(attr->nres.evcn) + 1)
- return NULL;
+ goto out;
data_size = le64_to_cpu(attr->nres.data_size);
if (le64_to_cpu(attr->nres.valid_size) > data_size)
- return NULL;
+ goto out;
alloc_size = le64_to_cpu(attr->nres.alloc_size);
if (data_size > alloc_size)
- return NULL;
+ goto out;
t32 = mi->sbi->cluster_mask;
if (alloc_size & t32)
- return NULL;
+ goto out;
if (!attr->nres.svcn && is_attr_ext(attr)) {
/* First segment of sparse/compressed attribute */
/* Can we use memory including attr->nres.total_size? */
if (asize < SIZEOF_NONRESIDENT_EX)
- return NULL;
+ goto out;
tot_size = le64_to_cpu(attr->nres.total_size);
if (tot_size & t32)
- return NULL;
+ goto out;
if (tot_size > alloc_size)
- return NULL;
+ goto out;
} else {
if (attr->nres.c_unit)
- return NULL;
+ goto out;
if (alloc_size > mi->sbi->volume.size)
- return NULL;
+ goto out;
}
return attr;
+
+out:
+ _ntfs_bad_inode(&ni->vfs_inode);
+ return NULL;
}
/*
* mi_find_attr - Find the attribute by type and name and id.
*/
-struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr,
- enum ATTR_TYPE type, const __le16 *name,
- size_t name_len, const __le16 *id)
+struct ATTRIB *mi_find_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ struct ATTRIB *attr, enum ATTR_TYPE type,
+ const __le16 *name, size_t name_len, const __le16 *id)
{
u32 type_in = le32_to_cpu(type);
u32 atype;
next_attr:
- attr = mi_enum_attr(mi, attr);
+ attr = mi_enum_attr(ni, mi, attr);
if (!attr)
return NULL;
@@ -460,9 +465,9 @@ int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
*
* Return: Not full constructed attribute or NULL if not possible to create.
*/
-struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
- const __le16 *name, u8 name_len, u32 asize,
- u16 name_off)
+struct ATTRIB *mi_insert_attr(struct ntfs_inode *ni, struct mft_inode *mi,
+ enum ATTR_TYPE type, const __le16 *name,
+ u8 name_len, u32 asize, u16 name_off)
{
size_t tail;
struct ATTRIB *attr;
@@ -482,7 +487,7 @@ struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
* at which we should insert it.
*/
attr = NULL;
- while ((attr = mi_enum_attr(mi, attr))) {
+ while ((attr = mi_enum_attr(ni, mi, attr))) {
diff = compare_attr(attr, type, name, name_len, upcase);
if (diff < 0)
@@ -500,7 +505,7 @@ struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
tail = used - PtrOffset(rec, attr);
}
- id = mi_new_attt_id(mi);
+ id = mi_new_attt_id(ni, mi);
memmove(Add2Ptr(attr, asize), attr, tail);
memset(attr, 0, asize);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0420/1887] fs/ntfs3: fix KMSAN uninit-value in ni_create_attr_list
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (418 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0419/1887] fs/ntfs3: Mark inode as bad as soon as error detected in mi_enum_attr() Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0421/1887] fs/ntfs3: fix slab-out-of-bounds write in ni_create_attr_list() Greg Kroah-Hartman
` (578 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+83c9dd5c0dcf6184fdbf,
Nirbhay Sharma, Konstantin Komarov, Nikita Nagornyi, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nirbhay Sharma <nirbhay.lkd@gmail.com>
[ Upstream commit 5f33da04e6ceee849e76e6592cc283c72fef7af9 ]
The call to kmalloc() to allocate the attribute list buffer is given a
size of al_aligned(rs). This size can be larger than the data
subsequently copied into the buffer, leaving trailing bytes uninitialized.
This can trigger a KMSAN "uninit-value" warning if that memory is
later accessed.
Fix this by using kzalloc() instead, which ensures the entire
allocated buffer is zero-initialized, preventing the warning.
Reported-by: syzbot+83c9dd5c0dcf6184fdbf@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=83c9dd5c0dcf6184fdbf
Signed-off-by: Nirbhay Sharma <nirbhay.lkd@gmail.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Backport to 6.1.y: only kmalloc -> kzalloc applied; 6.1.y lacks
14f527d44de6 ("fs/ntfs3: Correct checking while generating attr_list")
error-path rework. ]
Signed-off-by: Nikita Nagornyi <nagornyi@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/frecord.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 17559fca5984c..c9d0947651c4e 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -819,7 +819,7 @@ int ni_create_attr_list(struct ntfs_inode *ni)
* Skip estimating exact memory requirement.
* Looks like one record_size is always enough.
*/
- le = kmalloc(al_aligned(rs), GFP_NOFS);
+ le = kzalloc(al_aligned(rs), GFP_NOFS);
if (!le) {
err = -ENOMEM;
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0421/1887] fs/ntfs3: fix slab-out-of-bounds write in ni_create_attr_list()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (419 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0420/1887] fs/ntfs3: fix KMSAN uninit-value in ni_create_attr_list Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0422/1887] scsi: lpfc: Fix use-after-free of mboxq in lpfc_sli4_driver_resource_setup() Greg Kroah-Hartman
` (577 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches,
HE WEI(ギカク),
Konstantin Komarov, Nikita Nagornyi, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: HE WEI(ギカク) <skyexpoc@gmail.com>
[ Upstream commit 7c4841e2a62794a3bab7c1ff0540580f387e377f ]
ni_create_attr_list() allocates a fixed buffer of al_aligned(record_size)
(== record_size) bytes and then walks every attribute of the primary MFT
record, writing one ATTR_LIST_ENTRY per attribute and advancing the cursor
by le_size(name_len), with no check against the end of the buffer; the
total size is only computed after the loop.
A minimum-size resident attribute occupies SIZEOF_RESIDENT (0x18 = 24)
bytes on disk, but an unnamed attribute expands to le_size(0) (0x20 = 32)
bytes in the list. Because the number of attributes in a record is not
bounded (mi_enum_attr() accepts arbitrarily many equal-type, nameless
minimum-size attributes), a crafted record packed with such attributes
produces a list larger than record_size and overflows the heap buffer.
This is reachable from a crafted, loop-mounted NTFS image: opening the file
and adding an attribute (e.g. via setxattr) drives ntfs_set_ea() ->
ni_insert_resident() -> ni_insert_attr() -> ni_ins_attr_ext() ->
ni_create_attr_list().
BUG: KASAN: slab-out-of-bounds in ni_create_attr_list+0xc48/0x1058
Write of size 4 at addr ffff000008984c00 by task setfattr/345
ni_create_attr_list+0xc48/0x1058
ni_ins_attr_ext+0x510/0x7c0
ni_insert_attr+0x3f8/0x70c
ni_insert_resident+0xc8/0x3b0
ntfs_set_ea+0x66c/0xd28
ntfs_setxattr+0x4d8/0x5b0
__arm64_sys_setxattr+0xa4/0x124
Allocated by task 345:
ni_create_attr_list+0x188/0x1058
The buggy address belongs to the cache kmalloc-1k of size 1024
(the write lands at object+1024).
Size the buffer from the actual attributes instead of assuming a single
record_size is always enough.
Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Reported-by: HE WEI(ギカク) <skyexpoc@gmail.com>
Signed-off-by: HE WEI(ギカク) <skyexpoc@gmail.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Nikita Nagornyi <nagornyi@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/frecord.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index c9d0947651c4e..240983bac9c3c 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -816,10 +816,23 @@ int ni_create_attr_list(struct ntfs_inode *ni)
rs = sbi->record_size;
/*
- * Skip estimating exact memory requirement.
- * Looks like one record_size is always enough.
+ * Compute the exact size of the attribute list. Each attribute in the
+ * record yields one ATTR_LIST_ENTRY of le_size(name_len) bytes. The
+ * minimum on-disk attribute is SIZEOF_RESIDENT (0x18) bytes, but an
+ * unnamed one expands to le_size(0) (0x20) here, so a record crafted
+ * with many such attributes needs more than a single record_size; the
+ * previous fixed kzalloc(record_size) could therefore be overflowed by
+ * an attacker-controlled record.
*/
- le = kzalloc(al_aligned(rs), GFP_NOFS);
+ lsize = 0;
+ attr = NULL;
+ while ((attr = mi_enum_attr(ni, &ni->mi, attr)))
+ lsize += le_size(attr->name_len);
+
+ if (!lsize)
+ return -EINVAL;
+
+ le = kzalloc(al_aligned(lsize), GFP_NOFS);
if (!le) {
err = -ENOMEM;
goto out;
@@ -831,7 +844,6 @@ int ni_create_attr_list(struct ntfs_inode *ni)
attr = NULL;
nb = 0;
free_b = 0;
- attr = NULL;
for (; (attr = mi_enum_attr(ni, &ni->mi, attr)); le = Add2Ptr(le, sz)) {
sz = le_size(attr->name_len);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0422/1887] scsi: lpfc: Fix use-after-free of mboxq in lpfc_sli4_driver_resource_setup()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (420 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0421/1887] fs/ntfs3: fix slab-out-of-bounds write in ni_create_attr_list() Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:41 ` [PATCH 6.1 0423/1887] HID: core: introduce hid_safe_input_report() Greg Kroah-Hartman
` (576 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Andrey Misiurov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Misiurov <andrey.misyrov@gmail.com>
The 6.1.y backport of upstream commit 1bd28625e25b ("scsi: lpfc: Fix
memory leak in lpfc_sli4_driver_resource_setup()") added the new
mempool_free() of mboxq in the wrong place. Upstream frees mboxq after
the error handling of lpfc_get_sli4_parameters(). In 6.1.y the hunk
landed before that call, right after the NVMET WWN loop:
mempool_free(mboxq, phba->mbox_mem_pool);
lpfc_nvme_mod_param_dep(phba);
rc = lpfc_get_sli4_parameters(phba, mboxq);
mbox_mem_pool is created a few lines earlier in the same function, so
the pool is full and mempool_free() really kfree()s mboxq.
lpfc_get_sli4_parameters() then builds and issues a mailbox command in
freed memory. This happens on every SLI4 probe. Its error paths also
free mboxq a second time.
Move the mempool_free() to where upstream and the other stable trees
have it.
Fixes: 299f5baa1321 ("scsi: lpfc: Fix memory leak in lpfc_sli4_driver_resource_setup()")
Signed-off-by: Andrey Misiurov <andrey.misyrov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/lpfc/lpfc_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 13ebbe4a71c47..fc5a640b7f742 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8175,7 +8175,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
}
}
}
- mempool_free(mboxq, phba->mbox_mem_pool);
lpfc_nvme_mod_param_dep(phba);
@@ -8209,6 +8208,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
goto out_free_bsmbx;
}
}
+ mempool_free(mboxq, phba->mbox_mem_pool);
/*
* 1 for cmd, 1 for rsp, NVME adds an extra one
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0423/1887] HID: core: introduce hid_safe_input_report()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (421 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0422/1887] scsi: lpfc: Fix use-after-free of mboxq in lpfc_sli4_driver_resource_setup() Greg Kroah-Hartman
@ 2026-10-28 16:41 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0424/1887] HID: uhid: convert to hid_safe_input_report() Greg Kroah-Hartman
` (575 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:41 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Tissoires, Jiri Kosina,
Sasha Levin, Lee Jones
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <bentiss@kernel.org>
[ Upstream commit 206342541fc887ae919774a43942dc883161fece ]
hid_input_report() is used in too many places to have a commit that
doesn't cross subsystem borders. Instead of changing the API, introduce
a new one when things matters in the transport layers:
- usbhid
- i2chid
This effectively revert to the old behavior for those two transport
layers.
Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit a9527c32cc9d98252dc975d6fcb29f2013d0f63a)
[Lee: Implement hid_safe_input_report() directly and wrap it from
hid_input_report() as 67eccf151d76 ("HID: add source argument to
HID low level functions") is not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-core.c | 26 ++++++++++++++++++++++++--
drivers/hid/i2c-hid/i2c-hid-core.c | 7 ++++---
drivers/hid/usbhid/hid-core.c | 11 ++++++-----
include/linux/hid.h | 2 ++
4 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 61dde8e3fbb25..3b1952e66ca42 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2085,14 +2085,36 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
* @interrupt: distinguish between interrupt and control transfers
*
* This is data entry for lower layers.
+ * Legacy, please use hid_safe_input_report() instead.
*/
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data,
u32 size, int interrupt)
+{
+ return hid_safe_input_report(hid, type, data, size, size, interrupt);
+}
+EXPORT_SYMBOL_GPL(hid_input_report);
+
+/**
+ * hid_safe_input_report - report data from lower layer (usb, bt...)
+ *
+ * @hid: hid device
+ * @type: HID report type (HID_*_REPORT)
+ * @data: report contents
+ * @bufsize: allocated size of the data buffer
+ * @size: useful size of data parameter
+ * @interrupt: distinguish between interrupt and control transfers
+ *
+ * This is data entry for lower layers.
+ * Please use this function instead of the non safe version because we provide
+ * here the size of the buffer, allowing hid-core to make smarter decisions
+ * regarding the incoming buffer.
+ */
+int hid_safe_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data,
+ size_t bufsize, u32 size, int interrupt)
{
struct hid_report_enum *report_enum;
struct hid_driver *hdrv;
struct hid_report *report;
- size_t bufsize = size;
int ret = 0;
if (!hid)
@@ -2137,7 +2159,7 @@ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data
up(&hid->driver_input_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(hid_input_report);
+EXPORT_SYMBOL_GPL(hid_safe_input_report);
bool hid_match_one_id(const struct hid_device *hdev,
const struct hid_device_id *id)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 9559c96d44b4d..d301dc5acd31e 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -539,9 +539,10 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
if (ihid->hid->group != HID_GROUP_RMI)
pm_wakeup_event(&ihid->client->dev, 0);
- hid_input_report(ihid->hid, HID_INPUT_REPORT,
- ihid->inbuf + sizeof(__le16),
- ret_size - sizeof(__le16), 1);
+ hid_safe_input_report(ihid->hid, HID_INPUT_REPORT,
+ ihid->inbuf + sizeof(__le16),
+ ihid->bufsize - sizeof(__le16),
+ ret_size - sizeof(__le16), 1);
}
return;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ccf0aad99a4b9..3bfca6c3b5286 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -281,9 +281,9 @@ static void hid_irq_in(struct urb *urb)
break;
usbhid_mark_busy(usbhid);
if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
- hid_input_report(urb->context, HID_INPUT_REPORT,
- urb->transfer_buffer,
- urb->actual_length, 1);
+ hid_safe_input_report(urb->context, HID_INPUT_REPORT,
+ urb->transfer_buffer, urb->transfer_buffer_length,
+ urb->actual_length, 1);
/*
* autosuspend refused while keys are pressed
* because most keyboards don't wake up when
@@ -480,9 +480,10 @@ static void hid_ctrl(struct urb *urb)
switch (status) {
case 0: /* success */
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
- hid_input_report(urb->context,
+ hid_safe_input_report(urb->context,
usbhid->ctrl[usbhid->ctrltail].report->type,
- urb->transfer_buffer, urb->actual_length, 0);
+ urb->transfer_buffer, urb->transfer_buffer_length,
+ urb->actual_length, 0);
break;
case -ESHUTDOWN: /* unplug */
unplug = 1;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 9fde4e8839c91..803bbaccec6ab 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -960,6 +960,8 @@ extern void hidinput_disconnect(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32);
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
int interrupt);
+int hid_safe_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data,
+ size_t bufsize, u32 size, int interrupt);
struct hid_field *hidinput_get_led_field(struct hid_device *hid);
unsigned int hidinput_count_leds(struct hid_device *hid);
__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0424/1887] HID: uhid: convert to hid_safe_input_report()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (422 preceding siblings ...)
2026-10-28 16:41 ` [PATCH 6.1 0423/1887] HID: core: introduce hid_safe_input_report() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0425/1887] mm/damon/core: do non-safe region walk on kdamond_apply_schemes() Greg Kroah-Hartman
` (574 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carlos Llamas, Lee Jones,
Jiri Kosina, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Llamas <cmllamas@google.com>
[ Upstream commit 63a694c51bf120a37550890b8e7736b4888985e9 ]
Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
bogus memset()"), added a check in hid_report_raw_event() to reject
reports if the received data size is smaller than expected. This was
intended to prevent OOB errors by no longer allowing zeroing-out of
shorter reports due to the lack of buffer size information.
However, this leads to regressions in hid_report_raw_event(), where
shorter than expected reports are rejected, even though their buffers
are sufficiently large to be zero-padded.
To solve this issue, Benjamin introduced a safer alternative in commit
206342541fc8 ("HID: core: introduce hid_safe_input_report()"), which
forwards the buffer size and allows hid_report_raw_event() to safely
zero-pad the data.
Convert uhid to use hid_safe_input_report() and pass UHID_DATA_MAX as
the buffer size. This prevents the reported regressions [1], allowing
hid core to zero-pad the shorter reports safely as expected.
Cc: stable@vger.kernel.org
Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/ [1]
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Reviewed-by: Lee Jones <lee@kernel.org>
Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/uhid.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 59ac757c1d471..72baf8adf46cf 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -597,8 +597,8 @@ static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
if (!READ_ONCE(uhid->running))
return -EINVAL;
- hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data,
- min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
+ hid_safe_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, UHID_DATA_MAX,
+ min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
return 0;
}
@@ -608,8 +608,8 @@ static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev)
if (!READ_ONCE(uhid->running))
return -EINVAL;
- hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data,
- min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0);
+ hid_safe_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data, UHID_DATA_MAX,
+ min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0425/1887] mm/damon/core: do non-safe region walk on kdamond_apply_schemes()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (423 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0424/1887] HID: uhid: convert to hid_safe_input_report() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0426/1887] mm/damon/core: fix unconditionally skip last region Greg Kroah-Hartman
` (573 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SeongJae Park, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <sj@kernel.org>
[ Upstream commit 1745ccbd2907db2bdaa843e4abccde4fdaccbe5d ]
kdamond_apply_schemes() is using damon_for_each_region_safe(), which is
safe for deallocation of the region inside the loop. However, the loop
internal logic does not deallocate regions. Hence it is only wasting the
next pointer. Also, it causes a problem.
When an address filter is applied, and there is a region that intersects
with the filter, the filter splits the region on the filter boundary. The
intention is to let DAMOS apply action to only filtered-in address ranges.
However, it is using damon_for_each_region_safe(), which sets the next
region before the execution of the iteration. Hence, the region that
split and now will be next to the previous region, is simply ignored. As
a result, DAMOS applies the action to target regions bit slower than
expected, when the address filter is used. Shouldn't be a big problem but
definitely better to be fixed. damos_skip_charged_region() was working
around the issue using a double pointer hack.
Use damon_for_each_region(), which is safe for this use case. And drop
the work around in damos_skip_charged_region().
Link: https://lkml.kernel.org/r/20260227170623.95384-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 568f24da26e6e..6d7a5f18158a0 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -788,8 +788,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
sz = DAMON_MIN_REGION;
}
damon_split_region_at(t, r, sz);
- r = damon_next_region(r);
- sz = damon_sz_region(r);
+ continue;
}
quota->charge_target_from = NULL;
quota->charge_addr_from = 0;
@@ -858,7 +857,7 @@ static void damos_set_effective_quota(struct damos_quota *quota)
static void kdamond_apply_schemes(struct damon_ctx *c)
{
struct damon_target *t;
- struct damon_region *r, *next_r;
+ struct damon_region *r;
struct damos *s;
damon_for_each_scheme(s, c) {
@@ -912,7 +911,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
}
damon_for_each_target(t, c) {
- damon_for_each_region_safe(r, next_r, t)
+ damon_for_each_region(r, t)
damon_do_apply_schemes(c, t, r);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0426/1887] mm/damon/core: fix unconditionally skip last region
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (424 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0425/1887] mm/damon/core: do non-safe region walk on kdamond_apply_schemes() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0427/1887] Bluetooth: hci_event: fix simultaneous discovery stuck in FINDING Greg Kroah-Hartman
` (572 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liew Rui Yan, SJ Park, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liew Rui Yan <aethernet65535@gmail.com>
[ Upstream commit b3723b596b548c837a766aae3553c14a7b15af2b ]
Once quota set, the charge_{target,addr}_from unconditionally skips and
resets at the last region of the tracked target, so the last region can be
skipped even when it has not been processed.
Example:
1. Target has 2 regions: R1 (0-100 bytes) and R2 (100-200 bytes).
2. Quota is configured to process only 100 bytes per window.
3. Window 1: Processes R1 (0-100). Quota is full. charge_{target,
addr}_from is saved at (Target, 100).
4. Window 2: The loop reaches R2. Because R2 is
damon_last_region(t), the old code unconditionally returns true,
skipping R2 entirely and resetting the charge_{target,addr}_from.
Result: R2 is permanently skipped even though it has never been
processed.
However, it is important to note that this is a very minor issue. This is
because it is triggered only when the previous window saved/kept
charge_{target,addr}_from, and in the next window, all regions except the
last region were skipped by damos_skip_charged_region().
Fix this by only resetting the charge_{target,addr}_from when last region
is reached, only skipping when it is applied or cannot split.
Link: https://lore.kernel.org/20260908134739.96919-1-sj@kernel.org
Fixes: 50585192bc2e ("mm/damon/schemes: skip already charged targets and regions")
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Reviewed-by: SJ Park <sj@kernel.org>
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: <stable@vger.kernel.org> # v5.16.x
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 6d7a5f18158a0..f0da5cb2b88a0 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -756,6 +756,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
unsigned long sz = damon_sz_region(r);
struct timespec64 begin, end;
unsigned long sz_applied = 0;
+ bool skip = false;
if (!s->wmarks.activated)
continue;
@@ -768,14 +769,11 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
if (quota->charge_target_from) {
if (t != quota->charge_target_from)
continue;
- if (r == damon_last_region(t)) {
- quota->charge_target_from = NULL;
- quota->charge_addr_from = 0;
- continue;
- }
if (quota->charge_addr_from &&
- r->ar.end <= quota->charge_addr_from)
- continue;
+ r->ar.end <= quota->charge_addr_from) {
+ skip = true;
+ goto clean_charge_from_skip;
+ }
if (quota->charge_addr_from && r->ar.start <
quota->charge_addr_from) {
@@ -783,16 +781,23 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
r->ar.start, DAMON_MIN_REGION);
if (!sz) {
if (damon_sz_region(r) <=
- DAMON_MIN_REGION)
- continue;
+ DAMON_MIN_REGION) {
+ skip = true;
+ goto clean_charge_from_skip;
+ }
sz = DAMON_MIN_REGION;
}
damon_split_region_at(t, r, sz);
- continue;
+ skip = true;
}
+ }
+clean_charge_from_skip:
+ if (r == damon_last_region(t)) {
quota->charge_target_from = NULL;
quota->charge_addr_from = 0;
}
+ if (skip)
+ continue;
if (!damos_valid_target(c, t, r, s))
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0427/1887] Bluetooth: hci_event: fix simultaneous discovery stuck in FINDING
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (425 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0426/1887] mm/damon/core: fix unconditionally skip last region Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0428/1887] netfilter: nft_set_pipapo: restore cloned mapping table memcg accounting Greg Kroah-Hartman
` (571 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiajia Liu, Luiz Augusto von Dentz,
Iaroslav Voitovych, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiajia Liu <liujiajia@kylinos.cn>
[ Upstream commit 96d006ae6445679436b945593950fd465eba7e76 ]
When hci_inquiry_complete_evt is called between le_scan_disable and
le_set_scan_enable_complete and no remote name needs to be resolved,
the interleaved discovery with SIMULTANEOUS quirk gets stuck in
DISCOVERY_FINDING. le_set_scan_enable_complete does not check inquiry
state. No one sets DISCOVERY_STOPPED in this process.
Add state check in le_set_scan_enable_complete and change state if
the state is DISCOVERY_FINDING. Tested with AX201 (8087:0026) in Dell
Vostro 13. Discovering disabled MGMT Event below is reported when
running into the above condition.
@ MGMT Command: Start Discovery (0x0023) {0x0001} [hci0] 10885.970873
Address type: 0x07
BR/EDR
LE Public
LE Random
...
< HCI Command: LE Set Extended Scan Enable #38205 [hci0] 10886.131438
Extended scan: Enabled (0x01)
Filter duplicates: Enabled (0x01)
Duration: 0 msec (0x0000)
Period: 0.00 sec (0x0000)
> HCI Event: Command Complete (0x0e) plen 4 #38206 [hci0] 10886.133295
LE Set Extended Scan Enable (0x08|0x0042) ncmd 2
Status: Success (0x00)
@ MGMT Event: Discovering (0x0013) plen 2 {0x0001} [hci0] 10886.133414
Address type: 0x07
BR/EDR
LE Public
LE Random
Discovery: Enabled (0x01)
< HCI Command: Inquiry (0x01|0x0001) plen 5 #38207 [hci0] 10886.133528
Access code: 0x9e8b33 (General Inquiry)
Length: 10.24s (0x08)
Num responses: 0
> HCI Event: Command Status (0x0f) plen 4 #38208 [hci0] 10886.141333
Inquiry (0x01|0x0001) ncmd 2
Status: Success (0x00)
...
< HCI Command: LE Set Extended Scan Enable #38242 [hci0] 10896.381802
Extended scan: Disabled (0x00)
Filter duplicates: Disabled (0x00)
Duration: 0 msec (0x0000)
Period: 0.00 sec (0x0000)
> HCI Event: Inquiry Complete (0x01) plen 1 #38243 [hci0] 10896.383419
Status: Success (0x00)
> HCI Event: Command Complete (0x0e) plen 4 #38244 [hci0] 10896.394378
LE Set Extended Scan Enable (0x08|0x0042) ncmd 2
Status: Success (0x00)
@ MGMT Event: Device Found (0x0012) plen 22 {0x0001} [hci0] 10896.394497
LE Address: 88:12:AC:92:43:69
RSSI: -101 dBm (0x9b)
Flags: 0x00000004
Not Connectable
Data length: 8
Company: Xiaomi Inc. (911)
Data[0]:
16-bit Service UUIDs (complete): 1 entry
Xiaomi Inc. (0xfdaa)
@ MGMT Event: Discovering (0x0013) plen 2 {0x0001} [hci0] 10896.394506
Address type: 0x07
BR/EDR
LE Public
LE Random
Discovery: Disabled (0x00)
Fixes: 8ffde2a73f2c ("Bluetooth: Convert le_scan_disable timeout to hci_sync")
Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Iaroslav: test the quirk with test_bit() on hdev->quirks, as
this branch does elsewhere; hci_test_quirk() does not exist here ]
Signed-off-by: Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_event.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index aa879b0b64cf5..c6cf8b348314e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1748,6 +1748,13 @@ static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
hci_dev_clear_flag(hdev, HCI_LE_SCAN);
+ if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
+ test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks) &&
+ !test_bit(HCI_INQUIRY, &hdev->flags) &&
+ hdev->discovery.state == DISCOVERY_FINDING) {
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ }
+
/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
* interrupted scanning due to a connect request. Mark
* therefore discovery as stopped.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0428/1887] netfilter: nft_set_pipapo: restore cloned mapping table memcg accounting
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (426 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0427/1887] Bluetooth: hci_event: fix simultaneous discovery stuck in FINDING Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0429/1887] crypto: drbg - Fix ineffective sanity check Greg Kroah-Hartman
` (570 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
The 6.1.y backport of commit 69e687cea79f
("netfilter: nf_tables: missing objects with no memcg accounting")
changed the pipapo_clone() mapping-table allocation to
GFP_KERNEL_ACCOUNT.
The later stable backport of commit 07ace0bbe03b ("netfilter:
nft_set_pipapo: do not rely on ZERO_SIZE_PTR") rewrote this allocation
and changed the flag back to GFP_KERNEL. Upstream applied the
ZERO_SIZE_PTR change before the memcg accounting change and retains
GFP_KERNEL_ACCOUNT after both.
nft_pipapo_deactivate() clones a populated set before looking up an
element to delete. If the element is absent, priv->dirty remains false
and the clone is retained. Its mapping tables therefore remain allocated
without being charged to the requesting memory cgroup.
Restore GFP_KERNEL_ACCOUNT for the cloned mapping table.
Fixes: a4983e89e3b1 ("netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_set_pipapo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index c27ba1c5ae5da..2e98592a04288 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -1466,7 +1466,7 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old)
goto out_mt;
dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt),
- GFP_KERNEL);
+ GFP_KERNEL_ACCOUNT);
if (!dst->mt)
goto out_mt;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0429/1887] crypto: drbg - Fix ineffective sanity check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (427 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0428/1887] netfilter: nft_set_pipapo: restore cloned mapping table memcg accounting Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0430/1887] ipv4: stop PMTU walk when nexthop group shrinks Greg Kroah-Hartman
` (569 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Eric Biggers, Herbert Xu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 040ad83b0e8aa065fd2fc641cacba8491a8b186d upstream.
Fix drbg_healthcheck_sanity() to correctly check the return value of
drbg_generate(). drbg_generate() returns 0 on success, or a negative
errno value on failure. drbg_healthcheck_sanity() incorrectly assumed
that it returned a positive value on success.
This didn't make the sanity check fail, but it made it ineffective.
Fixes: cde001e4c3c3 ("crypto: rng - RNGs must return 0 in success case")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
crypto/drbg.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 211757f3f9723..8d6dff6f8c9d1 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -2001,7 +2001,6 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm,
*/
static inline int __init drbg_healthcheck_sanity(void)
{
- int len = 0;
#define OUTBUFLEN 16
unsigned char buf[OUTBUFLEN];
struct drbg_state *drbg = NULL;
@@ -2043,12 +2042,12 @@ static inline int __init drbg_healthcheck_sanity(void)
max_addtllen = drbg_max_addtl(drbg);
max_request_bytes = drbg_max_request_bytes(drbg);
drbg_string_fill(&addtl, buf, max_addtllen + 1);
- /* overflow addtllen with additonal info string */
- len = drbg_generate(drbg, buf, OUTBUFLEN, &addtl);
- BUG_ON(0 < len);
+ /* overflow addtllen with additional info string */
+ ret = drbg_generate(drbg, buf, OUTBUFLEN, &addtl);
+ BUG_ON(ret == 0);
/* overflow max_bits */
- len = drbg_generate(drbg, buf, (max_request_bytes + 1), NULL);
- BUG_ON(0 < len);
+ ret = drbg_generate(drbg, buf, max_request_bytes + 1, NULL);
+ BUG_ON(ret == 0);
/* overflow max addtllen with personalization string */
ret = drbg_seed(drbg, &addtl, false);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0430/1887] ipv4: stop PMTU walk when nexthop group shrinks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (428 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0429/1887] crypto: drbg - Fix ineffective sanity check Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0431/1887] ipv4: stop route notification sizing " Greg Kroah-Hartman
` (568 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Ido Schimmel,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 6619e01855e65ef35723685a557e3eb106f4ecf5 upstream.
Commit 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if
multipath enabled") made __ip_rt_update_pmtu() update every path.
For nexthop objects, fib_info_num_path() and fib_info_nhc()
independently load nh->nh_grp. RCU protects each group's lifetime but
does not make the loads observe the same group. If replacement shrinks
the group after the loop accepts an index, fib_info_nhc() returns NULL
and update_or_create_fnhe() dereferences it.
A deterministic probe only widened the existing window between the real
operations. On v7.2, an RTM_NEWNEXTHOP replacement published a
one-member group after the PMTU reader accepted index 1 from a two-member
group, producing:
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: update_or_create_fnhe+0x45/0x15b0
Stop when the indexed path is absent. Groups are dense, so no later
index exists in that snapshot. The same real-writer window completed
114,423 PMTU iterations without an oops with this check. A reproducer
is available on request.
Replacement requires CAP_NET_ADMIN in the network namespace. Where
unprivileged user namespaces are permitted, a local user can obtain it
in a new user and network namespace.
Fixes: 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if multipath enabled")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/4fb87ed994dfc067178fc845cdd8bc9b5446b039.1790915964.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/route.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1089,6 +1089,8 @@ static void __ip_rt_update_pmtu(struct r
for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) {
nhc = fib_info_nhc(res.fi, nhsel);
+ if (!nhc)
+ break;
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
jiffies + net->ipv4.ip_rt_mtu_expires);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0431/1887] ipv4: stop route notification sizing when nexthop group shrinks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (429 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0430/1887] ipv4: stop PMTU walk when nexthop group shrinks Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0432/1887] ipv4: do not warn on route notification size race Greg Kroah-Hartman
` (567 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Ido Schimmel,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit d3daa33c7af92e38f2274bbd2576f58bfbaf89e6 upstream.
Commit 680aea08e78c ("net: ipv4: Emit notification when fib
hardware flags are changed") added an RCU-only fib_nlmsg_size() call
for asynchronous hardware flag notifications.
fib_nlmsg_size() checks fib_info_num_path() before each iteration,
then fib_info_nhc() independently reloads nh->nh_grp. If
RTM_NEWNEXTHOP replaces a group with fewer paths between those loads,
fib_info_nhc() returns NULL and fib_nexthop_nlmsg_size() dereferences
it.
Stop sizing when the indexed path is absent. Nexthop groups are
dense, so the current snapshot has no later path.
Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/1054fa46165bba1b473782fa41367804aa908e86.1790915964.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_semantics.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -514,6 +514,9 @@ size_t fib_nlmsg_size(struct fib_info *f
struct fib_nh_common *nhc = fib_info_nhc(fi, i);
size_t nhsize;
+ if (!nhc)
+ break;
+
nhsize = fib_nexthop_nlmsg_size(nhc, nhs != 1);
if (nhs != 1)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0432/1887] ipv4: do not warn on route notification size race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (430 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0431/1887] ipv4: stop route notification sizing " Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0433/1887] ipv6: " Greg Kroah-Hartman
` (566 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit e02a5b6588161673ef75a4bc5cdfb62bd493374d upstream.
Commit 680aea08e78c ("net: ipv4: Emit notification when fib hardware
flags are changed") added asynchronous route notifications for hardware
flag changes.
fib_alias_hw_flags_set() sizes the skb with fib_nlmsg_size() and later
fills it with fib_dump_info() while holding only RCU. With nexthop
compatibility mode enabled, a concurrent replacement can grow the group
between these independent snapshots. fib_dump_info() can then
legitimately return -EMSGSIZE, so the warning does not prove a sizing bug.
Remove the warning. The existing error path still frees the skb and
reports the error to listeners.
Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261004082043.GB92032@shredder/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/b7e203fc5867651cb67ef84aa03e082f0f76008e.1791423190.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_trie.c | 2 --
1 file changed, 2 deletions(-)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1084,8 +1084,6 @@ void fib_alias_hw_flags_set(struct net *
err = fib_dump_info(skb, 0, 0, RTM_NEWROUTE, fri, 0);
if (err < 0) {
- /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
- WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0433/1887] ipv6: do not warn on route notification size race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (431 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0432/1887] ipv4: do not warn on route notification size race Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0434/1887] arm64: irq: exclude the softirq stack switch from KCOV Greg Kroah-Hartman
` (565 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit c97426ec649d99596d8969e1a052c16b14b7b485 upstream.
fib6_info_hw_flags_set() sizes the skb with rt6_nlmsg_size() and later
fills it with rt6_fill_node(). With nexthop compatibility mode enabled,
a concurrent replacement can grow the group between these independent
snapshots. rt6_fill_node() can then legitimately return -EMSGSIZE, so
the warning does not prove a sizing bug.
Remove the warning. The existing error path still frees the skb and
reports the error to listeners.
Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed")
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261007114003.GA1011260@shredder/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/4012604727e5ba80b69ccd4d08796511397ddaef.1791423190.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/route.c | 2 --
1 file changed, 2 deletions(-)
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -6333,8 +6333,6 @@ void fib6_info_hw_flags_set(struct net *
err = rt6_fill_node(net, skb, f6i, NULL, NULL, NULL, 0, RTM_NEWROUTE, 0,
0, 0);
if (err < 0) {
- /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
- WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0434/1887] arm64: irq: exclude the softirq stack switch from KCOV
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (432 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0433/1887] ipv6: " Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0435/1887] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P) Greg Kroah-Hartman
` (564 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Will Deacon
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit a9cd14bfb0c113f1cd77be4349784663bec71bb4 upstream.
On IRQ exit, __irq_exit_rcu() drops HARDIRQ_OFFSET before calling
invoke_softirq(). The arm64 do_softirq_own_stack() wrapper and its
____do_softirq() trampoline run before __do_softirq() establishes
softirq context, so KCOV records their PCs in the interrupted task's
coverage buffer. They also run outside softirq accounting when
local_bh_enable() reaches do_softirq().
The IRQ-exit coverage makes the KCOV boot selftest fail even after
the scheduler and timer coverage leaks are suppressed. The generic
softirq.o is already excluded from KCOV, but that exclusion does not
cover the separately compiled arm64 wrappers.
Exclude irq.o from KCOV instrumentation, as is already done for the
arm64 entry code. This covers both wrappers even with compilers that
lack the no_sanitize_coverage attribute. The softirq action functions
remain instrumented for explicit remote coverage.
Fixes: 8eb858c44b98 ("arm64: run softirqs on the per-CPU IRQ stack")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/kernel/Makefile | 3 +++
1 file changed, 3 insertions(+)
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,6 +25,9 @@ KASAN_SANITIZE_stacktrace.o := n
KCOV_INSTRUMENT_entry-common.o := n
KCOV_INSTRUMENT_idle.o := n
+# Softirq stack switching can run outside interrupt context.
+KCOV_INSTRUMENT_irq.o := n
+
# Object file lists.
obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
entry-common.o entry-fpsimd.o process.o ptrace.o \
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0435/1887] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P)
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (433 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0434/1887] arm64: irq: exclude the softirq stack switch from KCOV Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0436/1887] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode() Greg Kroah-Hartman
` (563 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Michael Garland, Mark Brown
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Garland <minimelkav@gmail.com>
commit d0cb7a7b2a490c381ad97f53155d02a748b60dea upstream.
The Acer Aspire Go 15 (AG15-21P, board MDC Herbag2_MDU) has two PDM
DMICs connected to the ACP. The BIOS does not set the AcpDmicConnected
_DSD property, so the acp6x machine driver never registers the DMIC
card. The existing Herbag_MDU entry does not match this board name, so
add a DMI quirk for it.
Tested on BIOS V1.11: the acp6x DMIC capture device is registered and
records audio on both channels.
Cc: stable@vger.kernel.org
Signed-off-by: Michael Garland <minimelkav@gmail.com>
Link: https://patch.msgid.link/20261005-acp6x-herbag2-quirk-v1-1-a1f2683d758f@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -608,6 +608,13 @@ static const struct dmi_system_id yc_acp
{
.driver_data = &acp6x_card,
.matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "MDC"),
+ DMI_MATCH(DMI_BOARD_NAME, "Herbag2_MDU"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Thin A15 B7VE"),
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0436/1887] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (434 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0435/1887] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P) Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0437/1887] dm ioctl: dont let data_start run past the buffer Greg Kroah-Hartman
` (562 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Wentao Liang,
David Sterba
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 1fd742c7479961da6d0bb794ef8ac6b7b9442847 upstream.
When paths_from_inode() fails, scrub_print_warning_inode() jumps to err
without dropping the reference taken by btrfs_get_fs_root(), leaking a
reference to the root every time path resolution fails while printing
scrub warnings. Every other error and success path of the function
drops the reference.
Drop the reference on the paths_from_inode() failure path too.
Fixes: 558540c17771 ("btrfs scrub: print paths of corrupted files")
CC: stable@vger.kernel.org
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/scrub.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -851,8 +851,10 @@ static int scrub_print_warning_inode(u64
}
ret = paths_from_inode(inum, ipath);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_put_root(local_root);
goto err;
+ }
/*
* we deliberately ignore the bit ipath might have been too small to
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0437/1887] dm ioctl: dont let data_start run past the buffer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (435 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0436/1887] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0438/1887] wifi: brcmfmac: fix P2P device removal race in brcmf_detach() Greg Kroah-Hartman
` (561 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+48d935cf48a4a76be346,
Palla Raghunath, Mikulas Patocka
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Palla Raghunath <raghunathpalla.0209@gmail.com>
commit 9b3fcf519d370df94a56f3b272d9eddffffa5be8 upstream.
struct dm_ioctl has seven bytes of trailing padding, so the smallest
buffer userspace is allowed to ask for, offsetof(struct dm_ioctl, data),
is seven bytes shorter than sizeof(struct dm_ioctl).
get_result_buffer() sets data_start to sizeof(struct dm_ioctl) without
looking at how big the buffer actually is. Ask for the minimum and
data_start ends up seven bytes past the end. Callers add it to
data_size, and ctl_ioctl() copies that much back to userspace:
BUG: KASAN: slab-out-of-bounds in _copy_to_user+0xad/0xd0
Read of size 312 at addr ffff8880169e4c00 by task repro-dm/140
ctl_ioctl+0x5e3/0xcb0
dm_ctl_ioctl+0x25/0x40
allocated 305-byte region [ffff8880169e4c00, ffff8880169e4d31)
A DM_LIST_DEVICES with data_size set to 305 is enough to hit it, and the
seven bytes that leak are whatever sat next to the allocation.
Clamp data_start to the buffer size.
Note that this is not a security bug because the out-of-bounds read can
only be triggered by root.
Reported-by: syzbot+48d935cf48a4a76be346@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=48d935cf48a4a76be346
Fixes: 76c072b48e39 ("dm ioctl: move compat code")
Cc: stable@vger.kernel.org
Signed-off-by: Palla Raghunath <raghunathpalla.0209@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-ioctl.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -545,10 +545,16 @@ static void *get_result_buffer(struct dm
{
param->data_start = align_ptr(param + 1) - (void *) param;
- if (param->data_start < param_size)
+ if (param->data_start < param_size) {
*len = param_size - param->data_start;
- else
+ } else {
+ /*
+ * The buffer can be as small as offsetof(*param, data), which
+ * is less than sizeof(*param), so don't run off the end of it.
+ */
*len = 0;
+ param->data_start = param_size;
+ }
return ((void *) param) + param->data_start;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0438/1887] wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (436 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0437/1887] dm ioctl: dont let data_start run past the buffer Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0439/1887] wireguard: noise: reject response consumption after intermediate initiation Greg Kroah-Hartman
` (560 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michele Dionisio, Arend van Spriel,
Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michele Dionisio <michele.dionisio@gmail.com>
commit 08a3f02fea636e97a7422d1512f76dacdb5b0887 upstream.
When the driver is removed while the user space process that created
the P2P device (e.g. wpa_supplicant) is still exiting, the P2P device
interface is removed twice and the kernel crashes.
The two paths are:
- wpa_supplicant, on exit, sends NL80211_CMD_DEL_INTERFACE for the P2P
device. nl80211_del_interface() holds RTNL and the wiphy mutex and
calls brcmf_p2p_del_vif(), which disables discovery and waits up to
1.5 s for BRCMF_E_IF_DEL. Then it calls brcmf_remove_interface(),
which unregisters the wdev and frees the vif and the ifp.
- brcmf_detach() sets the bus down, so BRCMF_E_IF_DEL never arrives,
and calls brcmf_remove_interface(ifp, false) for the same ifp.
brcmf_p2p_ifp_removed() reads ifp->vif and then blocks on
rtnl_lock(). When brcmf_p2p_del_vif() releases RTNL, it calls
cfg80211_unregister_wdev() on the wdev that was already unregistered
and freed.
The second list_del_rcu() of wdev->list faults on LIST_POISON2:
brcmfmac: brcmf_p2p_del_vif delete P2P vif
brcmfmac: brcmf_p2p_deinit_discovery enter
brcmfmac: brcmf_p2p_del_vif P2P: GO_NEG_PHASE status cleared
brcmfmac: brcmf_detach Enter
brcmfmac: brcmf_bus_change_state 1 -> 0
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
[1.5 s later, brcmf_p2p_del_vif() timed out]
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
Unable to handle kernel paging request at virtual address dead000000000122
Internal error: Oops: 96000044 [#1] PREEMPT_RT SMP
pc : _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
Call trace:
_cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
cfg80211_unregister_wdev+0x10/0x1c [cfg80211]
brcmf_p2p_ifp_removed+0x84/0xb0 [brcmfmac]
brcmf_remove_interface+0x1f4/0x254 [brcmfmac]
brcmf_detach+0x88/0x180 [brcmfmac]
brcmf_sdio_remove+0x90/0x7b0 [brcmfmac]
brcmf_sdiod_remove+0x20/0xa0 [brcmfmac]
brcmf_ops_sdio_remove+0xbc/0x12c [brcmfmac]
sdio_bus_remove+0x38/0x144
device_release_driver_internal+0x1e8/0x2c0
device_release_driver+0x14/0x20
brcmf_sdio_bus_remove+0x2c/0x40 [brcmfmac]
brcmf_fwvid_unregister_vendor+0xd8/0x170 [brcmfmac]
__exit_compat+0x18/0x418 [brcmfmac_cyw]
__arm64_sys_delete_module+0x1ac/0x244
The log was taken with debug=0x406 on an i.MX 8M Plus board with a
CYW55513 (Sona IF513) on SDIO. The driver is the Ezurio backport of
brcmfmac from v6.18.22 on a 5.4-rt kernel. The code involved is the same
in mainline.
To reproduce:
1. Start wpa_supplicant on wlan0 and let it associate. It creates the
P2P device (iw dev shows "type P2P-device").
2. Stop wpa_supplicant and remove the driver without waiting for
wpa_supplicant to exit:
kill $(pidof wpa_supplicant)
rmmod brcmfmac_cyw brcmfmac
The crash is reproducible on that board.
For the interface without a netdev (the P2P device), take RTNL and the
wiphy mutex in brcmf_detach() before reading iflist, and remove it with
locked=true. If brcmf_p2p_del_vif() runs first, brcmf_detach() finds the
slot empty. If brcmf_detach() runs first, nl80211 does not find the wdev
any more. The interfaces with a netdev are removed as before, because
brcmf_del_if() takes RTNL on its own for the primary interface.
Fixes: 9831bcb987df ("brcmfmac: Deleting of p2p device is leaking memory.")
Cc: stable@vger.kernel.org
Assisted-by: claude-opus-5-5
Signed-off-by: Michele Dionisio <michele.dionisio@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260924123027.4122909-2-michele.dionisio@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 27 ++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1471,8 +1471,31 @@ void brcmf_detach(struct device *dev)
brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
/* make sure primary interface removed last */
for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {
- if (drvr->iflist[i])
- brcmf_remove_interface(drvr->iflist[i], false);
+ struct brcmf_if *ifp = drvr->iflist[i];
+
+ if (!ifp)
+ continue;
+
+ if (ifp->ndev) {
+ brcmf_remove_interface(ifp, false);
+ continue;
+ }
+
+ /* The P2P device interface has no netdev. Its removal can
+ * race with NL80211_CMD_DEL_INTERFACE issued by a user space
+ * process that is exiting (e.g. wpa_supplicant), which ends
+ * in brcmf_p2p_del_vif() under RTNL and the wiphy mutex. If
+ * both paths remove the interface, the wdev is unregistered
+ * twice and the vif is used after being freed. Take the same
+ * locks and re-read iflist, so only one path removes it.
+ */
+ rtnl_lock();
+ wiphy_lock(drvr->wiphy);
+ ifp = drvr->iflist[i];
+ if (ifp)
+ brcmf_remove_interface(ifp, true);
+ wiphy_unlock(drvr->wiphy);
+ rtnl_unlock();
}
brcmf_bus_stop(drvr->bus_if);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0439/1887] wireguard: noise: reject response consumption after intermediate initiation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (437 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0438/1887] wifi: brcmfmac: fix P2P device removal race in brcmf_detach() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0440/1887] workqueue: Fix NULL current_pwq deref in chained work check Greg Kroah-Hartman
` (559 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Jason A. Donenfeld, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason A. Donenfeld <Jason@zx2c4.com>
commit d0305f8d90029556260c6824b61c493c424eba9e upstream.
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one,
B, gets partway through, and during that slow calculation, or even while
blocking on down_write(), A completes and then also a handshake
initiation that's already been queued up runs in thread C, which itself
takes that same down_write(). The handshake initiation creation
succeeds, and sets the state back to waiting-for-response, and calls
up_write(), at which point thread B resumes, because either its finished
its calculations or was finally allowed to acquire down_write(). Thread
B then copies the state back to the peer, and begins a new session,
using that state, which is the same session as the one made in thread A.
Thread A Thread B Thread C
down_read()
sA = handshake->state
memcpy(cA, handshake->crypto)
up_read()
if (sA != 1)
goto fail
slow_crypto(cA)
down_read()
sB = handshake->state
memcpy(cB, handshake->crypto)
up_read()
if (sB != 1)
goto fail
slow_crypto(cB)
down_write()
if (sA != handshake->state)
goto fail
memcpy(handshake->crypto, cA)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
down_write()
slow_crypto(handshake->crypto)
handshake->state = 1
up_write()
down_write()
if (sB != handshake->state)
goto fail
memcpy(handshake->crypto, cB)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Reported-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261008130124.724119-4-Jason@zx2c4.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireguard/noise.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/net/wireguard/noise.c
+++ b/drivers/net/wireguard/noise.c
@@ -784,10 +784,11 @@ wg_noise_handshake_consume_response(stru
/* Success! Copy everything to peer */
down_write(&handshake->lock);
- /* It's important to check that the state is still the same, while we
- * have an exclusive lock.
+ /* Check that the state is the same and that this is still the
+ * initiation we started with, while we have an exclusive lock.
*/
- if (handshake->state != state) {
+ if (handshake->state != state ||
+ crypto_memneq(handshake->ephemeral_private, ephemeral_private, NOISE_PUBLIC_KEY_LEN)) {
up_write(&handshake->lock);
goto fail;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0440/1887] workqueue: Fix NULL current_pwq deref in chained work check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (438 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0439/1887] wireguard: noise: reject response consumption after intermediate initiation Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0441/1887] xen/netfront: dont leak the skb when xennet_fill_frags() fails Greg Kroah-Hartman
` (558 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pavankumar Kondeti, Tejun Heo
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
commit 980db94e3eeefdd8a1c46f86412c33a7f7806f51 upstream.
current_wq_worker() only tells us that %current is a kworker. It does
not guarantee that the worker is currently executing a work item, as
worker->current_pwq is populated only while process_one_work() is running
the work function.
is_chained_work() can be reached while queueing on a draining or
destroying workqueue. If a kworker outside work-item execution reaches
that path, current_wq_worker() returns a worker but worker->current_pwq is
NULL, and the chained-work test can fault before it emits the intended
warning.
Guard the chained-work test with worker->current_pwq. A kworker without
current_pwq is not executing work on the target workqueue, so the helper
should return false and let the draining/destroying warning fire.
Fixes: 8d03ecfe4718 ("workqueue: reimplement is_chained_work() using current_wq_worker()")
Cc: stable@vger.kernel.org
Signed-off-by: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/workqueue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1382,7 +1382,7 @@ static bool is_chained_work(struct workq
* Return %true iff I'm a worker executing a work item on @wq. If
* I'm @worker, it's safe to dereference it without locking.
*/
- return worker && worker->current_pwq->wq == wq;
+ return worker && worker->current_pwq && worker->current_pwq->wq == wq;
}
/*
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0441/1887] xen/netfront: dont leak the skb when xennet_fill_frags() fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (439 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0440/1887] workqueue: Fix NULL current_pwq deref in chained work check Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0442/1887] strparser: make sure __strp_recv isnt running before tearing down the parser Greg Kroah-Hartman
` (557 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Juergen Gross,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
commit 93ccaf1c26e2133396173b76a071e59024daa622 upstream.
When a response chain has more slots than fit in the skb's frags,
xennet_fill_frags() returns an error and xennet_poll() jumps to its
error path. That path moves what's left on tmpq to errq to be freed,
but the skb being filled was already dequeued from tmpq, so it's never
freed. Each chain that overflows leaks the skb and the pages attached
to it as frags, and the backend decides how many slots it sends.
Put the skb back on tmpq before taking the error path, like the
xennet_set_skb_gso() failure just above it does.
Fixes: ad4f15dc2c70 ("xen/netfront: don't bug in case of too many frags")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://patch.msgid.link/20261007-b4-xen-netfront-fill-frags-leak-v1-1-a8a01ff9cd52@toxicpanda.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/xen-netfront.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1345,8 +1345,10 @@ err:
skb->data_len = rx->status;
skb->len += rx->status;
- if (unlikely(xennet_fill_frags(queue, skb, &tmpq)))
+ if (unlikely(xennet_fill_frags(queue, skb, &tmpq))) {
+ __skb_queue_head(&tmpq, skb);
goto err;
+ }
if (rx->flags & XEN_NETRXF_csum_blank)
skb->ip_summed = CHECKSUM_PARTIAL;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0442/1887] strparser: make sure __strp_recv isnt running before tearing down the parser
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (440 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0441/1887] xen/netfront: dont leak the skb when xennet_fill_frags() fails Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0443/1887] tipc: destroy topsrv workqueues before closing connections Greg Kroah-Hartman
` (556 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Sabrina Dubroca,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
commit 0984ebc631792acf8fff105112ee74a6b8f1efcc upstream.
The comment above strp_done() claims that if strp is stopped,
strp_recv will no longer be called. That's only true if the caller has
a mechanism (eg locking) to guarantee that strp_recv() calls that
started before strp_stop() have completed by the time we call
strp_done().
This adds a dummy lock_sock/release_sock pair to guarantee that any
in-flight strp_recv() (which runs under either bh_lock_sock or
lock_sock, depending if it's called from ->sk_data_ready or strp_work)
has completed.
Only espintcp can be affected by this race condition, but this patch
makes sure no future user of strp can have the bug.
This could crash on strp->sk ("general mode" of strp), but this mode
has been here for 9 years and has never been used. It'll be gone soon,
no point worrying about it.
Switch the stopped/paused/etc bits to u8's to avoid races between
strp_stop() and strp_pause/unpause().
A reproducer has been published and turns the possible UAF into an
exploit [1].
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Link: https://lore.kernel.org/all/aZLn2Faeg1FB7XOf@v4bel/
Link: https://lore.kernel.org/all/aZgpkyTDU3aXe_V0@v4bel/
Link: https://github.com/m0x41nos/RustyTux [1]
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Hyunwoo Kim <imv4bel@gmail.com>
Link: https://patch.msgid.link/425d9d926709b542ed5331110c19fee4aee1f28d.1791206940.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/networking/strparser.rst | 2 +-
include/net/strparser.h | 10 +++++-----
net/strparser/strparser.c | 6 +++++-
3 files changed, 11 insertions(+), 7 deletions(-)
--- a/Documentation/networking/strparser.rst
+++ b/Documentation/networking/strparser.rst
@@ -77,7 +77,7 @@ Functions
strp_done is called to release any resources held by the stream
parser instance. This must be called after the stream processor
- has been stopped.
+ has been stopped. The socket lock must not be held.
::
--- a/include/net/strparser.h
+++ b/include/net/strparser.h
@@ -91,11 +91,11 @@ static inline struct strp_msg *strp_msg(
struct strparser {
struct sock *sk;
- u32 stopped : 1;
- u32 paused : 1;
- u32 aborted : 1;
- u32 interrupted : 1;
- u32 unrecov_intr : 1;
+ u8 stopped;
+ u8 paused;
+ u8 aborted;
+ u8 interrupted;
+ u8 unrecov_intr;
struct sk_buff **skb_nextp;
struct sk_buff *skb_head;
--- a/net/strparser/strparser.c
+++ b/net/strparser/strparser.c
@@ -518,12 +518,16 @@ void strp_unpause(struct strparser *strp
EXPORT_SYMBOL_GPL(strp_unpause);
/* strp must already be stopped so that strp_recv will no longer be called.
- * Note that strp_done is not called with the lower socket held.
+ * Note that strp_done must not be called with the lower socket held.
*/
void strp_done(struct strparser *strp)
{
WARN_ON(!strp->stopped);
+ lock_sock(strp->sk);
+ /* sync with pending strp_recv */
+ release_sock(strp->sk);
+
cancel_delayed_work_sync(&strp->msg_timer_work);
cancel_work_sync(&strp->work);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0443/1887] tipc: destroy topsrv workqueues before closing connections
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (441 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0442/1887] strparser: make sure __strp_recv isnt running before tearing down the parser Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0444/1887] tipc: hold a reference to nodes found by link name Greg Kroah-Hartman
` (555 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei,
David S. Miller
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
commit 3acdd44385bc7e2e57605e073691ce69cc5a960d upstream.
tipc_topsrv_stop() closed subscriber connections while the topology
server's send and receive workqueues were still running. Socket
callbacks and subscription events could then queue more work, and
in-flight send/recv work could drop the last connection reference
during the conn_idr walk.
That race produced several teardown failures: refcount_t addition on
0 from conn_get() on a connection whose release was blocked on
idr_lock, a subsequent use-after-free in tipc_conn_close(),
queue_work() on an already destroyed workqueue from the listener
data-ready callback, and an RCU stall in tipc_topsrv_exit_net()
while the walk spun under idr_lock.
Clear srv->listener under idr_lock so it acts as a shutdown flag,
skip queue_work() once it is NULL, destroy the workqueues to flush
in-flight work, and only then close the remaining connections.
Refuse tipc_conn_lookup() after that flag is cleared, and drop
idr_lock when the teardown walk finds no connection, so an
in-flight subscription event cannot pin idr_in_use while the
walk holds the lock.
v3 supersedes the narrower in-thread diff Tung Quang Nguyen
posted on 2026-09-23. It keeps his teardown order and adds the
lookup refusal and the empty-idr unlock.
Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/topsrv.c | 80 +++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 15 deletions(-)
--- a/net/tipc/topsrv.c
+++ b/net/tipc/topsrv.c
@@ -54,7 +54,7 @@
/**
* struct tipc_topsrv - TIPC server structure
* @conn_idr: identifier set of connection
- * @idr_lock: protect the connection identifier set
+ * @idr_lock: protect the connection identifier set and listener
* @idr_in_use: amount of allocated identifier entry
* @net: network namspace instance
* @awork: accept work item
@@ -217,6 +217,10 @@ static struct tipc_conn *tipc_conn_looku
struct tipc_conn *con;
spin_lock_bh(&s->idr_lock);
+ if (!s->listener) {
+ spin_unlock_bh(&s->idr_lock);
+ return NULL;
+ }
con = idr_find(&s->conn_idr, conid);
if (!connected(con) || !kref_get_unless_zero(&con->kref))
con = NULL;
@@ -300,10 +304,20 @@ static void tipc_conn_send_to_sock(struc
static void tipc_conn_send_work(struct work_struct *work)
{
struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
+ struct tipc_topsrv *srv;
+
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (!srv->listener) {
+ spin_unlock_bh(&srv->idr_lock);
+ goto out;
+ }
+ spin_unlock_bh(&srv->idr_lock);
if (connected(con))
tipc_conn_send_to_sock(con);
+out:
conn_put(con);
}
@@ -333,8 +347,14 @@ void tipc_topsrv_queue_evt(struct net *n
list_add_tail(&e->list, &con->outqueue);
spin_unlock_bh(&con->outqueue_lock);
- if (queue_work(srv->send_wq, &con->swork))
- return;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ if (queue_work(srv->send_wq, &con->swork)) {
+ spin_unlock_bh(&srv->idr_lock);
+ return;
+ }
+ }
+ spin_unlock_bh(&srv->idr_lock);
err:
conn_put(con);
}
@@ -345,14 +365,20 @@ err:
*/
static void tipc_conn_write_space(struct sock *sk)
{
+ struct tipc_topsrv *srv;
struct tipc_conn *con;
read_lock_bh(&sk->sk_callback_lock);
con = sk->sk_user_data;
if (connected(con)) {
- conn_get(con);
- if (!queue_work(con->server->send_wq, &con->swork))
- conn_put(con);
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ conn_get(con);
+ if (!queue_work(srv->send_wq, &con->swork))
+ conn_put(con);
+ }
+ spin_unlock_bh(&srv->idr_lock);
}
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -417,8 +443,17 @@ static int tipc_conn_rcv_from_sock(struc
static void tipc_conn_recv_work(struct work_struct *work)
{
struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
+ struct tipc_topsrv *srv;
int count = 0;
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (!srv->listener) {
+ spin_unlock_bh(&srv->idr_lock);
+ goto out;
+ }
+ spin_unlock_bh(&srv->idr_lock);
+
while (connected(con)) {
if (tipc_conn_rcv_from_sock(con))
break;
@@ -429,6 +464,7 @@ static void tipc_conn_recv_work(struct w
count = 0;
}
}
+out:
conn_put(con);
}
@@ -437,14 +473,20 @@ static void tipc_conn_recv_work(struct w
*/
static void tipc_conn_data_ready(struct sock *sk)
{
+ struct tipc_topsrv *srv;
struct tipc_conn *con;
read_lock_bh(&sk->sk_callback_lock);
con = sk->sk_user_data;
if (connected(con)) {
- conn_get(con);
- if (!queue_work(con->server->rcv_wq, &con->rwork))
- conn_put(con);
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ conn_get(con);
+ if (!queue_work(srv->rcv_wq, &con->rwork))
+ conn_put(con);
+ }
+ spin_unlock_bh(&srv->idr_lock);
}
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -498,8 +540,12 @@ static void tipc_topsrv_listener_data_re
read_lock_bh(&sk->sk_callback_lock);
srv = sk->sk_user_data;
- if (srv)
- queue_work(srv->rcv_wq, &srv->awork);
+ if (srv) {
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener)
+ queue_work(srv->rcv_wq, &srv->awork);
+ spin_unlock_bh(&srv->idr_lock);
+ }
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -696,22 +742,26 @@ static void tipc_topsrv_stop(struct net
int id;
spin_lock_bh(&srv->idr_lock);
+ srv->listener = NULL;
+ spin_unlock_bh(&srv->idr_lock);
+ tipc_topsrv_work_stop(srv);
+
+ spin_lock_bh(&srv->idr_lock);
for (id = 0; srv->idr_in_use; id++) {
con = idr_find(&srv->conn_idr, id);
if (con) {
- conn_get(con);
spin_unlock_bh(&srv->idr_lock);
tipc_conn_close(con);
- conn_put(con);
spin_lock_bh(&srv->idr_lock);
+ continue;
}
+ spin_unlock_bh(&srv->idr_lock);
+ spin_lock_bh(&srv->idr_lock);
}
__module_get(lsock->ops->owner);
__module_get(lsock->sk->sk_prot_creator->owner);
- srv->listener = NULL;
spin_unlock_bh(&srv->idr_lock);
- tipc_topsrv_work_stop(srv);
sock_release(lsock);
idr_destroy(&srv->conn_idr);
kfree(srv);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0444/1887] tipc: hold a reference to nodes found by link name
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (442 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0443/1887] tipc: destroy topsrv workqueues before closing connections Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0445/1887] Revert "wifi: libertas: reject short monitor TX frames" Greg Kroah-Hartman
` (554 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 17e73bae400f6a434dc006e3bee92c94cf781954 upstream.
tipc_node_find_by_name() returns a node after dropping its RCU read lock
without taking a reference. The LINK_SET, LINK_GET and LINK_RESET_STATS
handlers then lock and access the node, racing with timer-driven cleanup of
a down peer. Generic netlink serialization does not exclude the node
timer.
The following interleaving can leave a handler using a freed node:
CPU 0: find the node under RCU and release the node read lock
CPU 1: tipc_node_timeout() clears the links and unlinks the down node
CPU 1: drop the list and timer references, queuing tipc_node_free()
CPU 0: leave the RCU read-side critical section
CPU 1: complete the grace period and free the node
CPU 0: acquire the node lock through the stale pointer
LINK_SET also uses the node's media address after releasing the node lock,
when passing queued packets to tipc_bearer_xmit().
KASAN on v7.3-rc5 reported:
BUG: KASAN: slab-use-after-free in _raw_read_lock_bh
Write of size 4 at addr ffff88807e06f008 by task poc/92
Call Trace:
_raw_read_lock_bh kernel/locking/spinlock.c:287
tipc_nl_node_set_link net/tipc/node.c:2475
genl_family_rcv_msg_doit net/netlink/genetlink.c:1114
genl_rcv_msg net/netlink/genetlink.c:1209
netlink_rcv_skb net/netlink/af_netlink.c:2575
Allocated by task 0:
tipc_node_create net/tipc/node.c:539
tipc_node_check_dest net/tipc/node.c:1196
tipc_disc_rcv net/tipc/discover.c:252
Freed by task 92:
kfree mm/slub.c:6801
rcu_core kernel/rcu/tree.c:2919
Last potentially related work creation:
__call_rcu_common.constprop.0 kernel/rcu/tree.c:3181
tipc_node_timeout net/tipc/node.c:814
Acquire a reference to the selected node with kref_get_unless_zero() before
leaving RCU, returning NULL if the node has already been released. Release
that reference on every caller exit after the last node access, including
transmission in LINK_SET. Keep the existing link lookup order and locking
so concurrent link removal still takes the existing error paths.
Fixes: 6a939f365bdb ("tipc: Auto removal of peer down node instance")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://patch.msgid.link/20260928161246.1895273-1-nicoyip.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/node.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2421,8 +2421,11 @@ static struct tipc_node *tipc_node_find_
}
}
tipc_node_read_unlock(n);
- if (found_node)
+ if (found_node) {
+ if (!kref_get_unless_zero(&found_node->kref))
+ found_node = NULL;
break;
+ }
}
rcu_read_unlock();
@@ -2507,6 +2510,7 @@ out:
tipc_node_read_unlock(node);
tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr,
NULL);
+ tipc_node_put(node);
return res;
}
@@ -2558,12 +2562,14 @@ int tipc_nl_node_get_link(struct sk_buff
link = node->links[bearer_id].link;
if (!link) {
tipc_node_read_unlock(node);
+ tipc_node_put(node);
err = -EINVAL;
goto err_free;
}
err = __tipc_nl_add_link(net, &msg, link, 0);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
if (err)
goto err_free;
}
@@ -2634,11 +2640,13 @@ int tipc_nl_node_reset_link_stats(struct
if (!link) {
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return -EINVAL;
}
tipc_link_reset_stats(link);
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return 0;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0445/1887] Revert "wifi: libertas: reject short monitor TX frames"
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (443 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0444/1887] tipc: hold a reference to nodes found by link name Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0446/1887] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts Greg Kroah-Hartman
` (553 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Johannes Berg
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
commit 9727d1c4e1c971fc42b049b645fdda6852758835 upstream.
This reverts commit 13ff543e0b2c713aedeaadadde686686e949dc78.
The 'goto free' just made things worse, causing a spinlock
to be handled incorrectly. Revert this for now.
Reported-by: Takashi Iwai <tiwai@suse.de>
Cc: stable@vger.kernel.org
Fixes: 13ff543e0b2c ("wifi: libertas: reject short monitor TX frames")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/libertas/tx.c | 7 -------
1 file changed, 7 deletions(-)
--- a/drivers/net/wireless/marvell/libertas/tx.c
+++ b/drivers/net/wireless/marvell/libertas/tx.c
@@ -117,13 +117,6 @@ netdev_tx_t lbs_hard_start_xmit(struct s
if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
- if (skb->len < sizeof(*rtap_hdr) + 4 + ETH_ALEN) {
- lbs_deb_tx("tx err: short monitor frame %u\n", skb->len);
- dev->stats.tx_dropped++;
- dev->stats.tx_errors++;
- goto free;
- }
-
/* set txpd fields from the radiotap header */
txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0446/1887] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (444 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0445/1887] Revert "wifi: libertas: reject short monitor TX frames" Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0447/1887] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute Greg Kroah-Hartman
` (552 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Stephen Smalley, Paul Moore
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Smalley <stephen.smalley.work@gmail.com>
commit 28b7260548af3d35773477993ad4e4de41578dd7 upstream.
When an NFSv4 filesystem exported with security_label is mounted a
second time, sget_fc() returns the existing superblock and
nfs_get_root() calls security_sb_set_mnt_opts() again on it. Since the
superblock is already SB_INITIALIZED, selinux_set_mnt_opts() takes an
early exit without setting SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags. nfs_get_root() then sees kflags without
SECURITY_LSM_NATIVE_LABELS set and clears NFS_CAP_SECURITY_LABEL on
the shared nfs_server, silently disabling per-file labeling for both
the new and the original mount.
Commit 3815a245b501 ("security/selinux: fix SECURITY_LSM_NATIVE_LABELS
on reused superblock") fixed the same problem in
selinux_sb_clone_mnt_opts(). The reused-superblock path for a plain
second mount now goes through sb_set_mnt_opts rather than
sb_clone_mnt_opts, so it needs the same treatment: on both
SE_SBINITIALIZED early exits, set SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags when the superblock was already using
SECURITY_FS_USE_NATVE.
Cc: stable@vger.kernel.org
Closes: https://github.com/SELinuxProject/selinux-kernel/issues/69
Closes: https://github.com/SELinuxProject/selinux-kernel/issues/70
Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/91
Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/92
Fixes: eb9ae686507b ("SELinux: Add new labeling type native labels")
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/hooks.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -646,8 +646,12 @@ static int selinux_set_mnt_opts(struct s
* will be used for both mounts)
*/
if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
- && !opts)
+ && !opts) {
+ if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) &&
+ sbsec->behavior == SECURITY_FS_USE_NATIVE)
+ *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
goto out;
+ }
root_isec = backing_inode_security_novalidate(root);
@@ -691,6 +695,9 @@ static int selinux_set_mnt_opts(struct s
/* previously mounted with options, but not on this attempt? */
if ((sbsec->flags & SE_MNTMASK) && !opts)
goto out_double_mount;
+ if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) &&
+ sbsec->behavior == SECURITY_FS_USE_NATIVE)
+ *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
rc = 0;
goto out;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0447/1887] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (445 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0446/1887] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0448/1887] gpio: xilinx: fix runtime PM leak on request error path Greg Kroah-Hartman
` (551 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xin Long, Hui Peng, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 538b529509c7ab0d909cb65bb7264edca1788d30 upstream.
When an SCTP stream output extension structure (streamoute) has not yet
been allocated, sctp_getsockopt_pr_streamstatus() sets the local stack
variables params.sprstat_abandoned_unsent = 0 and
params.sprstat_abandoned_sent = 0, but then immediately jumps to 'out:',
bypassing copy_to_user(). As a result, when an uninitialized user buffer
is passed to getsockopt(SCTP_PR_STREAM_STATUS), the kernel returns
success (0) without copying the zeroed stats back to user space, leaving
uninitialized data in the user buffer.
Refactor the !streamoute check into an if-else chain so that when
streamoute is NULL, params is zeroed and falls through to copy_to_user(),
copying the zeroed stats to user space and setting retval = 0 once before
returning.
Tested in QEMU against Linux 7.3.0-rc3 using an uninitialized
sctp_prstatus user struct passed to getsockopt(SCTP_PR_STREAM_STATUS) on a
freshly created stream: on the unfixed kernel the user struct contains
uninitialized stack garbage; whereas with this fix applied, getsockopt()
copies zeroed stats into user space and returns 0.
Cc: stable@vger.kernel.org
Reviewed-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Hui Peng <benquike@gmail.com>
Fixes: f952be79cebd ("sctp: introduce struct sctp_stream_out_ext")
Link: https://patch.msgid.link/20260930044611.204739-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sctp/socket.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -7520,11 +7520,7 @@ static int sctp_getsockopt_pr_streamstat
/* Not allocated yet, means all stats are 0 */
params.sprstat_abandoned_unsent = 0;
params.sprstat_abandoned_sent = 0;
- retval = 0;
- goto out;
- }
-
- if (policy == SCTP_PR_SCTP_ALL) {
+ } else if (policy == SCTP_PR_SCTP_ALL) {
params.sprstat_abandoned_unsent = 0;
params.sprstat_abandoned_sent = 0;
for (policy = 0; policy <= SCTP_PR_INDEX(MAX); policy++) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0448/1887] gpio: xilinx: fix runtime PM leak on request error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (446 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0447/1887] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0449/1887] ibmveth: h_free logical LAN on open-fail after register Greg Kroah-Hartman
` (550 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Bartosz Golaszewski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
commit ff82fc3a4a1d417dee1229681cc5285986edb1fa upstream.
pm_runtime_get_sync() leaves the usage counter incremented even when it
fails, and xgpio_request() returns the error without dropping it.
gpiolib does not call ->free() when ->request() fails, so xgpio_free(),
which holds the only matching pm_runtime_put(), never runs. The reference
is leaked and the controller can no longer runtime-suspend, so its clock
stays enabled.
Switch to pm_runtime_resume_and_get(), which only increments the usage
counter on success.
Fixes: 26b04774621e ("gpio: gpio-xilinx: Add support for suspend and resume")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260923113905.1409290-1-khurana.ridham222@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-xilinx.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -292,14 +292,7 @@ static void xgpio_save_regs(struct xgpio
static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
{
- int ret;
-
- ret = pm_runtime_get_sync(chip->parent);
- /*
- * If the device is already active pm_runtime_get() will return 1 on
- * success, but gpio_request still needs to return 0.
- */
- return ret < 0 ? ret : 0;
+ return pm_runtime_resume_and_get(chip->parent);
}
static void xgpio_free(struct gpio_chip *chip, unsigned int offset)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0449/1887] ibmveth: h_free logical LAN on open-fail after register
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (447 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0448/1887] gpio: xilinx: fix runtime PM leak on request error path Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0450/1887] ibmveth: fix TX LTB and filter unwind on open-fail Greg Kroah-Hartman
` (549 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mingming Cao, Dave Marquardt,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingming Cao <mmc@linux.ibm.com>
commit af0524bf4ce1a4cbd2946aa81751582951cfcab5 upstream.
ibmveth_open() registers the logical LAN, then allocates the RX
buffer pools. A pool failure jumps to out_free_buffer_pools without
h_free_logical_lan(), so PHYP still owns the buffer-list page when
it is unmapped. request_irq() failure already issued the hypercall
before taking the same label.
Move that h_free to the shared post-register unwind so both paths
deregister before the buffer list is unmapped.
Fixes: d43732ce021f ("ibmveth: properly unwind on init errors")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/7a56fbfb9e0674f011f4e310fbd7dfd8e67c30aa.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -630,10 +630,6 @@ static int ibmveth_open(struct net_devic
if (rc != 0) {
netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
netdev->irq, rc);
- do {
- lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
- } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
-
goto out_free_buffer_pools;
}
@@ -649,6 +645,9 @@ static int ibmveth_open(struct net_devic
return 0;
out_free_buffer_pools:
+ do {
+ lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
+ } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
while (--i >= 0) {
if (adapter->rx_buff_pool[i].active)
ibmveth_free_buffer_pool(adapter,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0450/1887] ibmveth: fix TX LTB and filter unwind on open-fail
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (448 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0449/1887] ibmveth: h_free logical LAN on open-fail after register Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0451/1887] keys: finalize persistent keyring timeout after link attempt Greg Kroah-Hartman
` (548 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mingming Cao, Dave Marquardt,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingming Cao <mmc@linux.ibm.com>
commit 84bec0bf035258a1073ffd6f6dc8ea61806aa7d4 upstream.
out_free_buffer_pools reuses open()'s loop index for the TX LTB
walk. After the pool unwind i is -1, so the TX buffers allocated
earlier are leaked. request_irq() failure has the same leak.
The TX-fail goto on that walk also skips dma_unmap of the filter
list (pre-existing since the LTB was added). Rewrite the TX walk
to real_num_tx_queues with a pointer check, and unmap the filter
list before those frees.
Fixes: d926793c1de9 ("ibmveth: Implement multi queue on xmit")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/d14314c2b10f125f5e578782484ba3cc50564d53.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -465,10 +465,15 @@ static void ibmveth_rxq_harvest_buffer(s
static void ibmveth_free_tx_ltb(struct ibmveth_adapter *adapter, int idx)
{
+ void *ptr = adapter->tx_ltb_ptr[idx];
+
+ if (!ptr)
+ return;
+
+ adapter->tx_ltb_ptr[idx] = NULL;
dma_unmap_single(&adapter->vdev->dev, adapter->tx_ltb_dma[idx],
adapter->tx_ltb_size, DMA_TO_DEVICE);
- kfree(adapter->tx_ltb_ptr[idx]);
- adapter->tx_ltb_ptr[idx] = NULL;
+ kfree(ptr);
}
static int ibmveth_allocate_tx_ltb(struct ibmveth_adapter *adapter, int idx)
@@ -579,7 +584,7 @@ static int ibmveth_open(struct net_devic
for (i = 0; i < netdev->real_num_tx_queues; i++) {
if (ibmveth_allocate_tx_ltb(adapter, i))
- goto out_free_tx_ltb;
+ goto out_unmap_filter_list;
}
adapter->rx_queue.index = 0;
@@ -657,10 +662,8 @@ out_unmap_filter_list:
dma_unmap_single(dev, adapter->filter_list_dma, 4096,
DMA_BIDIRECTIONAL);
-out_free_tx_ltb:
- while (--i >= 0) {
+ for (i = netdev->real_num_tx_queues - 1; i >= 0; i--)
ibmveth_free_tx_ltb(adapter, i);
- }
out_unmap_buffer_list:
dma_unmap_single(dev, adapter->buffer_list_dma, 4096,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0451/1887] keys: finalize persistent keyring timeout after link attempt
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (449 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0450/1887] ibmveth: fix TX LTB and filter unwind on open-fail Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0452/1887] KEYS: Fix add_key() race with keyring restriction Greg Kroah-Hartman
` (547 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jarkko Sakkinen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit 25bf14f817168079f731975b8998fc2af380f29e upstream.
When no keyring exists for the requested UID, KEYCTL_GET_PERSISTENT
creates and registers one before linking it to the requested destination.
The configured timeout is set only after the destination link succeeds.
A destination restricted with KEYCTL_RESTRICT_KEYRING makes that link fail
with -EPERM. With persistent_keyring_expiry set to 60 seconds, /proc/keys
still reports the registered keyring's expiry as "perm".
The failed call therefore leaves a quota-exempt keyring in the namespace's
hidden register, where it may remain until namespace teardown.
Rename the write-locked helper to key_get_or_create_persistent() and return
the key reference through a result parameter. Return 0 when it creates a
keyring and 1 when the retry finds an existing one. Return a negative error
on failure. Another caller may create the keyring between the initial
read-locked lookup and the retry under the write lock.
Set the timeout after permission checking and linking. Do this on success,
or on failure if the call allocated the keyring. This leaves a new keyring
collectible after failure without starting its timeout while linking is
still in progress.
Cc: stable@vger.kernel.org # v5.10+
Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260912095440.79864-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/persistent.c | 55 ++++++++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 23 deletions(-)
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -33,25 +33,31 @@ static int key_create_persistent_registe
}
/*
- * Create the persistent keyring for the specified user.
+ * Get or create the persistent keyring for the specified user.
*
* Called with the namespace's sem locked for writing.
+ *
+ * Returns a boolean indicating whether the keyring already existed,
+ * or a negative error. On success, *persistent_ref holds a reference
+ * to the keyring.
*/
-static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
- struct keyring_index_key *index_key)
+static int key_get_or_create_persistent(struct user_namespace *ns, kuid_t uid,
+ struct keyring_index_key *index_key,
+ key_ref_t *persistent_ref)
{
struct key *persistent;
- key_ref_t reg_ref, persistent_ref;
+ key_ref_t reg_ref;
if (!ns->persistent_keyring_register) {
- long err = key_create_persistent_register(ns);
+ int err = key_create_persistent_register(ns);
+
if (err < 0)
- return ERR_PTR(err);
+ return err;
} else {
reg_ref = make_key_ref(ns->persistent_keyring_register, true);
- persistent_ref = find_key_to_update(reg_ref, index_key);
- if (persistent_ref)
- return persistent_ref;
+ *persistent_ref = find_key_to_update(reg_ref, index_key);
+ if (*persistent_ref)
+ return 1;
}
persistent = keyring_alloc(index_key->description,
@@ -61,9 +67,10 @@ static key_ref_t key_create_persistent(s
KEY_ALLOC_NOT_IN_QUOTA, NULL,
ns->persistent_keyring_register);
if (IS_ERR(persistent))
- return ERR_CAST(persistent);
+ return PTR_ERR(persistent);
- return make_key_ref(persistent, true);
+ *persistent_ref = make_key_ref(persistent, true);
+ return 0;
}
/*
@@ -78,6 +85,7 @@ static long key_get_persistent(struct us
key_ref_t reg_ref, persistent_ref;
char buf[32];
long ret;
+ bool created = false;
/* Look in the register if it exists */
memset(&index_key, 0, sizeof(index_key));
@@ -100,23 +108,24 @@ static long key_get_persistent(struct us
* also need to create the register.
*/
down_write(&ns->keyring_sem);
- persistent_ref = key_create_persistent(ns, uid, &index_key);
+ ret = key_get_or_create_persistent(ns, uid, &index_key,
+ &persistent_ref);
up_write(&ns->keyring_sem);
- if (!IS_ERR(persistent_ref))
- goto found;
-
- return PTR_ERR(persistent_ref);
+ if (ret < 0)
+ return ret;
+ created = ret == 0;
found:
+ persistent = key_ref_to_ptr(persistent_ref);
ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK);
- if (ret == 0) {
- persistent = key_ref_to_ptr(persistent_ref);
+ if (ret == 0)
ret = key_link(key_ref_to_ptr(dest_ref), persistent);
- if (ret == 0) {
- key_set_timeout(persistent, persistent_keyring_expiry);
- ret = persistent->serial;
- }
- }
+
+ if (ret == 0 || created)
+ key_set_timeout(persistent, persistent_keyring_expiry);
+
+ if (ret == 0)
+ ret = persistent->serial;
key_ref_put(persistent_ref);
return ret;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0452/1887] KEYS: Fix add_key() race with keyring restriction
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (450 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0451/1887] keys: finalize persistent keyring timeout after link attempt Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0453/1887] memstick: core: wait for request completion before freeing card Greg Kroah-Hartman
` (546 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, 성병찬,
Jarkko Sakkinen
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: 성병찬 <tjdqudcks0424@naver.com>
commit dd3ea3fcba7c75493760cdbccd35f029597e8d5e upstream.
__key_create_or_update() snapshots keyring->restrict_link before taking
the destination keyring's semaphore. keyring_restrict() installs a
restriction while holding that semaphore.
This allows a writer to observe no restriction, wait for the keyring
owner to install a reject-all restriction and return successfully, and
then link a key using the stale NULL snapshot. The writer only needs
write permission on the destination keyring.
Move the restrict_link read after __key_link_lock() and
__key_link_begin(). The read and the subsequent restriction check are
then serialized with restriction installation by keyring->sem.
The race was reproduced on v7.2.8 in 19 executions where restriction
installation returned before the link completed. All 19 linked the key
despite the reject-all restriction. With this change, 312 executions
reached the same ordering and every add_key() call failed with -EPERM.
The issue was found by manual concurrency analysis assisted by AI-based
analysis and independently verified with a QEMU reproducer and kernel
instrumentation.
Fixes: 5ac7eace2d00 ("KEYS: Add a facility to restrict new links into a keyring")
Cc: stable@vger.kernel.org
Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260930041802.6114-1-tjdqudcks0424@naver.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/key.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -845,9 +845,6 @@ key_ref_t key_create_or_update(key_ref_t
key_check(keyring);
- if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
- restrict_link = keyring->restrict_link;
-
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
goto error_put_type;
@@ -885,6 +882,9 @@ key_ref_t key_create_or_update(key_ref_t
goto error_link_end;
}
+ if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
+ restrict_link = keyring->restrict_link;
+
if (restrict_link && restrict_link->check) {
ret = restrict_link->check(keyring, index_key.type,
&prep.payload, restrict_link->key);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0453/1887] memstick: core: wait for request completion before freeing card
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (451 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0452/1887] KEYS: Fix add_key() race with keyring restriction Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0454/1887] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them Greg Kroah-Hartman
` (545 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ccffdf05833ebdaeae70,
Raj Ojha, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raj Ojha <rajojha047@gmail.com>
commit aa0a37b5024d921e96ac4f8f487c8bfbf1f1a582 upstream.
In memstick_alloc_card() and memstick_set_rw_addr(),
wait_for_completion_timeout() is used to wait for device identification
and address configuration requests to complete.
The memstick subsystem does not provide an abort or cancellation
callback in struct memstick_host for in-flight requests. If
wait_for_completion_timeout() expires (for instance, when a USB transfer
or command retry is delayed), memstick_alloc_card() returns an error and
frees the memstick_dev structure via kfree(card).
However, the host controller driver (such as rtsx_usb_ms) is still
running the request asynchronously in worker context. When the transfer
eventually finishes, the driver writes into host->req->data, which
points to memory inside the already freed card structure. This leads to
a KASAN slab-use-after-free write:
BUG: KASAN: slab-use-after-free in ms_read_bytes+0x8fe/0x990
Write of size 1 at addr ffff88813c188079 by task kworker/1:5/5239
Workqueue: events rtsx_usb_ms_handle_req
Call Trace:
ms_read_bytes+0x8fe/0x990 drivers/memstick/host/rtsx_usb_ms.c:450
rtsx_usb_ms_issue_cmd drivers/memstick/host/rtsx_usb_ms.c:477 [inline]
rtsx_usb_ms_handle_req+0x557/0x1a00 drivers/memstick/host/rtsx_usb_ms.c:531
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3560
kthread+0x373/0x450 kernel/kthread.c:436
Allocated by task 1662:
memstick_alloc_card drivers/memstick/core/memstick.c:383 [inline]
memstick_check+0x2c1/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Freed by task 1662:
kfree+0x20c/0x650 mm/slub.c:6792
memstick_alloc_card drivers/memstick/core/memstick.c:420 [inline]
memstick_check+0x72b/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Host controller drivers (rtsx_usb_ms, jmb38x_ms, tifm_ms, r592) already
implement their own hardware and bus timeouts, and callers in
mspro_block and ms_block already rely on wait_for_completion()
unconditionally.
Replace wait_for_completion_timeout() with wait_for_completion() in
memstick_set_rw_addr() and memstick_alloc_card() so that the card
structure is never freed while an asynchronous request is in flight.
Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support")
Reported-by: syzbot+ccffdf05833ebdaeae70@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ccffdf05833ebdaeae70
Cc: stable@vger.kernel.org
Signed-off-by: Raj Ojha <rajojha047@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/memstick/core/memstick.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -367,9 +367,7 @@ int memstick_set_rw_addr(struct memstick
{
card->next_request = h_memstick_set_rw_addr;
memstick_new_req(card->host);
- if (!wait_for_completion_timeout(&card->mrq_complete,
- msecs_to_jiffies(500)))
- card->current_mrq.error = -ETIMEDOUT;
+ wait_for_completion(&card->mrq_complete);
return card->current_mrq.error;
}
@@ -403,9 +401,7 @@ static struct memstick_dev *memstick_all
card->next_request = h_memstick_read_dev_id;
memstick_new_req(host);
- if (!wait_for_completion_timeout(&card->mrq_complete,
- msecs_to_jiffies(500)))
- card->current_mrq.error = -ETIMEDOUT;
+ wait_for_completion(&card->mrq_complete);
if (card->current_mrq.error)
goto err_out;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0454/1887] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (452 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0453/1887] memstick: core: wait for request completion before freeing card Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0455/1887] dm-crypt: reject the lmk IV mode with AEAD ciphers Greg Kroah-Hartman
` (544 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nguyen Ngoc Thang, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
commit c96ca94425b076dc398d929366e378d1e22ec794 upstream.
memstick_check() can pass its host->removing check just before
rtsx_usb_ms_drv_remove() sets eject/removing. Its next request is then
silently dropped: rtsx_usb_ms_request() skips schedule_work() once eject
is set, and drv_remove's cancel_work_sync() can also cancel a queued
handle_req before it picks the request up. Nobody completes
card->mrq_complete.
Once memstick core waits for requests without a timeout ("memstick: core:
wait for request completion before freeing card"), this hangs removal:
memstick_check() never returns and memstick_remove_host() blocks in
flush_workqueue():
INFO: task kworker/u10:3:65 blocked for more than 20 seconds.
Workqueue: kmemstick memstick_check
__wait_for_common
memstick_check
INFO: task kworker/1:1:33 blocked for more than 20 seconds.
Workqueue: usb_hub_wq hub_event
__flush_workqueue
memstick_remove_host
rtsx_usb_ms_drv_remove
Never drop a request. rtsx_usb_ms_request() always schedules handle_req,
and handle_req fails requests with -ENOMEDIUM once eject is set, without
touching the device. drv_remove flushes handle_req instead of cancelling
it, and cancels it only after memstick_remove_host(), when no new
request can arrive, so it cannot run on a freed host.
The host_mutex drain in drv_remove is removed: handle_req always leaves
host->req NULL when it finishes, so the drain never had anything to do,
and it would now race with handle_req.
Fixes: 99451dceeb5f ("memstick: Add realtek USB memstick host driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20260924204142.607-1-rajojha047@gmail.com/
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/memstick/host/rtsx_usb_ms.c | 31 +++++++++++--------------------
1 file changed, 11 insertions(+), 20 deletions(-)
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -27,7 +27,6 @@ struct rtsx_usb_ms {
struct memstick_host *msh;
struct memstick_request *req;
- struct mutex host_mutex;
struct work_struct handle_req;
struct delayed_work poll_card;
@@ -511,6 +510,13 @@ static void rtsx_usb_ms_handle_req(struc
struct memstick_host *msh = host->msh;
int rc;
+ /* Fail requests after eject so their waiters are released. */
+ if (host->eject) {
+ while (!memstick_next_req(msh, &host->req))
+ host->req->error = -ENOMEDIUM;
+ return;
+ }
+
if (!host->req) {
pm_runtime_get_sync(ms_dev(host));
do {
@@ -544,8 +550,7 @@ static void rtsx_usb_ms_request(struct m
dev_dbg(ms_dev(host), "--> %s\n", __func__);
- if (!host->eject)
- schedule_work(&host->handle_req);
+ schedule_work(&host->handle_req);
}
static int rtsx_usb_ms_set_param(struct memstick_host *msh,
@@ -778,7 +783,6 @@ static int rtsx_usb_ms_drv_probe(struct
host->power_mode = MEMSTICK_POWER_OFF;
platform_set_drvdata(pdev, host);
- mutex_init(&host->host_mutex);
INIT_WORK(&host->handle_req, rtsx_usb_ms_handle_req);
INIT_DELAYED_WORK(&host->poll_card, rtsx_usb_ms_poll_card);
@@ -809,27 +813,12 @@ static int rtsx_usb_ms_drv_remove(struct
{
struct rtsx_usb_ms *host = platform_get_drvdata(pdev);
struct memstick_host *msh = host->msh;
- int err;
host->eject = true;
msh->removing = true;
- cancel_work_sync(&host->handle_req);
+ flush_work(&host->handle_req);
cancel_delayed_work_sync(&host->poll_card);
- mutex_lock(&host->host_mutex);
- if (host->req) {
- dev_dbg(ms_dev(host),
- "%s: Controller removed during transfer\n",
- dev_name(&msh->dev));
- host->req->error = -ENOMEDIUM;
- do {
- err = memstick_next_req(msh, &host->req);
- if (!err)
- host->req->error = -ENOMEDIUM;
- } while (!err);
- }
- mutex_unlock(&host->host_mutex);
-
/* Balance possible unbalanced usage count
* e.g. unconditional module removal
*/
@@ -838,6 +827,8 @@ static int rtsx_usb_ms_drv_remove(struct
pm_runtime_disable(ms_dev(host));
memstick_remove_host(msh);
+ /* No card, no new requests; wait for the last failed one to finish. */
+ cancel_work_sync(&host->handle_req);
dev_dbg(ms_dev(host),
": Realtek USB Memstick controller has been removed\n");
memstick_free_host(msh);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0455/1887] dm-crypt: reject the lmk IV mode with AEAD ciphers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (453 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0454/1887] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0456/1887] dm-snap: reject the transient exception store for snapshot-merge Greg Kroah-Hartman
` (543 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Cressey, Mikulas Patocka
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Cressey <ben@cressey.dev>
commit 3195e0daf590683992edb4eed32269e569e04924 upstream.
A "capi:" table line that pairs an AEAD cipher with the lmk IV mode,
for example "capi:gcm(aes)-lmk" with the integrity:28:aead option,
causes an oops when it is loaded. lmk sets tfms_count to 64, but
crypt_alloc_tfms_aead only allocates one transform, so crypt_setkey
reads past the end of the tfms_aead array and calls crypto_aead_setkey
on the values it finds there.
lmk exists for compatibility with Loop-AES, which uses CBC, so refuse
it with an AEAD cipher rather than allocate 64 AEAD transforms. The
check cannot go in crypt_iv_lmk_ctr with the other lmk checks, because
the IV constructor runs after crypt_set_key.
Note that this is not a security bug because the memory corruption can
only be triggered by root.
Fixes: 33d2f09fcb35 ("dm crypt: introduce new format of cipher with "capi:" prefix")
Cc: stable@vger.kernel.org
Signed-off-by: Ben Cressey <ben@cressey.dev>
Assisted-by: LLM
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-crypt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2914,8 +2914,13 @@ static int crypt_ctr_cipher_new(struct d
}
}
- if (*ivmode && !strcmp(*ivmode, "lmk"))
+ if (*ivmode && !strcmp(*ivmode, "lmk")) {
+ if (crypt_integrity_aead(cc)) {
+ ti->error = "AEAD transforms not supported for LMK";
+ return -EINVAL;
+ }
cc->tfms_count = 64;
+ }
if (*ivmode && !strcmp(*ivmode, "essiv")) {
if (!*ivopts) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0456/1887] dm-snap: reject the transient exception store for snapshot-merge
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (454 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0455/1887] dm-crypt: reject the lmk IV mode with AEAD ciphers Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0457/1887] mmc: cavium-octeon: destroy slot platform devices on remove Greg Kroah-Hartman
` (542 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ma Xinmeng, Mikulas Patocka
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Xinmeng <1564938642@qq.com>
commit fcbde6227fcc53c73f08c56b2539e462d545cac6 upstream.
snapshot_merge_next_chunks() calls s->store->type->prepare_merge() without
checking it. The transient store ("N") implements neither prepare_merge nor
commit_merge, and snapshot_ctr() validates those callbacks only on the handover
path (__validate_exception_handover()), so a directly constructed snapshot-merge
calls a NULL prepare_merge on resume:
snapshot_merge_resume -> snapshot_merge_next_chunks -> prepare_merge(...)
commit_merge() is NULL for the same reason. Userspace only issues documented
device-mapper ioctls (CAP_SYS_ADMIN); this is a misconfiguration the kernel must
reject rather than oops on.
Reject the combination in snapshot_ctr() at table-load time (-EINVAL), the same
check the handover path already performs; this also covers the commit_merge()
call site, which a guard local to the prepare_merge call would miss.
Tested on Linux v6.6.157 KASAN: unpatched, the dmsetup reproducer oopses in
snapshot_merge_next_chunks(); with this patch, the table load fails with -EINVAL
and no oops. Also present on v6.6.145; still present on the linux-dm tree
(555f3d7be91a) and on torvalds/linux master (62f4c998b297) as of 2026-09-22.
Note that this is not a security bug because only root can trigger it.
Signed-off-by: Ma Xinmeng <1564938642@qq.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-snap.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1306,6 +1306,20 @@ static int snapshot_ctr(struct dm_target
goto bad_store;
}
+ /*
+ * snapshot-merge requires the optional prepare_merge/commit_merge
+ * callbacks; the transient exception store does not implement them.
+ * The handover path checks this in __validate_exception_handover(),
+ * but a directly constructed snapshot-merge never goes through it.
+ */
+ if (dm_target_is_snapshot_merge(ti) &&
+ (!s->store->type->prepare_merge ||
+ !s->store->type->commit_merge)) {
+ ti->error = "Snapshot exception store does not support snapshot-merge.";
+ r = -EINVAL;
+ goto bad_hash_tables;
+ }
+
argv += args_used;
argc -= args_used;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0457/1887] mmc: cavium-octeon: destroy slot platform devices on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (455 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0456/1887] dm-snap: reject the transient exception store for snapshot-merge Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0458/1887] mmc: cavium-thunderx: " Greg Kroah-Hartman
` (541 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 0f4d4424fc1d651ec3fa63a0a8060ba9087eb0ec upstream.
octeon_mmc_probe() creates host->slot_pdev[i] with
of_platform_device_create(), while octeon_mmc_remove() does not destroy
the child platform devices.
The probe failure path removes each MMC slot and destroys its associated
platform device, but the normal remove path only removes the MMC slot.
As a result, the child platform devices remain registered after the
Octeon MMC controller is removed.
Destroy each slot platform device during removal after cleaning up the
corresponding MMC slot, matching the probe failure cleanup path.
This issue was found by manual code inspection.
Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/cavium-octeon.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/cavium-octeon.c
+++ b/drivers/mmc/host/cavium-octeon.c
@@ -300,9 +300,12 @@ static int octeon_mmc_remove(struct plat
u64 dma_cfg;
int i;
- for (i = 0; i < CAVIUM_MAX_MMC; i++)
+ for (i = 0; i < CAVIUM_MAX_MMC; i++) {
if (host->slot[i])
cvm_mmc_of_slot_remove(host->slot[i]);
+ if (host->slot_pdev[i])
+ of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
+ }
dma_cfg = readq(host->dma_base + MIO_EMM_DMA_CFG(host));
dma_cfg &= ~MIO_EMM_DMA_CFG_EN;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0458/1887] mmc: cavium-thunderx: destroy slot platform devices on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (456 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0457/1887] mmc: cavium-octeon: destroy slot platform devices on remove Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0459/1887] mmc: mtk-sd: Cancel request timeout work " Greg Kroah-Hartman
` (540 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 29ee8cf18a21b02cd0b2e35f741b61cd1fe3e14e upstream.
thunder_mmc_probe() creates host->slot_pdev[i] with
of_platform_device_create(), while thunder_mmc_remove() does not destroy
the child platform devices.
The probe failure path removes each MMC slot and destroys its associated
platform device, but the normal remove path only removes the MMC slot.
As a result, the child platform devices remain registered after the
ThunderX MMC controller is removed.
Destroy each slot platform device during removal after cleaning up the
corresponding MMC slot, matching the probe failure cleanup path. Keep an
extra device reference around of_platform_device_destroy() as done in
the existing error path.
This issue was found by manual code inspection.
Fixes: 166bac38c3c56 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/cavium-thunderx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/cavium-thunderx.c
+++ b/drivers/mmc/host/cavium-thunderx.c
@@ -173,9 +173,12 @@ static void thunder_mmc_remove(struct pc
u64 dma_cfg;
int i;
- for (i = 0; i < CAVIUM_MAX_MMC; i++)
+ for (i = 0; i < CAVIUM_MAX_MMC; i++) {
if (host->slot[i])
cvm_mmc_of_slot_remove(host->slot[i]);
+ if (host->slot_pdev[i])
+ of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
+ }
dma_cfg = readq(host->dma_base + MIO_EMM_DMA_CFG(host));
dma_cfg &= ~MIO_EMM_DMA_CFG_EN;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0459/1887] mmc: mtk-sd: Cancel request timeout work on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (457 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0458/1887] mmc: cavium-thunderx: " Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0460/1887] mmc: sdhci-sprd: disable runtime PM " Greg Kroah-Hartman
` (539 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yibo Tan, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yibo Tan <lhfff@tju.edu.cn>
commit b38af5386a74416e898955443f2e26547b358cb2 upstream.
The driver queues req_timeout while a request is active.
msdc_request_done() uses cancel_delayed_work(), which does not wait for
a timeout callback that has already started.
The timeout callback calls mmc_request_done(), which wakes the request
waiter, and then continues to use host->dev_comp and check the SDIO IRQ.
During unbind, msdc_drv_remove() can return and the managed mmc_host can
be freed before the callback finishes.
KASAN reported use-after-free accesses in msdc_request_done() and
msdc_recheck_sdio_irq() in each of three unbind tests. The same tests
completed without a kernel diagnostic after this change.
Call cancel_delayed_work_sync() after mmc_remove_host() has stopped new
requests and before the driver releases the host resources.
Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mtk-sd.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -2854,6 +2854,7 @@ static int msdc_drv_remove(struct platfo
platform_set_drvdata(pdev, NULL);
mmc_remove_host(mmc);
+ cancel_delayed_work_sync(&host->req_timeout);
msdc_deinit_hw(host);
msdc_gate_clock(host);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0460/1887] mmc: sdhci-sprd: disable runtime PM on remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (458 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0459/1887] mmc: mtk-sd: Cancel request timeout work " Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0461/1887] net/packet: guard the ll header push in packet_rcv_spkt() Greg Kroah-Hartman
` (538 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Baolin Wang,
Adrian Hunter, Ulf Hansson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit e1c6c10a6a70a69e29b04fcc1ebe4b9bcbc7a49a upstream.
sdhci_sprd_probe() enables runtime PM, while sdhci_sprd_remove() does
not perform the corresponding runtime PM cleanup.
The probe failure path disables runtime PM before disabling the clocks,
but the normal remove path directly disables clocks that are also
managed by the runtime PM callbacks. If the device is runtime
suspended, those clocks may already be disabled.
Resume the device before removal, disable runtime PM and drop the
temporary runtime PM reference before disabling the clocks.
This issue was found by manual code inspection.
Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci-sprd.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/mmc/host/sdhci-sprd.c
+++ b/drivers/mmc/host/sdhci-sprd.c
@@ -756,6 +756,10 @@ static int sdhci_sprd_remove(struct plat
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
sdhci_remove_host(host, 0);
clk_disable_unprepare(sprd_host->clk_sdio);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0461/1887] net/packet: guard the ll header push in packet_rcv_spkt()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (459 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0460/1887] mmc: sdhci-sprd: disable runtime PM " Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0462/1887] net/smc: protect clcsock lifetime in smc_getname Greg Kroah-Hartman
` (537 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Quchaosheng, Willem de Bruijn,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quchaosheng <quchaosheng000406@163.com>
commit 28bc1ef699610ee09ce3d46a00552f5a0a0144bd upstream.
packet_rcv_spkt() restores the link layer header with
skb_push(skb, skb->data - skb_mac_header(skb));
That subtraction is only meaningful when the device actually has a link
layer header. packet_rcv() and tpacket_rcv() both wrap it in
dev_has_header(), which is also the predicate the block comment at the
top of the file states the restore in terms of; packet_rcv_spkt() does
not. commit d549699048b4 ("net/packet: fix packet receive on L3
devices without visible hard header") introduced the helper and changed
the two call sites, and this one stayed behind.
A device without a visible ll header can leave skb->mac_header at the
0xFFFF sentinel that __alloc_skb() initialises it to. A CAN skb does:
init_can_skb() sets pkt_type and ip_summed but does not reset the
headers, and commit 9f10374bb024 ("can: remove private CAN skb
headroom infrastructure") dropped the skb_reset_*_header() calls that
used to be there. skb_mac_header() is then 0xFFFF, the length becomes
a large negative number and skb_push() reports it through
skb_under_panic() -- from softirq context, so it is a full system panic
even with panic_on_oops=0:
skbuff: skb_under_panic: text:ffffffff8bd21bc1 len:-65455 put:-65471 head:... data:... tail:0x50 end:0x180 dev:can0
kernel BUG at net/core/skbuff.c:214!
RIP: 0010:skb_panic+0x50/0x60
Call Trace:
<IRQ>
skb_push+0x38/0x40
packet_rcv_spkt+0xe1/0x170
__netif_receive_skb_core.constprop.0+0x7e8/0xd30
...
Kernel panic - not syncing: Fatal exception in interrupt
The socket type is reachable: packet_create() accepts SOCK_PACKET
alongside SOCK_RAW and SOCK_DGRAM behind the same CAP_NET_RAW check,
and neither the socket length nor a capability check keeps it away
from a CAN interface.
The missing skb_reset_*_header() calls in init_can_skb() are a
regression in their own right and are being fixed separately, but a
packet socket should not turn a link layer that did not initialise its
mac header into a kernel panic. Guard the push the way the other two
receive paths do.
Tested on v7.3-rc5 under QEMU with a slcan device on a pty, which is
the driver RX path: vcan does not reproduce it, because can_send()
resets the headers on the way out. One SOCK_PACKET socket bound to
can0 and one frame written into the line discipline panics an
unpatched kernel with the trace above; the same image with this patch
prints no panic and powers off normally. Both kernels are this tree,
defconfig plus CONFIG_CAN_SLCAN=y, differing only in this hunk.
Fixes: d549699048b4 ("net/packet: fix packet receive on L3 devices without visible hard header")
Cc: stable@vger.kernel.org
Signed-off-by: Quchaosheng <quchaosheng000406@163.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260928113108.2127215-1-quchaosheng000406@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1964,7 +1964,8 @@ static int packet_rcv_spkt(struct sk_buf
spkt = &PACKET_SKB_CB(skb)->sa.pkt;
- skb_push(skb, skb->data - skb_mac_header(skb));
+ if (dev_has_header(dev))
+ skb_push(skb, skb->data - skb_mac_header(skb));
/*
* The SOCK_PACKET socket receives _all_ frames.
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0462/1887] net/smc: protect clcsock lifetime in smc_getname
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (460 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0461/1887] net/packet: guard the ll header push in packet_rcv_spkt() Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0463/1887] net: bridge: avoid recursive multicast port cleanup Greg Kroah-Hartman
` (536 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Mahanta Jambigi,
Dust Li, Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 64a6b36b0e1855288080bc5f89769f27d6dc03c8 upstream.
smc_getname() dereferences smc->clcsock without holding
clcsock_release_lock. Link-group termination can release the CLC socket
through smc_close_active_abort() while the SMC socket is still open,
for example after shutdown(SHUT_WR).
A getsockname() caller can load smc->clcsock, then the termination worker
can clear the pointer and call sock_release() before the caller accesses
clcsock->ops or invokes getname(). This causes a use-after-free; if the
worker clears the pointer before the load, it causes a NULL dereference.
The syscall's file reference keeps the SMC socket alive but does not
prevent asynchronous release of its CLC socket.
KASAN reported the following with test-only timing instrumentation:
BUG: KASAN: slab-use-after-free in smc_getname+0x19e/0x1b0
Read of size 8 at addr ffff888109abb4e0 by task poc/103
Call Trace:
smc_getname+0x19e/0x1b0
do_getsockname+0xe5/0x170
__sys_getsockname+0x8c/0x100
Allocated by task 95:
sock_alloc_inode+0x1e/0x280
sock_alloc+0x3d/0x240
__sock_create+0x7e/0x430
smc_create+0x121/0x240
Freed by task 0:
kmem_cache_free+0xcc/0x340
rcu_core+0x50a/0x1850
Last potentially related work creation:
evict+0x446/0x6c0
smc_clcsock_release+0xa8/0xd0
smc_close_active_abort+0x26a/0x3a0
__smc_lgr_terminate.part.0+0x137/0x2e0
Hold clcsock_release_lock across the pointer check and the getname()
callback to serialize with smc_clcsock_release(). Return -EBADF if the
CLC socket has already been released, preserving the existing peer
state check and the callback's return value otherwise.
Fixes: b03faa1fafc8 ("net/smc: postpone release of clcsock")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20261008084444.787449-1-nicoyip.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/smc/af_smc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -2677,6 +2677,7 @@ static int smc_getname(struct socket *so
int peer)
{
struct smc_sock *smc;
+ int rc = -EBADF;
if (peer && (sock->sk->sk_state != SMC_ACTIVE) &&
(sock->sk->sk_state != SMC_APPCLOSEWAIT1))
@@ -2684,7 +2685,11 @@ static int smc_getname(struct socket *so
smc = smc_sk(sock->sk);
- return smc->clcsock->ops->getname(smc->clcsock, addr, peer);
+ mutex_lock(&smc->clcsock_release_lock);
+ if (smc->clcsock)
+ rc = smc->clcsock->ops->getname(smc->clcsock, addr, peer);
+ mutex_unlock(&smc->clcsock_release_lock);
+ return rc;
}
static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0463/1887] net: bridge: avoid recursive multicast port cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (461 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0462/1887] net/smc: protect clcsock lifetime in smc_getname Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0464/1887] net: dsa: microchip: fix KSZ8765 fiber detection Greg Kroah-Hartman
` (535 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zixuan Chai, Ren Wei,
David S. Miller
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zixuan Chai <petalzu987@gmail.com>
commit 5158353121bae4f552cb677ce8c5c3ef52f93a0d upstream.
br_multicast_sg_del_exclude_ports() removes automatically added STAR_EXCL
port groups by calling br_multicast_del_pg(). For S,G entries, that
deletion calls back into br_multicast_sg_del_exclude_ports(), so a large
number of STAR_EXCL ports consumes one kernel stack frame per port and can
hit the stack guard page.
Keep the complete port-group deletion path for cleanup, but suppress the
S,G exclude-port cleanup while that helper is already walking the same
entry. Normal deletion callers retain the existing behavior.
Fixes: 8266a0491e92 ("net: bridge: mcast: handle port group filter modes")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bridge/br_multicast.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -80,6 +80,10 @@ __br_multicast_add_group(struct net_brid
bool blocked);
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg);
+static void __br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp,
+ bool sg_del_exclude_ports);
static void __br_multicast_stop(struct net_bridge_mcast *brmctx);
static int br_mc_disabled_update(struct net_device *dev, bool value,
@@ -436,7 +440,7 @@ static void br_multicast_sg_del_exclude_
for (pp = &sgmp->ports;
(p = mlock_dereference(*pp, sgmp->br)) != NULL;) {
if (!(p->flags & MDB_PG_FLAGS_PERMANENT))
- br_multicast_del_pg(sgmp, p, pp);
+ __br_multicast_del_pg(sgmp, p, pp, false);
else
pp = &p->next;
}
@@ -675,9 +679,10 @@ static void br_multicast_destroy_port_gr
kfree_rcu(pg, rcu);
}
-void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
- struct net_bridge_port_group *pg,
- struct net_bridge_port_group __rcu **pp)
+static void __br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp,
+ bool sg_del_exclude_ports)
{
struct net_bridge *br = pg->key.port->br;
struct net_bridge_group_src *ent;
@@ -692,7 +697,8 @@ void br_multicast_del_pg(struct net_brid
if (!br_multicast_is_star_g(&mp->addr)) {
rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode,
br_sg_port_rht_params);
- br_multicast_sg_del_exclude_ports(mp);
+ if (sg_del_exclude_ports)
+ br_multicast_sg_del_exclude_ports(mp);
} else {
br_multicast_star_g_handle_mode(pg, MCAST_INCLUDE);
}
@@ -703,6 +709,13 @@ void br_multicast_del_pg(struct net_brid
mod_timer(&mp->timer, jiffies);
}
+void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp)
+{
+ __br_multicast_del_pg(mp, pg, pp, true);
+}
+
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg)
{
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0464/1887] net: dsa: microchip: fix KSZ8765 fiber detection
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (462 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0463/1887] net: bridge: avoid recursive multicast port cleanup Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0465/1887] net: usb: ax88179_178a: fix rx frame length for non-last packets Greg Kroah-Hartman
` (534 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Sebastien Royen,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastien Royen <sebastien.royen@armadeus.com>
commit fc13ba44da197a186f2f4d77c5b7d73d0f99f053 upstream.
The KSZ8765 is similar to the KSZ8795 but has two fiber ports.
KSZ8_PORT_STATUS_0 is used to detect fiber mode. It is currently
defined as 0x08, which is the Global Control 6 MIB Control register
and has bit 7 defined as Flush Counter.
Set KSZ8_PORT_STATUS_0 to 0x18, which is the Port 1 Status 0 register
where bit 7 is the Fiber Mode bit.
This issue was discovered when upgrading an embedded device from kernel
5.10 to 6.16. The device was using a KSZ8765 device tree configuration
and the corresponding hardware, but during boot the kernel incorrectly
detected it as a KSZ8795. The relevant boot messages were:
ksz-switch spi0.0: found switch: KSZ8795, rev 0
ksz-switch spi0.0: Device tree specifies chip KSZ8765 but found KSZ8795, please fix it!
Cc: stable@vger.kernel.org
Fixes: 91a98917a883 ("net: dsa: microchip: move switch chip_id detection to ksz_common")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Sebastien Royen <sebastien.royen@armadeus.com>
Link: https://patch.msgid.link/20261007080557.15719-1-sebastien.royen@armadeus.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/dsa/microchip/ksz_common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -552,7 +552,7 @@ static inline int is_lan937x(struct ksz_
#define KSZ87_FAMILY_ID 0x87
#define KSZ88_FAMILY_ID 0x88
-#define KSZ8_PORT_STATUS_0 0x08
+#define KSZ8_PORT_STATUS_0 0x18
#define KSZ8_PORT_FIBER_MODE BIT(7)
#define SW_CHIP_ID_M GENMASK(7, 4)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0465/1887] net: usb: ax88179_178a: fix rx frame length for non-last packets
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (463 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0464/1887] net: dsa: microchip: fix KSZ8765 fiber detection Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0466/1887] nvme: fix swapped ZRASF zone state values for full and read only Greg Kroah-Hartman
` (533 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fredrik Nyberg, Simon Horman,
Jakub Kicinski
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fredrik Nyberg <fredrik.nyberg@volvocars.com>
commit 9b6c20f788472d2042717a3c2f1bc60b2b77083e upstream.
Commit 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about
skb->truesize") replaced skb_clone() with a copy into a new skb for
every packet of a bulk-in transfer except the last one. The copy skips
the 2-byte IP alignment pseudo header but still copies pkt_len bytes,
and pkt_len includes that header. Each of these frames is therefore
delivered with two extra trailing bytes: the 0xeeee pseudo header of
the next slot when the frame ends on an 8-byte boundary, or slot
padding otherwise. The last packet is still trimmed to pkt_len - 2.
IPv4 and IPv6 trim the extra bytes, so most traffic is unaffected.
Anything that relies on the frame length is not. MACsec takes the ICV
from the last 16 bytes and drops every such frame as InPktsNotValid. In
our setup that was 0.2-1.2% of received MACsec frames, depending on how
many frames shared a transfer, including service discovery multicast.
Allocate and copy pkt_len - 2 bytes, like the last-packet path.
Fixes: 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about skb->truesize")
Cc: stable@vger.kernel.org
Signed-off-by: Fredrik Nyberg <fredrik.nyberg@volvocars.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261002-ax88179-rx-len-v1-1-f01a2a295079@volvocars.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/ax88179_178a.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1461,11 +1461,11 @@ static int ax88179_rx_fixup(struct usbne
return 1;
}
- ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len);
+ ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len - 2);
if (!ax_skb)
return 0;
- skb_put(ax_skb, pkt_len);
- memcpy(ax_skb->data, skb->data + 2, pkt_len);
+ skb_put(ax_skb, pkt_len - 2);
+ memcpy(ax_skb->data, skb->data + 2, pkt_len - 2);
ax88179_rx_checksum(ax_skb, pkt_hdr);
usbnet_skb_return(dev, ax_skb);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0466/1887] nvme: fix swapped ZRASF zone state values for full and read only
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (464 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0465/1887] net: usb: ax88179_178a: fix rx frame length for non-last packets Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0467/1887] openvswitch: fix soft lockup in the netlink flow dump Greg Kroah-Hartman
` (532 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Damien Le Moal, Karl Bonde Torp,
Andreas Hindborg, Keith Busch
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Bonde Torp <k.torp@samsung.com>
commit 564e46d9f6e87912effa03f123d37a511d520f09 upstream.
The Zone Management Receive command Zone Receive Action Specific (ZRASF)
reporting option values for the Full and Read Only zone states are swapped
compared to the NVM Express Zoned Namespace Command Set Specification,
Revision 1.5, Figure 35:
- 5h lists the zones in the ZSF:Full state.
- 6h lists the zones in the ZSRO:Read Only state.
The nvmet ZNS backend uses these constants to map the ZRASF value received
from the host to a block layer zone condition when filtering zones in
Report Zones. Because of the swap, a host asking for full zones was given
the read only zones, and a host asking for read only zones was given the
full zones.
Swap the values of NVME_ZRASF_ZONE_STATE_FULL and
NVME_ZRASF_ZONE_STATE_READONLY to match the specification.
Fixes: aaf2e048af27 ("nvmet: add ZBD over ZNS backend support")
Cc: stable@vger.kernel.org
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Karl Bonde Torp <k.torp@samsung.com>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/nvme.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1060,8 +1060,8 @@ enum {
NVME_ZRASF_ZONE_STATE_IMP_OPEN = 0x02,
NVME_ZRASF_ZONE_STATE_EXP_OPEN = 0x03,
NVME_ZRASF_ZONE_STATE_CLOSED = 0x04,
- NVME_ZRASF_ZONE_STATE_READONLY = 0x05,
- NVME_ZRASF_ZONE_STATE_FULL = 0x06,
+ NVME_ZRASF_ZONE_STATE_FULL = 0x05,
+ NVME_ZRASF_ZONE_STATE_READONLY = 0x06,
NVME_ZRASF_ZONE_STATE_OFFLINE = 0x07,
NVME_REPORT_ZONE_PARTIAL = 1,
};
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0467/1887] openvswitch: fix soft lockup in the netlink flow dump
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (465 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0466/1887] nvme: fix swapped ZRASF zone state values for full and read only Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0468/1887] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers Greg Kroah-Hartman
` (531 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Denis V. Lunev, Ilya Maximets,
David S. Miller
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis V. Lunev <den@openvz.org>
commit aaaaf87ea99b8766c9a8aa0e71aa42e6bc8a5320 upstream.
A production compute node carrying a few thousand datapath flows hit a
soft lockup inside a single netlink flow dump and panicked.
ovs_flow_cmd_dump() calls ovs_flow_stats_get() for every flow it
emits, and that releases stats->lock with spin_unlock_bh() once per
CPU that has touched the flow. Every release is a local_bh_enable(),
and each one runs the pending softirq backlog in the dumping thread's
own context.
The skb bounds the flows one callback emits, but not the softirq work
it absorbs. On a CPU that carries the box's packet load the backlog
refills as fast as it drains, so the dumping thread becomes that CPU's
softirq engine. It never sleeps and it has no reschedule point, so
under voluntary preemption nothing can take the CPU away from it:
neither the ksoftirqd the kernel woke to take the work over, nor the
stopper thread the softlockup detector dispatches to refresh its
timestamp.
Hold BH off across the whole callback instead, the way
ctnetlink_dump_table() does, so the nested spin_unlock_bh() stop
draining softirqs. The loop already runs under rcu_read_lock() and
cannot sleep. What it gives up is preemption under CONFIG_PREEMPT,
since a BH-off region is not preemptible outside PREEMPT_RT. The
region stays short: the skb caps the flows one callback emits, and
empty buckets cost no skb space but are each visited once per dump, as
the cursor only moves forward. The table grows on insert and shrinks
only on flush, so the walk is bounded by the largest flow count the
datapath has held. The softirq backlog the callback used to absorb has
no bound at all.
Fixes: 63e7959c4b9b ("openvswitch: Per NUMA node flow stats.")
Cc: stable@vger.kernel.org
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/datapath.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1476,6 +1476,12 @@ static int ovs_flow_cmd_dump(struct sk_b
return -ENODEV;
}
+ /*
+ * Not needed for safety. Stops every spin_unlock_bh() in
+ * ovs_flow_stats_get() from running the softirq backlog.
+ */
+ local_bh_disable();
+
ti = rcu_dereference(dp->table.ti);
for (;;) {
struct sw_flow *flow;
@@ -1496,6 +1502,8 @@ static int ovs_flow_cmd_dump(struct sk_b
cb->args[0] = bucket;
cb->args[1] = obj;
}
+
+ local_bh_enable();
rcu_read_unlock();
return skb->len;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0468/1887] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (466 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0467/1887] openvswitch: fix soft lockup in the netlink flow dump Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0469/1887] scsi: qedi: Initialize callback state before registration Greg Kroah-Hartman
` (530 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Abhishek Ojha, Mark Brown
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
commit 28c2388ee24cdbefbcc458fa41ef7bffaaa1cc83 upstream.
HRST (0x1e) and CLIRQ (0x1f) are write-only command strobes. Writing HRST
triggers a hard reset of the chip and writing CLIRQ clears the interrupt;
reading them returns nothing useful, and the read itself fires the command.
The result is that a plain register dump resets the board:
cat /sys/kernel/debug/regmap/2-003c/registers
walks every readable register, hits HRST, and the board reboots.
Split the callback back in two so HRST and CLIRQ stay writable but are no
longer readable. The readable range is left unchanged
(LTC3676_BUCK1 ... LTC3676_IRQSTAT).
Fixes: 37b918a034fe ("regulator: Add LTC3676 support")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
Link: https://patch.msgid.link/20260902010701.3360310-1-Abhishek.ojha@savoirfairelinux.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/regulator/ltc3676.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--- a/drivers/regulator/ltc3676.c
+++ b/drivers/regulator/ltc3676.c
@@ -232,7 +232,7 @@ static const struct regulator_desc ltc36
LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2),
};
-static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg)
+static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
@@ -243,6 +243,15 @@ static bool ltc3676_readable_writeable_r
return false;
}
+static bool ltc3676_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
+ return true;
+ }
+ return false;
+}
+
static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -255,8 +264,8 @@ static bool ltc3676_volatile_reg(struct
static const struct regmap_config ltc3676_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .writeable_reg = ltc3676_readable_writeable_reg,
- .readable_reg = ltc3676_readable_writeable_reg,
+ .writeable_reg = ltc3676_writeable_reg,
+ .readable_reg = ltc3676_readable_reg,
.volatile_reg = ltc3676_volatile_reg,
.max_register = LTC3676_CLIRQ,
.use_single_read = true,
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0469/1887] scsi: qedi: Initialize callback state before registration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (467 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0468/1887] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0470/1887] Bluetooth: hci_sock: Serialize dead-device detachment Greg Kroah-Hartman
` (529 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao,
Martin K. Petersen (Oracle)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 85de8b3a5eaa23d153aff4c7c83dddbc949064c9 upstream.
qedi_get_protocol_tlv_data() can be called asynchronously by QED after
qedi_ops->register_ops(). It takes stats_lock and reads ll2_mtu, but
__qedi_probe() currently registers the callback before initializing the
mutex and assigning the default MTU on the normal probe path.
Initialize the callback-visible state before registering qedi_cb_ops. Keep
the recovery path from reinitializing state because it reuses the existing
qedi context.
Fixes: 3cc5746e5ad7 ("scsi: qedi: Initialize the stats mutex lock")
Cc: stable@vger.kernel.org
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260910092405.1300129-1-runyu.xiao@seu.edu.cn
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qedi/qedi_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -2664,8 +2664,6 @@ retry_probe:
snprintf(host_buf, sizeof(host_buf), "host_%d", qedi->shost->host_no);
qedi_ops->common->set_name(qedi->cdev, host_buf);
- qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
-
memset(¶ms, 0, sizeof(params));
params.mtu = DEF_PATH_MTU + IPV6_HDR_LEN + TCP_HDR_LEN;
qedi->ll2_mtu = DEF_PATH_MTU;
@@ -2682,6 +2680,7 @@ retry_probe:
spin_lock_init(&qedi->task_idx_lock);
mutex_init(&qedi->stats_lock);
}
+ qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
qedi_ops->ll2->register_cb_ops(qedi->cdev, &qedi_ll2_cb_ops, qedi);
qedi_ops->ll2->start(qedi->cdev, ¶ms);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0470/1887] Bluetooth: hci_sock: Serialize dead-device detachment
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (468 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0469/1887] scsi: qedi: Initialize callback state before registration Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0471/1887] Bluetooth: MGMT: Fix status of pending commands flushed on power off Greg Kroah-Hartman
` (528 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 381a0925c556a8d91a80a9b9e3e86651d60ffee3 upstream.
Rebinding an HCI socket after its controller is unregistered can race
monitor control replay and crash the kernel. hci_sock_bind() clears
hci_pi(sk)->hdev and drops the device reference under only the socket
lock, whereas send_monitor_control_replay() holds hci_sk_list.lock for
reading.
Replay can observe a non-NULL hdev, then bind can clear it and drop the
last reference before create_monitor_ctrl_open() reads hdev->id. This
can cause a NULL pointer dereference if the pointer is reloaded, or a
use-after-free if the old pointer is retained.
The kernel reported:
KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f]
RIP: 0010:create_monitor_ctrl_open+0x579/0x800
Call Trace:
hci_sock_bind+0xd96/0x1190
__sys_bind+0x166/0x200
__x64_sys_bind+0x6d/0xb0
do_syscall_64+0xdd/0x4a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The same missing serialization lets hci_send_to_sock() select a socket
for the old device and queue its frame after bind has detached the socket
or installed a new binding.
Take hci_sk_list.lock for writing when clearing the device pointer and
resetting the socket state. This waits for existing replay and delivery
readers to finish before detachment and prevents later readers from
using the old binding. Keep hci_dev_put() outside the critical section
because the final device release can sleep.
Fixes: e04480920d1e ("Bluetooth: defer cleanup of resources in hci_unregister_dev()")
Cc: stable@vger.kernel.org
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_sock.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1161,8 +1161,10 @@ static int hci_sock_bind(struct socket *
*/
hdev = hci_pi(sk)->hdev;
if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+ write_lock(&hci_sk_list.lock);
hci_pi(sk)->hdev = NULL;
sk->sk_state = BT_OPEN;
+ write_unlock(&hci_sk_list.lock);
hci_dev_put(hdev);
}
hdev = NULL;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0471/1887] Bluetooth: MGMT: Fix status of pending commands flushed on power off
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (469 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0470/1887] Bluetooth: hci_sock: Serialize dead-device detachment Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0472/1887] Bluetooth: RFCOMM: free the skb when the DLC has no owner Greg Kroah-Hartman
` (527 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iaroslav Voitovych,
Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
commit 86ef0f58bdecdedb3a1240971c56d71b7e4ce3fc upstream.
cmd_complete_rsp() receives a struct cmd_lookup and, for a pending
command that has no cmd_complete callback, falls through to
cmd_status_rsp(cmd, data). cmd_status_rsp() reads data as a u8 *, so
the status sent comes from the first byte of match->sk's
representation, not from match->mgmt_status.
commit f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on
mgmt_index_removed") changed the callers' data from &status to &match
and updated the cmd_complete branch to match->mgmt_status, but left
the fall-through passing data unchanged.
In mgmt_index_removed() match->sk is NULL, so every such command is
answered with status 0x00 (Success) instead of
MGMT_STATUS_INVALID_INDEX. In __mgmt_power_off() it is NULL too,
unless a Set Powered command was pending: then settings_rsp() has
stored that command's socket in match->sk, and the byte sent comes
from the socket pointer. Either way the status the caller set,
MGMT_STATUS_NOT_POWERED (or MGMT_STATUS_INVALID_INDEX when the device
is being unregistered), is lost.
Pass the status the callers set.
This was seen on a QCA9377 laptop: bluetoothd's Start Discovery,
pending when the adapter was powered off, was answered with Command
Status 0x00 and no parameters, and bluetoothd 5.72 crashed on the
zero-length success. BlueZ master has since added the length check
on that path ("adapter: Fix crash on short start discovery reply",
BlueZ a734b06059cb), but userspace should still be told Not Powered,
not Success.
Tested on Ubuntu 7.0.0-31 with a virtual controller (hci_vhci):
power off is held in HCI Write Scan Enable while a Start Discovery is
submitted, and the flush answers it with status 0x00 before this
change and 0x0f (Not Powered) after.
Fixes: f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on mgmt_index_removed")
Cc: stable@vger.kernel.org
Signed-off-by: Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/mgmt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1453,7 +1453,7 @@ static void cmd_complete_rsp(struct mgmt
return;
}
- cmd_status_rsp(cmd, data);
+ cmd_status_rsp(cmd, &match->mgmt_status);
}
static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0472/1887] Bluetooth: RFCOMM: free the skb when the DLC has no owner
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (470 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0471/1887] Bluetooth: MGMT: Fix status of pending commands flushed on power off Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0473/1887] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown Greg Kroah-Hartman
` (526 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Gavrilov, Maxim Skokov,
Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxim Skokov <skokovmaksimevg@gmail.com>
commit 9d1afbf60ed53c5b051cd124153e0ae3078c8b93 upstream.
rfcomm_recv_data() hands the skb to d->data_ready() and returns 0
without freeing it, so the callback owns the skb from that point on.
The tty implementation frees it when the DLC has been detached from its
device:
static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc,
struct sk_buff *skb)
{
struct rfcomm_dev *dev = dlc->owner;
if (!dev) {
kfree_skb(skb);
return;
}
The socket implementation returns without freeing it, and the skb is
leaked.
A connected DLC can have no owner: rfcomm_sock_destruct() clears
d->owner, while the DLC itself stays on the session until it is closed.
Data frames that arrive in that window still find d->state ==
BT_CONNECTED in rfcomm_recv_data() and are handed to the callback, one
leaked skb each.
The leak does not stop on its own either. The remote runs out of
credits only once RFCOMM_RX_THROTTLED is set, and for a socket the only
place that sets it is rfcomm_sk_data_ready() itself, below the return.
rfcomm_process_dlcs() keeps granting credits, so the remote keeps
sending and the leak keeps growing.
Free the skb, as the tty side does.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Closes: https://lore.kernel.org/linux-bluetooth/CABXGCsPe5wykd8Aj-hm+SJ7SGQyb8yoGNnx3XDpPmBathj+EGg@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Assisted-by: Claude:claude-opus-5
Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/sock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -50,8 +50,11 @@ static void rfcomm_sock_kill(struct sock
static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
{
struct sock *sk = d->owner;
- if (!sk)
+
+ if (!sk) {
+ kfree_skb(skb);
return;
+ }
atomic_add(skb->len, &sk->sk_rmem_alloc);
skb_queue_tail(&sk->sk_receive_queue, skb);
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0473/1887] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (471 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0472/1887] Bluetooth: RFCOMM: free the skb when the DLC has no owner Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0474/1887] drm/gud: dont keep a connector without a CRTC as connector_state Greg Kroah-Hartman
` (525 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4a807caf7680652d53b6,
Palla Raghunath, Luiz Augusto von Dentz
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Palla Raghunath <raghunathpalla.0209@gmail.com>
commit 08e90633377f1b2567ab5ad6810b74c552246a07 upstream.
syzbot hit a NULL pointer dereference in rfcomm_dev_shutdown() when an
RFCOMM tty is closed.
rfcomm_dev_add() puts the new device on rfcomm_dev_list first and only
then registers the tty device and saves it in dev->tty_dev. If that
registration fails, dev->tty_dev is never set at all. The device can be
looked up in the meantime, so an open() of /dev/rfcommN gets through
rfcomm_tty_install() and attaches to it. When that tty is closed again,
rfcomm_dev_shutdown() uses dev->tty_dev without checking it:
Oops: general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000040-0x0000000000000047]
RIP: 0010:rfcomm_dev_shutdown+0x48/0xb0 net/bluetooth/rfcomm/tty.c:131
Call Trace:
tty_port_shutdown+0x1bf/0x220 drivers/tty/tty_port.c:372
tty_port_close+0x4e/0x150 drivers/tty/tty_port.c:705
tty_release+0x359/0x1670 drivers/tty/tty_io.c:1718
__fput+0x418/0xa50 fs/file_table.c:512
rfcomm_dev_destruct() already copes with a NULL dev->tty_dev. Add the
same check to rfcomm_dev_shutdown(), so the tty device is only moved
when it was actually registered.
Fixes: cad348a17e17 ("Bluetooth: Implement .activate, .shutdown and .carrier_raised methods")
Reported-by: syzbot+4a807caf7680652d53b6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4a807caf7680652d53b6
Cc: stable@vger.kernel.org
Signed-off-by: Palla Raghunath <raghunathpalla.0209@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/tty.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -131,7 +131,7 @@ static void rfcomm_dev_shutdown(struct t
{
struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
- if (dev->tty_dev->parent)
+ if (dev->tty_dev && dev->tty_dev->parent)
device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
/* close the dlc */
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0474/1887] drm/gud: dont keep a connector without a CRTC as connector_state
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (472 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0473/1887] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0475/1887] drm/i915/gem: Prevent overstepping exec array boundary Greg Kroah-Hartman
` (524 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sajal Gupta, Ruben Wauters
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sajal Gupta <sajal2005gupta@gmail.com>
commit 71ec70ea26e399eb8371fe9d2d5bf5dab09570fb upstream.
If the 'for_each_new_connector_in_state()' loop finishes without
hitting the break, connector_state is left pointing at the last
connector visited, which has no CRTC, instead of
staying NULL.
That skips the "if (!connector_state)" fallback below the loop, which
looks up the active connector when the state contains none. The
function then carries on with a connector that is not driven.
Fix by resetting connector_state to NULL for each connector visited that
has no CRTC, so that it is NULL when none was found and the fallback runs.
Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260902123254.36987-1-sajal2005gupta@gmail.com?part=1
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260922084026.15481-1-sajal2005gupta@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/gud/gud_pipe.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -489,6 +489,7 @@ int gud_pipe_check(struct drm_simple_dis
for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc)
break;
+ connector_state = NULL;
}
/*
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0475/1887] drm/i915/gem: Prevent overstepping exec array boundary
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (473 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0474/1887] drm/gud: dont keep a connector without a CRTC as connector_state Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0476/1887] drm/i915/gt: Unmask interrupts only when ACTIVE is true Greg Kroah-Hartman
` (523 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Krzysztof Karas, Andi Shyti,
Jani Nikula
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <krzysztof.karas@intel.com>
commit ebe162db655881a38de43301151ff7ac940602b5 upstream.
It is possible for eb_relocate_parse_slow() to call kvfree() on
entries outside the original exec array during following
scenario inside eb_relocate_parse_slow():
1) eb_copy_relocations() allocates as many as eb->buffer_count
copies for exec entries;
2) eb_parse() appends up to two VMAs, right after incrementing
eb->buffer_count;
3) cleanup under "out" label uses this incremented buffer_count
to release relocation pointers from exec array via kvfree(),
not from VMA array.
To amend this problem, ensure that relocation cleanup uses the
original exec object count, excluding the VMAs appended by the
command parser.
Fixes: 8e4ba491b0ba ("drm/i915: Parse command buffer earlier in eb_relocate(slow)")
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Assisted-by: GitHub-Copilot:gpt-6-astra
Cc: stable@vger.kernel.org # 5.10+
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260911061145.3535489-1-krzysztof.karas@intel.com
(cherry picked from commit 2a0158925fb943c7ba8f3216e2734952128defc9)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1752,6 +1752,7 @@ static int eb_reinit_userptr(struct i915
static noinline int eb_relocate_parse_slow(struct i915_execbuffer *eb)
{
+ const unsigned int count = eb->buffer_count;
bool have_copy = false;
struct eb_vma *ev;
int err = 0;
@@ -1854,7 +1855,6 @@ err:
out:
if (have_copy) {
- const unsigned int count = eb->buffer_count;
unsigned int i;
for (i = 0; i < count; i++) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0476/1887] drm/i915/gt: Unmask interrupts only when ACTIVE is true
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (474 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0475/1887] drm/i915/gem: Prevent overstepping exec array boundary Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0477/1887] drm/vc4: drain the hangcheck timer and works on V3D unbind Greg Kroah-Hartman
` (522 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Krzysztof Karas, Andi Shyti,
Jani Nikula
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <krzysztof.karas@intel.com>
commit 5346b1cec6afa4f9b4b49a9f84e3cfef95a3f7bb upstream.
There is a small race window between intel_rps_boost() reading
a stale ACTIVE state and queuing rps->work, where ACTIVE may be
changed via asynchronous calls triggered by wakeref drop.
This means that rps_work() could be triggered after the GT has
been parked, so unmasking RPS PM interrupts would happen without
holding PM wakelock. This sequence of events may be observed
during live_rc6_ctx_wa() selftest:
1) live_rc6_ctx_wa()
-> intel_engine_pm_put()
-> wakeref_put()
ASYNC1) wakeref_put() callback
-> __engine_park()
-> intel_gt_pm_put_async()
-> intel_gt_pm_put_async_untracked()
-> intel_wakeref_put_async()
ASYNC2) wakeref_put_async() callback
-> __gt_park()
-> intel_rps_park()
-> intel_rps_clear_active() [clear ACTIVE]
WITH INTERRUPTS:
-> rps_disable_interrupts()
-> cancel_work_sync(rps->work)
-> rps_reset_interrupts() [rps->pm_iir = 0]
WITHOUT INTERRUPTS (TIMER mode):
-> rps_stop_timer()
-> cancel_work_sync(rps->work)
2) live_rc6_ctx_wa()
-> intel_gt_wait_for_idle()
-> intel_gt_retire_requests_timeout()
-> dma_fence_wait_timeout()
-> ops->wait() [i915_fence_wait()]
-> i915_request_wait_timeout()
-> intel_rps_boost()
-> intel_rps_is_active() [check ACTIVE]
[OPEN RACE WINDOW]
-> queue_work(rps->work)
-> retire_requests()
-> i915_request_retire()
-> intel_rps_dec_waiters() [from 1 to 0]
If ASYNC1 and ASYNC2 would execute during [OPEN RACE WINDOW],
then:
3) rps_work() executes from the workqueue and may satisfy
"(!pm_iir && !client_boost)" test (in TIMER mode rps->pm_iir
is zeroed by an earlier rps_work() call or never gets a new
value after previous intel_rps_unpark() event), so it jumps
to "out" label, bypassing intel_rps_is_active() guard and
executes gen6_gt_pm_unmask_irq();
4) GT is parked and runtime PM wakelock is dropped, so only
a raw reference in __gt_park() ->
intel_display_power_put_async() remains for 100ms, then the
MMIO write in gen6_gt_pm_unmask_irq() detects missing
wakelock via assert_rpm_wakelock_held() and emits
"RPM wakelock ref not held during HW access" tainting kernel.
Commit 3e7abf814193 ("drm/i915: Extract GT render power state management")
dropped the "if (rps->interrupts_enabled)" guard that
gen6_pm_rps_work() had around this unmask in i915_irq.c.
INTEL_RPS_ACTIVE brackets the same window, since it is set in
intel_rps_unpark() before rps_enable_interrupts() and
rps_start_timer() and cleared in intel_rps_park() before
rps_stop_timer() and rps_disable_interrupts().
Skip unmasking when RPS is no longer active (reaching unmask
operation is independent of INTERRUPT mode). This does not
prevent RPS operation from resuming on the next unpark.
In interrupt mode, intel_rps_unpark() calls
rps_enable_interrupts(), which enables and unmasks the PM
interrupts. In timer mode, it calls rps_start_timer(),
restarting periodic engine-busyness evaluation. The timer
generates software RPS events and queues rps_work() directly,
independently of PM interrupt delivery. Neither mode requires
the late worker to unmask interrupts while the GT is parked
Fixes: 3e7abf814193 ("drm/i915: Extract GT render power state management")
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16562
Cc: stable@vger.kernel.org # v5.5+
Assisted-by: GitHub-Copilot:claude-opus-5
Assisted-by: GitHub-Copilot:gpt-6-astra
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260910081329.3300417-1-krzysztof.karas@intel.com
(cherry picked from commit ca4a6deadad15b91ee083afe445fa6bdbfb68206)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/gt/intel_rps.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -1874,7 +1874,8 @@ static void rps_work(struct work_struct
out:
spin_lock_irq(gt->irq_lock);
- gen6_gt_pm_unmask_irq(gt, rps->pm_events);
+ if (intel_rps_is_active(rps))
+ gen6_gt_pm_unmask_irq(gt, rps->pm_events);
spin_unlock_irq(gt->irq_lock);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0477/1887] drm/vc4: drain the hangcheck timer and works on V3D unbind
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (475 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0476/1887] drm/i915/gt: Unmask interrupts only when ACTIVE is true Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0478/1887] drm/amdgpu: make Mac FB workaround generic Greg Kroah-Hartman
` (521 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Maíra Canal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 94cf5971b1d04c6382437387c4dc3836cc7a1437 upstream.
Nothing stops the hangcheck timer that submitted jobs arm, or the
job_done_work that the render-done interrupt queues, at teardown:
vc4_irq_disable() cancels only overflow_mem_work, and vc4_gem_destroy()
runs from the drm-managed release, after vc4_v3d_unbind() has already
uninstalled the V3D interrupt and cleared vc4->v3d. A timer still armed
by then reads V3D registers through the NULL vc4->v3d pointer, and the
late callbacks run on the vc4_dev embedding them after it has been
freed.
Drain them in vc4_v3d_unbind(): shut the timer down and cancel
reset_work before the interrupt is taken down, because its
vc4_irq_reset() re-enables it, then flush job_done_work so that
completions queued at teardown still release their jobs.
This issue was found by an in-house static analysis tool.
Fixes: d5b1a78a772f ("drm/vc4: Add support for drawing 3D frames.")
Cc: stable@vger.kernel.org # 6.2+
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260915095103.156007-1-fanwu01@zju.edu.cn
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/vc4/vc4_v3d.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -9,6 +9,7 @@
#include <linux/component.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/timer.h>
#include "vc4_drv.h"
#include "vc4_regs.h"
@@ -513,8 +514,15 @@ static void vc4_v3d_unbind(struct device
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
+ /* A straggler vc4_reset() re-enables the interrupt. */
+ timer_shutdown_sync(&vc4->hangcheck.timer);
+ cancel_work_sync(&vc4->hangcheck.reset_work);
+
vc4_irq_uninstall(drm);
+ /* Flush rather than cancel, so queued completions release their jobs. */
+ flush_work(&vc4->job_done_work);
+
/* Disable the binner's overflow memory address, so the next
* driver probe (if any) doesn't try to reuse our old
* allocation.
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0478/1887] drm/amdgpu: make Mac FB workaround generic
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (476 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0477/1887] drm/vc4: drain the hangcheck timer and works on V3D unbind Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0479/1887] fs: refuse fspick() on internal superblocks Greg Kroah-Hartman
` (520 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ayhan Çiçek, Alex Deucher
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <alexander.deucher@amd.com>
commit c7f44ec5c4ec760e74351f1843dcb8322f67cbf6 upstream.
Rather than adding a case of every chip where this is seen
just check if the FB is at 0 and the ssid is apple. This
should cover all chips which fall into this case.
Tested-by: Ayhan Çiçek <ayhancicek@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c54e4d10507722398dc90cf3c532e50b86cf425a)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -652,20 +652,17 @@ void amdgpu_gmc_get_vbios_allocations(st
case CHIP_RENOIR:
adev->mman.keep_stolen_vga_memory = true;
break;
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_POLARIS12:
- /* MacBookPros with switchable graphics put VRAM at 0 when
- * the iGPU is enabled which results in cursor issues if
- * the cursor ends up at 0. Reserve vram at 0 in that case.
- */
- if (adev->gmc.vram_start == 0)
- adev->mman.keep_stolen_vga_memory = true;
- break;
default:
adev->mman.keep_stolen_vga_memory = false;
break;
}
+ /* MacBookPros with switchable graphics put VRAM at 0 when
+ * the iGPU is enabled which results in cursor issues if
+ * the cursor ends up at 0. Reserve vram at 0 in that case.
+ */
+ if ((adev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+ (adev->gmc.vram_start == 0))
+ adev->mman.keep_stolen_vga_memory = true;
if (amdgpu_sriov_vf(adev) ||
!amdgpu_device_has_display_hardware(adev)) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0479/1887] fs: refuse fspick() on internal superblocks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (477 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0478/1887] drm/amdgpu: make Mac FB workaround generic Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0480/1887] namespace: check a submount for references right before unmounting it Greg Kroah-Hartman
` (519 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 02587a4af82adccaef8e3b3624b4e7f1c401632d upstream.
There's a few instances where a internal superblock is reachable by
fspick(). Block that. graft_tree() and fsmount() already refuse them.
fanotify refuses mount and superblock marks on them for the same reason.
Fixes: cf3cba4a429b ("vfs: syscall: Add fspick() to select a superblock for reconfiguration")
Cc: stable@vger.kernel.org # v5.2+
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-6-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fsopen.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/fsopen.c
+++ b/fs/fsopen.c
@@ -191,6 +191,9 @@ SYSCALL_DEFINE3(fspick, int, dfd, const
ret = -EINVAL;
if (target.mnt->mnt_root != target.dentry)
goto err_path;
+ /* kernel-internal superblocks are nobody's to reconfigure */
+ if (target.dentry->d_sb->s_flags & SB_NOUSER)
+ goto err_path;
fc = fs_context_for_reconfigure(target.dentry, 0, 0);
if (IS_ERR(fc)) {
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0480/1887] namespace: check a submount for references right before unmounting it
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (478 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0479/1887] fs: refuse fspick() on internal superblocks Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0481/1887] dcache: dont put a mountpoint on a dentry thats being removed Greg Kroah-Hartman
` (518 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 32bf92416614a1e3ff3524fc6b780259c7aad3ef upstream.
shrink_submounts() and mark_mounts_for_expiry() first collect all the
mounts they are allowed to unmount and then unmount them.
Whether a mount is busy is decided by propagate_mount_busy() on the
tree. But unmounting the first mount changes the tree that the second
one propagates into. propagate_umount()
moves a surviving overmount off a copy it unmounts and mounts it where
the copy was mounted. If that's where the propagated copy of the second
victim is looked up the overmount becomes a candidate of the second
umount_tree(). It's childless and so trim_one() commits it without
looking at its reference count.
So a synchronous umount pulls out a busy mount that is in use somewhere
else and marks it MNT_SYNC_UMOUNT while it has users:
umount2(/tmp/plshrink/p1, 0) = 0 errno 0
cwd is (unreachable)
The same two umounts requested one after the other fail with EBUSY.
This needs a mount with MNT_SHRINKABLE, i.e., automounted submounts of
NFS, AFS and CIFS or the tracefs mount below debugfs. Bind mounts
inherit the flag.
Check each mount right before it is unmounted under the same hold of
namespace_sem and mount_lock as the umount itself. Make sure that the
algorithm stays linear.
Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-2-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 78 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 53 insertions(+), 25 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3198,6 +3198,11 @@ void mark_mounts_for_expiry(struct list_
}
while (!list_empty(&graveyard)) {
mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
+ /* an earlier umount_tree() may have moved a busy mount here */
+ if (propagate_mount_busy(mnt, 1)) {
+ list_move(&mnt->mnt_expire, mounts);
+ continue;
+ }
touch_mnt_namespace(mnt->mnt_ns);
umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
}
@@ -3208,16 +3213,36 @@ void mark_mounts_for_expiry(struct list_
EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
/*
+ * Unmount @mnt if it's a shrinkable mount without children that nobody uses.
+ *
+ * mount_lock must be held for write
+ */
+static bool shrink_submount(struct mount *mnt)
+{
+ if (propagate_mount_busy(mnt, 1))
+ return false;
+ touch_mnt_namespace(mnt->mnt_ns);
+ umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
+ return true;
+}
+
+/*
* Ripoff of 'select_parent()'
*
- * search the list of submounts for a given mountpoint, and move any
- * shrinkable submounts to the 'graveyard' list.
+ * unmount the shrinkable submounts of @parent that aren't busy, children
+ * before their parent, and say whether anything went
+ *
+ * The cursor into the children of @this_parent survives the umount of a
+ * child mount without child mounts. The mounts that get umounted together with
+ * it are located under receiving mounts of @this_parent and never under
+ * @this_parent itself. The one exception is @this_parent getting unmounted
+ * then the walk starts over.
*/
-static int select_submounts(struct mount *parent, struct list_head *graveyard)
+static bool __shrink_submounts(struct mount *parent)
{
struct mount *this_parent = parent;
struct list_head *next;
- int found = 0;
+ bool shrunk = false;
repeat:
next = this_parent->mnt_mounts.next;
@@ -3236,42 +3261,45 @@ resume:
this_parent = mnt;
goto repeat;
}
-
- if (!propagate_mount_busy(mnt, 1)) {
- list_move_tail(&mnt->mnt_expire, graveyard);
- found++;
- }
+ if (!shrink_submount(mnt))
+ continue;
+ shrunk = true;
+ if (unlikely(this_parent->mnt.mnt_flags & MNT_UMOUNT))
+ return true;
}
/*
* All done at this level ... ascend and resume the search
*/
if (this_parent != parent) {
- next = this_parent->mnt_child.next;
- this_parent = this_parent->mnt_parent;
+ struct mount *mnt = this_parent;
+
+ next = mnt->mnt_child.next;
+ this_parent = mnt->mnt_parent;
+ /* its children are gone, maybe it can go as well */
+ if (shrink_submount(mnt)) {
+ shrunk = true;
+ if (unlikely(this_parent->mnt.mnt_flags & MNT_UMOUNT))
+ return true;
+ }
goto resume;
}
- return found;
+ return shrunk;
}
/*
- * process a list of expirable mountpoints with the intent of discarding any
- * submounts of a specific parent mountpoint
+ * unmount the shrinkable submounts of @mnt that aren't busy
+ *
+ * The busy check and the umount of a mount are adjacent. An umount can
+ * still empty or move a mount in a part of the tree that was walked
+ * already, so walk again until nothing goes.
*
* mount_lock must be held for write
*/
static void shrink_submounts(struct mount *mnt)
{
- LIST_HEAD(graveyard);
- struct mount *m;
-
- /* extract submounts of 'mountpoint' from the expiration list */
- while (select_submounts(mnt, &graveyard)) {
- while (!list_empty(&graveyard)) {
- m = list_first_entry(&graveyard, struct mount,
- mnt_expire);
- touch_mnt_namespace(m->mnt_ns);
- umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC);
- }
+ for (;;) {
+ if (!__shrink_submounts(mnt))
+ break;
}
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0481/1887] dcache: dont put a mountpoint on a dentry thats being removed
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (479 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0480/1887] namespace: check a submount for references right before unmounting it Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0482/1887] namespace: refuse an automount below a mount that is in no namespace Greg Kroah-Hartman
` (517 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 75f4197f1e11d2eb75c2d6f916a7d4764db621e5 upstream.
rmdir(), unlink() and rename() call dont_mount() on the victim and then
detach_mounts() with the victim's inode locked. do_lock_mount() takes
the inode lock of the mountpoint and checks cant_mount() so a mount
can't show up after detach_mounts().
But attach_recursive_mnt() makes a second mountpoint for the root of the
source mount so that the mounts already located at the destination can
be put on top of it. No inode is locked for that one and d_set_mounted()
only refuses a dentry that is unlinked. Between detach_mounts() and
d_delete() the victim is still hashed:
rmrace: b passed dont_mount() and detach_mounts(), sleeping
T2: move_mount(S, /tmp/plcant/x, BENEATH) = 0 errno 0 ()
T1: rmdir(/tmp/plcant/d/b) = 0 errno 0
109 107 0:61 /d/b//deleted /tmp/plcant/x rw,relatime - tmpfs tmpfs rw
108 109 0:63 / /tmp/plcant/x rw,relatime - tmpfs T rw
A bind mount of the directory that's being removed is moved beneath an
existing mount while the rmdir() is located between the two calls. The
mount ends up on the removed directory and nothing will ever detach it.
Check cant_mount() in d_set_mounted() as well. dont_mount() raises the
flag under d_lock before detach_mounts() runs so either the mountpoint
is set first and detach_mounts() finds the mount or the flag is seen and
the mount is refused.
Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-15-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/dcache.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1502,6 +1502,8 @@ EXPORT_SYMBOL(path_has_submounts);
*
* Only one of d_invalidate() and d_set_mounted() must succeed. For
* this reason take rename_lock and d_lock on dentry and ancestors.
+ * Likewise for dont_mount() which marks a dentry that is being removed
+ * under d_lock.
*/
int d_set_mounted(struct dentry *dentry)
{
@@ -1518,7 +1520,7 @@ int d_set_mounted(struct dentry *dentry)
spin_unlock(&p->d_lock);
}
spin_lock(&dentry->d_lock);
- if (!d_unlinked(dentry)) {
+ if (!d_unlinked(dentry) && !cant_mount(dentry)) {
ret = -EBUSY;
if (!d_mountpoint(dentry)) {
dentry->d_flags |= DCACHE_MOUNTED;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0482/1887] namespace: refuse an automount below a mount that is in no namespace
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (480 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0481/1887] dcache: dont put a mountpoint on a dentry thats being removed Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:42 ` [PATCH 6.1 0483/1887] drm/dp: dont mark the AUX backlight enabled when enabling failed Greg Kroah-Hartman
` (516 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit ba985ce08471c555af2a2fbe217c1bc2e72a6d8c upstream.
It's possible to add autmounts even when the parent mount isn't in the
mount namespace of the caller. The only requirement we have is that the
parent mount namespace must not be NULL, i.e., unmounted.
Problem is that clone_private_mount() has MNT_NS_INTERNAL which makes
that trivially true. So that passes the test and attach_recursive_mnt()
accepts that as a mount point and funny enough, count_mounts()
dereferences MNT_NS_INTERNAL. The problem is it is an error pointer...
So we can reach this in userspace via fanotify. A filesystem mark on the
lower filesystem of an overlay reports paths on the layer clone and
reading the event hands out a descriptor on it. For example with debugfs
as the lower layer it goes kaboom:
openat(evfd, "tracing", O_DIRECTORY)
Oops: general protection fault
KASAN: null-ptr-deref in range [0x1d0-0x1d7]
RIP: 0010:count_mounts+0x35/0x200
attach_recursive_mnt
finish_automount
And since that sleeping beauty happens under namespace_sem held for
writing every mount operation on the system blocks from then on.
Congrats.
Use is_mounted() instead which rejects unmounted and internal mounts
alike. The open fails with EINVAL just as it did before
clone_private_mount() used MNT_NS_INTERNAL.
Fixes: df820f8de4e4 ("ovl: make private mounts longterm")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-5-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2965,7 +2965,7 @@ static int do_add_mount(struct mount *ne
if (!(mnt_flags & MNT_SHRINKABLE))
return -EINVAL;
/* ... and for those we'd better have mountpoint still alive */
- if (!parent->mnt_ns)
+ if (!is_mounted(&parent->mnt))
return -EINVAL;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0483/1887] drm/dp: dont mark the AUX backlight enabled when enabling failed
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (481 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0482/1887] namespace: refuse an automount below a mount that is in no namespace Greg Kroah-Hartman
@ 2026-10-28 16:42 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0484/1887] gpio: exar: initialize the ID before registering its cleanup Greg Kroah-Hartman
` (515 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleg Keri, Douglas Anderson,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Keri <okerixx@gmail.com>
[ Upstream commit 707ce102521496c67860d81221b20c56d8255f2f ]
If drm_edp_backlight_enable() fails, dp_aux_backlight_update_status()
still marks the backlight as enabled. From then on every brightness
change only updates the level and the enable is never retried, so the
panel stays dark until something blanks and unblanks the backlight.
Return the error instead, so the next update tries to enable again.
Fixes: 10f7b40e4f30 ("drm/panel: add basic DP AUX backlight support")
Signed-off-by: Oleg Keri <okerixx@gmail.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patch.msgid.link/20260925132558.27518-1-okerixx@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/display/drm_dp_helper.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 14dcaca0d8c14..74fd93180f700 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -3843,7 +3843,9 @@ static int dp_aux_backlight_update_status(struct backlight_device *bd)
if (!backlight_is_blank(bd)) {
if (!bl->enabled) {
- drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ ret = drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ if (ret)
+ return ret;
bl->enabled = true;
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0484/1887] gpio: exar: initialize the ID before registering its cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (482 preceding siblings ...)
2026-10-28 16:42 ` [PATCH 6.1 0483/1887] drm/dp: dont mark the AUX backlight enabled when enabling failed Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0485/1887] drm/aspeed: Balance the display clock enable on teardown Greg Kroah-Hartman
` (514 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Linus Walleij, Bartosz Golaszewski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4d69e74034b208588636ecc177e0dd43a7696af3 ]
devm_add_action_or_reset() invokes the cleanup action immediately when
registering the action fails. gpio_exar_probe() currently stores the
allocated ID in exar_gpio only after registering the action, so that
failure makes exar_devm_ida_free() release ID 0. If the allocated ID is
nonzero, this leaks that ID and can free ID 0 belonging to another device.
Store the ID before registering the cleanup action so both the immediate
failure path and normal device teardown release the correct allocation.
Fixes: 5300ebb695fa ("gpio: exar: use devm action for freeing the IDA and drop remove()")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/179070265834.12871.48183786512201899.idr-bug-79@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpio/gpio-exar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c
index e641bc96c4e71..0096f8a9377bd 100644
--- a/drivers/gpio/gpio-exar.c
+++ b/drivers/gpio/gpio-exar.c
@@ -196,6 +196,7 @@ static int gpio_exar_probe(struct platform_device *pdev)
index = ida_alloc(&ida_index, GFP_KERNEL);
if (index < 0)
return index;
+ exar_gpio->index = index;
ret = devm_add_action_or_reset(dev, exar_devm_ida_free, exar_gpio);
if (ret)
@@ -211,7 +212,6 @@ static int gpio_exar_probe(struct platform_device *pdev)
exar_gpio->gpio_chip.set = exar_set_value;
exar_gpio->gpio_chip.base = -1;
exar_gpio->gpio_chip.ngpio = ngpios;
- exar_gpio->index = index;
exar_gpio->first_pin = first_pin;
ret = devm_gpiochip_add_data(dev, &exar_gpio->gpio_chip, exar_gpio);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0485/1887] drm/aspeed: Balance the display clock enable on teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (483 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0484/1887] gpio: exar: initialize the ID before registering its cleanup Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0486/1887] drm/vc4: Free the BO cache size list " Greg Kroah-Hartman
` (513 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Thomas Zimmermann, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit ecce445c6489895463b7ddec2af66338287fee4c ]
aspeed_gfx_load() enables the display clock without checking the return
value and never disables it on probe failure or removal. devm_clk_get()
only releases the clock reference, leaving the enable unbalanced.
Use devm_clk_get_enabled() to handle enable failures and automatically
disable and unprepare the clock on probe failure or removal.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: 4f2a8f5898ec ("drm: Add ASPEED GFX driver")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Assisted-by: OpenAI:GPT-5.6
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260913223019.89651-1-mhun512@gmail.com
Link: https://patch.msgid.link/20260905080426.34224-1-kmehltretter@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index a94f1a9e8f409..79f67413c1175 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -194,13 +194,12 @@ static int aspeed_gfx_load(struct drm_device *drm)
}
reset_control_deassert(priv->rst);
- priv->clk = devm_clk_get(drm->dev, NULL);
+ priv->clk = devm_clk_get_enabled(drm->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev,
- "missing or invalid clk device tree entry");
+ "failed to get and enable clock\n");
return PTR_ERR(priv->clk);
}
- clk_prepare_enable(priv->clk);
/* Sanitize control registers */
writel(0, priv->base + CRT_CTRL1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0486/1887] drm/vc4: Free the BO cache size list on teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (484 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0485/1887] drm/aspeed: Balance the display clock enable on teardown Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0487/1887] net/sched: em_text: reject unterminated algo before autoload Greg Kroah-Hartman
` (512 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thadeu Lima de Souza Cascardo,
Maíra Canal, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit b41ff8b529278216cba22a5dcdc93fea2a3a9619 ]
vc4_bo_cache_destroy() purges the cached BOs but never frees the size
list, leaking it on every unbind.
Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
Assisted-by: LLM
Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Link: https://patch.msgid.link/20260930190721.1897264-1-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_bo.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 9028a56dd12b8..d687afb3c4426 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -1054,6 +1054,7 @@ static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused)
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
+ kfree(vc4->bo_cache.size_list);
for (i = 0; i < vc4->num_labels; i++) {
if (vc4->bo_labels[i].num_allocated) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0487/1887] net/sched: em_text: reject unterminated algo before autoload
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (485 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0486/1887] drm/vc4: Free the BO cache size list " Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0488/1887] amt: send the relays General Query directly from the receive path Greg Kroah-Hartman
` (511 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (gemini), Jamal Hadi Salim,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit c9728fcf2e7fb4a7a8d08ebd9524c3b02ae1a021 ]
This is a follow-up to commit 9c572a83037a ("net/sched: fix potential
stack infoleak in em_text_dump()"), which zero-initialised the dump-side
struct. Sashiko pointed at a pre-existing bug that exposed the change-side
input-validation gap open.
em_text_change() casts the raw netlink attribute payload to struct
tcf_em_text and passes conf->algo, a 16-byte array with no enforced NUL
terminator, to textsearch_prepare(). On the TS_AUTOLOAD retry
textsearch_prepare() calls request_module("ts_%s", algo); vsnprintf()
walks %s until it finds a NUL, so an algo[] with no NUL reads past the
array into the adjacent struct fields and payload and feeds those bytes
to the usermode helper command line. This is an out-of-bounds read and
a kernel memory disclosure.
Reject the attribute when no NUL exists within TC_EM_TEXT_ALGOSIZ bytes,
matching the check xt_string has had since 3ab720881b6e.
Conditions to recreate the bug:
- CAP_NET_ADMIN on the target netns (namespace-local via unshare -Urn
is enough)
- install clsact on an interface, then add a basic filter with one text
ematch whose algo[] is 16 bytes with no NUL (e.g. "A"*16) and
pattern_len at least 1
- the add fails with -ENOENT and the kernel invokes modprobe with a
module name made of "ts_" plus the 16 bytes and the adjacent payload
Fixes: d675c989ed2d4 ("[PKT_SCHED]: Packet classification based on textsearch (ematch)")
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260918133953.12494-1-bernard.ladenthin%40gmail.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-2DIU.v1.20260929183844@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/em_text.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 32aae8a9dedaa..d612ad4e5c123 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -58,6 +58,9 @@ static int em_text_change(struct net *net, void *data, int len,
if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len))
return -EINVAL;
+ if (!memchr(conf->algo, '\0', sizeof(conf->algo)))
+ return -EINVAL;
+
if (conf->from_layer > conf->to_layer)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0488/1887] amt: send the relays General Query directly from the receive path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (486 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0487/1887] net/sched: em_text: reject unterminated algo before autoload Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0489/1887] cxgb4/ch_ktls: disable softirqs around tid_list erases Greg Kroah-Hartman
` (510 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, AutonomousCodeSecurity,
Xiang Mei (Microsoft), Cen Zhang (Microsoft Security FORGE Labs),
Omar Ramadan, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Ramadan <omar@blockcast.net>
[ Upstream commit afae89de73dd693cfa329580ba0fba63bd3f0a11 ]
An skb queued in a qdisc can outlive the tunnel it references
through a raw pointer in skb->cb. For example, with igmp_qrv set
to 1 on the relay a tunnel lives for 135s, so a netem delay of
180s on the amt device outlives it; when the tunnel expires and is
freed, the subsequent dequeue triggers a use-after-free in
amt_dev_xmit().
BUG: KASAN: slab-use-after-free in amt_dev_xmit+0x2763/0x2e20
Call Trace:
amt_dev_xmit+0x2763/0x2e20 [drivers/net/amt.c:1262]
dev_hard_start_xmit+0x22f/0x620
sch_direct_xmit+0x12e/0xac0
netem_dequeue+0x333/0xc50
net_tx_action+0x35c/0xa60
amt_send_igmp_gq() and amt_send_mld_gq() are only called from
amt_request_handler(), inside the rcu_read_lock_bh() section of
amt_rcv(). amt_request_handler() already has the tunnel the query is
for: it found or created it inside that section. Queuing the query with
dev_queue_xmit() only leads back into amt_dev_xmit(), which strips the
Ethernet header and calls amt_send_membership_query() for that tunnel.
Make that call directly from the two senders instead, the same way
amt_send_advertisement() transmits from the receive path. The query
never waits in a qdisc, the tunnel is only dereferenced inside the
RCU section that found or created it, and nothing is stored in
skb->cb, so no lookup or refcount is needed. Remove the query branch
of amt_dev_xmit(), amt_skb_cb() and struct amt_skb_cb, which have no
users left.
Behaviour changes:
- The relay's own General Queries no longer pass through the amt
device's egress path: its qdisc, tc egress (clsact/tcx), the
netfilter egress hook and packet taps. They are still visible as
UDP on the underlay.
- A query that is sent successfully is no longer counted as
tx_dropped. The old query branch left through the unlock label,
which counted every sent query as dropped.
- A query that reaches amt_dev_xmit() on a relay from elsewhere,
such as a userspace querier, is now dropped at the IGMP/MLD type
switch. Before, it trusted whatever skb->cb held, and a NULL
tunnel hit the WARN_ON(1).
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
Reported-by: AutonomousCodeSecurity@microsoft.com
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Reported-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
Signed-off-by: Omar Ramadan <omar@blockcast.net>
Link: https://patch.msgid.link/20260928202312.74574-2-omar@blockcast.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/amt.c | 48 +++++++++++++++--------------------------------
include/net/amt.h | 4 ----
2 files changed, 15 insertions(+), 37 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 4799f8fd03c45..33614c802be1c 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -78,15 +78,6 @@ static struct in6_addr mld2_all_node = MLD2_ALL_NODE_INIT;
static struct mld2_grec mldv2_zero_grec;
#endif
-static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb)
-{
- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) >
- sizeof_field(struct sk_buff, cb));
-
- return (struct amt_skb_cb *)((void *)skb->cb +
- sizeof(struct tc_skb_cb));
-}
-
static void __amt_source_gc_work(void)
{
struct amt_source_node *snode;
@@ -787,6 +778,11 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
rcu_read_unlock();
}
+static bool amt_send_membership_query(struct amt_dev *amt,
+ struct sk_buff *skb,
+ struct amt_tunnel_list *tunnel,
+ bool v6);
+
static void amt_send_igmp_gq(struct amt_dev *amt,
struct amt_tunnel_list *tunnel)
{
@@ -796,8 +792,11 @@ static void amt_send_igmp_gq(struct amt_dev *amt,
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, false)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -881,8 +880,11 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, true)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#else
static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
@@ -1178,7 +1180,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
bool report = false;
struct igmphdr *ih;
- bool query = false;
struct iphdr *iph;
bool data = false;
bool v6 = false;
@@ -1196,9 +1197,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case IGMP_HOST_MEMBERSHIP_REPORT:
report = true;
break;
- case IGMP_HOST_MEMBERSHIP_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1220,9 +1218,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case ICMPV6_MLD2_REPORT:
report = true;
break;
- case ICMPV6_MGM_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1253,19 +1248,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto free;
goto unlock;
} else if (amt->mode == AMT_MODE_RELAY) {
- if (query) {
- tunnel = amt_skb_cb(skb)->tunnel;
- if (!tunnel) {
- WARN_ON(1);
- goto free;
- }
-
- /* Do not forward unexpected query */
- if (amt_send_membership_query(amt, skb, tunnel, v6))
- goto free;
- goto unlock;
- }
-
if (!data)
goto free;
list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
diff --git a/include/net/amt.h b/include/net/amt.h
index c881bc8b673b3..ad844d65a64d4 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -231,10 +231,6 @@ struct amt_relay_headers {
};
} __packed;
-struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
-};
-
struct amt_tunnel_list {
struct list_head list;
/* Protect All resources under an amt_tunne_list */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0489/1887] cxgb4/ch_ktls: disable softirqs around tid_list erases
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (487 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0488/1887] amt: send the relays General Query directly from the receive path Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0490/1887] nvmet: use the local P2P device on metadata allocation failure Greg Kroah-Hartman
` (509 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Ayush Sawal, David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4c9dc0faca98084922caeb689579d338cf3e1c29 ]
chcr_ktls_cpl_act_open_rpl() inserts into tid_list from the receive path
using xa_insert_bh(). The array is shared by the adapter's connections
and initialized with XA_FLAGS_LOCK_BH. However, chcr_ktls_dev_del() and
the chcr_ktls_dev_add() error path use xa_erase(), which takes the XArray
lock without disabling softirqs.
When cleanup runs with softirqs enabled, a receive softirq for another
connection on the same CPU can interrupt the erase and spin on the lock
held by the interrupted task. Use xa_erase_bh() at both sites to match
the insertion path.
Fixes: 65e302a9bd57 ("cxgb4/ch_ktls: Clear resources when pf4 device is removed")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reviewed-by: Ayush Sawal <ayush.sawal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
index da9973b711f49..b2adb15812368 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
@@ -390,7 +390,7 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
tx_info->tid, tx_info->ip_family);
- xa_erase(&u_ctx->tid_list, tx_info->tid);
+ xa_erase_bh(&u_ctx->tid_list, tx_info->tid);
}
port_stats = &tx_info->adap->ch_ktls_stats.ktls_port[tx_info->port_id];
@@ -581,7 +581,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
tx_info->tid, tx_info->ip_family);
- xa_erase(&u_ctx->tid_list, tx_info->tid);
+ xa_erase_bh(&u_ctx->tid_list, tx_info->tid);
put_module:
/* release module refcount */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0490/1887] nvmet: use the local P2P device on metadata allocation failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (488 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0489/1887] cxgb4/ch_ktls: disable softirqs around tid_list erases Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0491/1887] ASoC: adau1372: allow sleepy powerdown GPIOs Greg Kroah-Hartman
` (508 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Maurizio Lombardi,
Sang-Hoon Choi, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4aa9c0f377a4de5e8fddce76b34ee4529639a1ff ]
nvmet_req_alloc_p2pmem_sgls() assigns req->p2p_dev only after the data
and metadata SGL allocations succeed. If the data allocation succeeds
but the metadata allocation fails, out_free_sg passes req->p2p_dev to
pci_p2pmem_free_sgl() before that assignment has taken place.
Pass the local p2p_dev argument instead, so cleanup uses the same PCI
device as the successful data allocation.
Fixes: bcd9a0797d73 ("nvmet: fix freeing unallocated p2pmem")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 72703cdbff2ab..e1bfab6c21e0f 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1053,7 +1053,7 @@ static int nvmet_req_alloc_p2pmem_sgls(struct pci_dev *p2p_dev,
return 0;
out_free_sg:
- pci_p2pmem_free_sgl(req->p2p_dev, req->sg);
+ pci_p2pmem_free_sgl(p2p_dev, req->sg);
out_err:
return -ENOMEM;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0491/1887] ASoC: adau1372: allow sleepy powerdown GPIOs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (489 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0490/1887] nvmet: use the local P2P device on metadata allocation failure Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0492/1887] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes Greg Kroah-Hartman
` (507 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alvin Šipraga <alvin.sipraga@analog.com>
[ Upstream commit 64dd172bbffe6135d79a06ddad53dd2da4d8bd62 ]
gpiod_set_value() emits a WARN when the GPIO provider indicates that it
can sleep, as is typical for I2C controlled GPIO expanders. Since the
powerdown GPIO is only manipulated in process context, use the _cansleep
variant instead. This lets the driver use sleepy GPIOs to power off the
chip.
Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-1-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/adau1372.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c
index 3e3b8955036d9..13673c96bc548 100644
--- a/sound/soc/codecs/adau1372.c
+++ b/sound/soc/codecs/adau1372.c
@@ -798,7 +798,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
if (ret)
return ret;
if (adau1372->pd_gpio)
- gpiod_set_value(adau1372->pd_gpio, 0);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 0);
if (adau1372->switch_mode)
adau1372->switch_mode(adau1372->dev);
@@ -818,8 +818,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
ADAU1372_CLK_CTRL_PLL_EN,
0);
regcache_cache_only(adau1372->regmap, true);
- if (adau1372->pd_gpio)
- gpiod_set_value(adau1372->pd_gpio, 1);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 1);
clk_disable_unprepare(adau1372->mclk);
return ret;
}
@@ -836,7 +835,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
* map. No need to do any register writes to manually
* turn things off.
*/
- gpiod_set_value(adau1372->pd_gpio, 1);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 1);
regcache_mark_dirty(adau1372->regmap);
} else {
regmap_update_bits(adau1372->regmap, ADAU1372_REG_CLK_CTRL,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0492/1887] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (490 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0491/1887] ASoC: adau1372: allow sleepy powerdown GPIOs Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0493/1887] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM Greg Kroah-Hartman
` (506 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alvin Šipraga <alvin.sipraga@analog.com>
[ Upstream commit 36d0e05815ce84266c8b138cd4f84c3feeaf15f4 ]
The chip has strange power-on reset values for the registers that
control the output ASRC and DAC source muxes - the values are actually
marked "Reserved" in the datasheet [1]. This means that until the
underlying kcontrols are modified, the codec will not function as
expected.
The registers in question are:
register / field reset value valid values
ASRCO_SOURCE_0_1 0x10
ASRC_OUT_SOURCE0 0 4 .. 16
ASRC_OUT_SOURCE1 1 4 .. 16
ASRCO_SOURCE_2_3 0x10
ASRC_OUT_SOURCE2 2 4 .. 16
ASRC_OUT_SOURCE3 3 4 .. 16
DAC_SOURCE_0_1 0x10
DAC_SOURCE_0 0 12 .. 13
DAC_SOURCE_1 1 12 .. 13
Set some sane defaults during the driver probe:
ADC Decimator0 -> Output ASRC0
ADC Decimator1 -> Output ASRC1
ADC Decimator2 -> Output ASRC2
ADC Decimator3 -> Output ASRC3
Input ASRC0 -> DAC0
Input ASRC1 -> DAC1
With this, the chip will behave as advertised by the default kcontrol
state exposed by the driver.
[1] https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1372.pdf
Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-2-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/adau1372.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c
index 13673c96bc548..f89555e3e5252 100644
--- a/sound/soc/codecs/adau1372.c
+++ b/sound/soc/codecs/adau1372.c
@@ -1000,6 +1000,17 @@ int adau1372_probe(struct device *dev, struct regmap *regmap,
regmap_write(regmap, ADAU1372_REG_OP_STAGE_MUTE, 0x0);
+ /*
+ * Set sane default values for the Output ASRC and DAC input muxes,
+ * since the power-on reset defaults are invalid "Reserved" states.
+ */
+ regmap_write(regmap, ADAU1372_REG_ASRCO_SOURCE_0_1,
+ 0x54); /* Decimator0, Decimator1 */
+ regmap_write(regmap, ADAU1372_REG_ASRCO_SOURCE_2_3,
+ 0x76); /* Decimator2, Decimator3 */
+ regmap_write(regmap, ADAU1372_REG_DAC_SOURCE,
+ 0xdc); /* Input ASRC0, Input ASRC1 */
+
regmap_write(regmap, 0x7, 0x01); /* CLOCK OUT */
return devm_snd_soc_register_component(dev, &adau1372_driver, &adau1372_dai_driver, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0493/1887] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (491 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0492/1887] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0494/1887] flow_dissector: avoid u16 truncation of skb->len when computing thoff Greg Kroah-Hartman
` (505 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marek Szyprowski, Mark Brown,
Sasha Levin, Claude Opus 5.5
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <m.szyprowski@samsung.com>
[ Upstream commit 7529254014764ae0b8c33d5c61a58f36c65b1a1c ]
The probe function puts the device into the runtime PM active state with
only the "iis" bus clock enabled, but it also sets priv->op_clk to the
parent of the RCLK_SRC mux without enabling it. The runtime PM suspend
callback disables both clocks, so the first runtime suspend after probe
disables op_clk once more than it was enabled.
On Exynos5250 Arndale both clocks resolve to the same EXYNOS_I2S_BUS gate,
so this triggers the following warning during boot:
WARNING: drivers/clk/clk.c:1270 at clk_core_disable+0xe4/0x23c, CPU#0: kworker/u8:3/45
i2s_bus already disabled
...
Workqueue: pm pm_runtime_work
Call trace:
...
clk_core_disable from clk_disable+0x28/0x34
clk_disable from i2s_runtime_suspend+0x58/0x68 [snd_soc_i2s]
i2s_runtime_suspend [snd_soc_i2s] from genpd_runtime_suspend+0xc4/0x298
genpd_runtime_suspend from __rpm_callback+0x48/0x18c
__rpm_callback from rpm_callback+0x4c/0x50
rpm_callback from rpm_suspend+0xf4/0x718
rpm_suspend from pm_runtime_work+0x9c/0xa0
...
Fix this by enabling op_clk in probe right after getting it, so the clock
state matches the runtime PM active state, and by disabling it in remove.
Fixes: 48279c53fd1d ("ASoC: samsung: i2s: Prevent external abort on exynos5433 I2S1 access")
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://patch.msgid.link/20261002092116.585466-1-m.szyprowski@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/samsung/i2s.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 9505200f3d11b..be0d6984bb861 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1531,9 +1531,16 @@ static int samsung_i2s_probe(struct platform_device *pdev)
goto err_disable_pm;
priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
+ ret = clk_prepare_enable(priv->op_clk);
+ if (ret < 0) {
+ priv->op_clk = NULL;
+ goto err_unregister_clk;
+ }
return 0;
+err_unregister_clk:
+ i2s_unregister_clock_provider(priv);
err_disable_pm:
pm_runtime_disable(&pdev->dev);
err_del_sec:
@@ -1556,6 +1563,7 @@ static int samsung_i2s_remove(struct platform_device *pdev)
i2s_unregister_clock_provider(priv);
i2s_delete_secondary_device(priv);
+ clk_disable_unprepare(priv->op_clk);
clk_disable_unprepare(priv->clk);
pm_runtime_put_noidle(&pdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0494/1887] flow_dissector: avoid u16 truncation of skb->len when computing thoff
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (492 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0493/1887] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0495/1887] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect() Greg Kroah-Hartman
` (504 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Willem de Bruijn,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit 99bda1ecbd56905f8bd934b9cdccd3bd251192b1 ]
__skb_flow_dissect() computes key_control->thoff using:
key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
min_t(u16, ...) casts both arguments to u16 before comparing them.
Whenever skb->len (or hlen) modulo 65536 is smaller than nhoff, the
truncated length wins and thoff is set to a bogus small value, even
when the dissection succeeded. For example, an IPv4/TCP frame with
skb->len == 65540 and nhoff == 34 gets thoff == 4, so callers such as
skb_probe_transport_header() point the transport header inside the
Ethernet header.
Such skbs are not exotic:
- At the time of commit d0c081b49137 ("flow_dissector: properly cap
thoff field"), AF_PACKET with PACKET_VNET_HDR could already build GSO
skbs larger than 64KB (MTU checks are skipped for GSO, and
alloc_skb_with_frags() accepted up to MAX_SKB_FRAGS (17) order-0
pages on top of the linear part).
- BIG TCP now makes skbs larger than 64KB common.
- The following patch makes tun_get_user() dissect IFF_TAP frames
before eth_type_trans() pulls the Ethernet header, so a GSO frame
carrying a 65522..65535 byte L3 packet will be dissected with
skb->len in [65536, 65549].
Compare as u32 instead. If the resulting offset cannot be represented
in the u16 key_control->thoff, cap it to U16_MAX and report the
dissection as failed rather than silently returning a wrong transport
offset. thoff is still set on failure, as some callers (such as
eth_get_headlen()) use it regardless of the return value.
Fixes: d0c081b49137 ("flow_dissector: properly cap thoff field")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261001191140.2818991-2-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/flow_dissector.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 12216a5710a92..a51c8930f6d0d 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -969,6 +969,7 @@ bool __skb_flow_dissect(const struct net *net,
int mpls_lse = 0;
int num_hdrs = 0;
u8 ip_proto = 0;
+ u32 thoff;
bool ret;
if (!data) {
@@ -1575,7 +1576,13 @@ bool __skb_flow_dissect(const struct net *net,
ret = true;
out:
- key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
+ thoff = min_t(u32, nhoff, skb ? skb->len : hlen);
+ if (unlikely(thoff > U16_MAX)) {
+ /* Cannot be represented in key_control->thoff. */
+ thoff = U16_MAX;
+ ret = false;
+ }
+ key_control->thoff = thoff;
key_basic->n_proto = proto;
key_basic->ip_proto = ip_proto;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0495/1887] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (493 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0494/1887] flow_dissector: avoid u16 truncation of skb->len when computing thoff Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0496/1887] net/mlx5e: Order ICOSQ cc update after CQ doorbell Greg Kroah-Hartman
` (503 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit f202578efc738b883cfa04889eb97328914265a7 ]
bpf_flow_dissect() sanitizes the offsets returned by the BPF program
with clamp_t(u16, ..., hlen).
If hlen is bigger than 65535, the upper bound is truncated before
the comparison. For instance, with hlen == 65536, both nhoff and
thoff are forced to zero, even if the program returned sane values.
This is the same class of bug as the one fixed in commit 99bda1ecbd56
("flow_dissector: avoid u16 truncation of skb->len when computing
thoff"). That fix does not cover the BPF path, because
__skb_flow_dissect() returns early when a BPF flow dissector
handles the packet.
struct bpf_flow_keys stores nhoff and thoff as u16, so cap hlen
to U16_MAX before clamping.
Found by sashiko while reviewing the commit above.
Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261007045616.445596-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/flow_dissector.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index a51c8930f6d0d..511335741d687 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -921,6 +921,8 @@ u32 bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
result = bpf_prog_run_pin_on_cpu(prog, ctx);
+ /* bpf_flow_keys offsets are u16: do not let @hlen be truncated. */
+ hlen = min_t(int, hlen, U16_MAX);
flow_keys->nhoff = clamp_t(u16, flow_keys->nhoff, nhoff, hlen);
flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
flow_keys->nhoff, hlen);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0496/1887] net/mlx5e: Order ICOSQ cc update after CQ doorbell
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (494 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0495/1887] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0497/1887] net: openvswitch: validate transport header presence in set_ipv6_addr Greg Kroah-Hartman
` (502 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li RongQing, Dragos Tatulea,
Tariq Toukan, Daniel Machon, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <lirongqing@baidu.com>
[ Upstream commit b056ca4d3742d0769f91137bb1ce3215428398f7 ]
mlx5e_poll_ico_cq() requires sq->cc to be updated only after
mlx5_cqwq_update_db_record(), otherwise a CQ overrun may occur.
The current implementation updates sq->cc before the CQ doorbell
record, violating this ordering requirement.
Update the CQ doorbell record first and use dma_wmb() before updating
sq->cc. This ensures that the CQ space is released to the device
before the corresponding ICOSQ consumer index is updated by software.
Fixes: fd9b4be8002c ("net/mlx5e: RX, Support multiple outstanding UMR posts")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261006105820.257208-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 75934d0f144cc..346db86c59483 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -931,10 +931,12 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
} while (!last_wqe);
} while ((++i < MLX5E_TX_CQ_POLL_BUDGET) && (cqe = mlx5_cqwq_get_cqe(&cq->wq)));
- sq->cc = sqcc;
-
mlx5_cqwq_update_db_record(&cq->wq);
+ /* ensure cq space is freed before enabling more cqes */
+ dma_wmb();
+
+ sq->cc = sqcc;
return i;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0497/1887] net: openvswitch: validate transport header presence in set_ipv6_addr
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (495 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0496/1887] net/mlx5e: Order ICOSQ cc update after CQ doorbell Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0498/1887] mtd: Clean refcounting with MTD_PARTITIONED_MASTER Greg Kroah-Hartman
` (501 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4cc63fcfb3845e149969,
Fernando Fernandez Mancera, Ilya Maximets, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <fmancera@suse.de>
[ Upstream commit 3c6a4b11330fe424557538a98fca9f0a4c5bf313 ]
When executing IPv6 address rewrite actions on IPv6 fragments,
set_ipv6_addr() calls update_ipv6_checksum(). If parse_ipv6hdr()
processes a non-first IPv6 fragment, it sets key->ip.proto to
NEXTHDR_FRAGMENT and returns early without calling
skb_set_transport_header().
update_ipv6_checksum() unconditionally evaluates skb_transport_offset()
on entry before checking l4_proto. Because skb->transport_header is
uninitialized, this triggers a warning under CONFIG_DEBUG_NET=y although
it is completely harmless.
Fix this by returning early in update_ipv6_checksum() if l4_proto is
NEXTHDR_FRAGMENT. This avoids reading the uninitialized transport offset
for fragments while preserving the debug warning for any other protocol
where the transport header is unexpectedly missing.
See the syzbot trace:
!skb_transport_header_was_set(skb)
WARNING: ./include/linux/skbuff.h:3075 at skb_transport_header include/linux/skbuff.h:3075 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at skb_transport_offset include/linux/skbuff.h:3250 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at update_ipv6_checksum net/openvswitch/actions.c:361 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399, CPU#1: syz-executor463/5635
[...]
RIP: 0010:skb_transport_header include/linux/skbuff.h:3075 [inline]
RIP: 0010:skb_transport_offset include/linux/skbuff.h:3250 [inline]
RIP: 0010:update_ipv6_checksum net/openvswitch/actions.c:361 [inline]
RIP: 0010:set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399
[...]
Call Trace:
<TASK>
set_ipv6 net/openvswitch/actions.c:531 [inline]
do_execute_actions+0x557e/0x8600 net/openvswitch/actions.c:1366
ovs_execute_actions+0xde/0x520 net/openvswitch/actions.c:1592
ovs_packet_cmd_execute+0xb4f/0xf10 net/openvswitch/datapath.c:705
genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800
Reported-by: syzbot+4cc63fcfb3845e149969@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4cc63fcfb3845e149969
Fixes: 3fdbd1ce11e5 ("openvswitch: add ipv6 'set' action")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/20261008104135.4722-1-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/openvswitch/actions.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 679409953ac50..00a3e0af95658 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -380,7 +380,12 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
__be32 addr[4], const __be32 new_addr[4])
{
- int transport_len = skb->len - skb_transport_offset(skb);
+ int transport_len;
+
+ if (l4_proto == NEXTHDR_FRAGMENT)
+ return;
+
+ transport_len = skb->len - skb_transport_offset(skb);
if (l4_proto == NEXTHDR_TCP) {
if (likely(transport_len >= sizeof(struct tcphdr)))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0498/1887] mtd: Clean refcounting with MTD_PARTITIONED_MASTER
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (496 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0497/1887] net: openvswitch: validate transport header presence in set_ipv6_addr Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0499/1887] mtd: fix use-after-free in mtd release Greg Kroah-Hartman
` (500 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tomas Winkler, Alexander Usyskin,
Zhang Xiaoxu, Miquel Raynal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
commit 264725e35fbc3b67e053a405e022393a6017e6da upstream.
The logic is way too convoluted, let's clean the kref_get/put section to
clarify what this block does when using CONFIG_MTD_PARTITIONED_MASTER:
- Iterate through all the parent mtd devices
- Grab a reference over them all but the master
- Only grab the master whith CONFIG_MTD_PARTITIONED_MASTER
Same logic must apply in the put path, otherwise it would be broken.
Cc: Tomas Winkler <tomas.winkler@intel.com>
Cc: Alexander Usyskin <alexander.usyskin@intel.com>
Cc: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Tested-by: Alexander Usyskin <alexander.usyskin@intel.com>
Link: https://lore.kernel.org/linux-mtd/20230731090903.770277-1-miquel.raynal@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/mtdcore.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1221,14 +1221,15 @@ int __get_mtd_device(struct mtd_info *mt
return -ENODEV;
}
- kref_get(&mtd->refcnt);
-
- while (mtd->parent) {
- if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd->parent != master)
- kref_get(&mtd->parent->refcnt);
+ while (mtd) {
+ if (mtd != master)
+ kref_get(&mtd->refcnt);
mtd = mtd->parent;
}
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+ kref_get(&master->refcnt);
+
return 0;
}
EXPORT_SYMBOL_GPL(__get_mtd_device);
@@ -1312,10 +1313,12 @@ void __put_mtd_device(struct mtd_info *m
{
struct mtd_info *master = mtd_get_master(mtd);
- while (mtd != master) {
+ while (mtd) {
+ /* kref_put() can relese mtd, so keep a reference mtd->parent */
struct mtd_info *parent = mtd->parent;
- kref_put(&mtd->refcnt, mtd_device_release);
+ if (mtd != master)
+ kref_put(&mtd->refcnt, mtd_device_release);
mtd = parent;
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0499/1887] mtd: fix use-after-free in mtd release
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (497 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0498/1887] mtd: Clean refcounting with MTD_PARTITIONED_MASTER Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0500/1887] mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters Greg Kroah-Hartman
` (499 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miquel Raynal, Zhang Xiaoxu,
Tomas Winkler, Alexander Usyskin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Usyskin <alexander.usyskin@intel.com>
commit e9714c22c1a8238a85d069b1517941fc723312f7 upstream.
I case of partition device_unregister() in mtd_device_release()
calls mtd_release() which frees mtd_info structure for partition.
All code after device_unregister in mtd_device_release thus
uses already freed memory.
Move part of code to mtd_release() and restict mtd->dev cleanup
to non-partion object.
For partition object such cleanup have no sense as partition
mtd_info is removed.
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
Reviewed-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230731115836.542747-1-alexander.usyskin@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/mtdcore.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -92,6 +92,9 @@ static void mtd_release(struct device *d
struct mtd_info *mtd = dev_get_drvdata(dev);
dev_t index = MTD_DEVT(mtd->index);
+ idr_remove(&mtd_idr, mtd->index);
+ of_node_put(mtd_get_of_node(mtd));
+
if (mtd_is_partition(mtd))
release_mtd_partition(mtd);
@@ -102,6 +105,7 @@ static void mtd_release(struct device *d
static void mtd_device_release(struct kref *kref)
{
struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+ bool is_partition = mtd_is_partition(mtd);
debugfs_remove_recursive(mtd->dbg.dfs_dir);
@@ -110,11 +114,13 @@ static void mtd_device_release(struct kr
device_unregister(&mtd->dev);
- /* Clear dev so mtd can be safely re-registered later if desired */
- memset(&mtd->dev, 0, sizeof(mtd->dev));
-
- idr_remove(&mtd_idr, mtd->index);
- of_node_put(mtd_get_of_node(mtd));
+ /*
+ * Clear dev so mtd can be safely re-registered later if desired.
+ * Should not be done for partition,
+ * as it was already destroyed in device_unregister().
+ */
+ if (!is_partition)
+ memset(&mtd->dev, 0, sizeof(mtd->dev));
module_put(THIS_MODULE);
}
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0500/1887] mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (498 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0499/1887] mtd: fix use-after-free in mtd release Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0501/1887] mtd: fix double free and WARN_ON in add_mtd_device() error paths Greg Kroah-Hartman
` (498 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, kernel test robot, Miquel Raynal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
commit a7d84a2e7663bbe12394cc771107e04668ea313a upstream.
While switching to ref counters for track mtd devices use, the vmu-flash
driver was forgotten. The reason for reading the ref counter seems
debatable, but let's just fix the build for now.
Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202312022315.79twVRZw-lkp@intel.com/
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20231205075936.13831-1-miquel.raynal@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/maps/vmu-flash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/maps/vmu-flash.c
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -720,7 +720,7 @@ static int vmu_can_unload(struct maple_d
card = maple_get_drvdata(mdev);
for (x = 0; x < card->partitions; x++) {
mtd = &((card->mtd)[x]);
- if (mtd->usecount > 0)
+ if (kref_read(&mtd->refcnt))
return 0;
}
return 1;
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0501/1887] mtd: fix double free and WARN_ON in add_mtd_device() error paths
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (499 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0500/1887] mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0502/1887] dlm: validate length in dlm_search_rsb_tree Greg Kroah-Hartman
` (497 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e9c76b56dc05023b8117, Xue Lei,
Miquel Raynal
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xue Lei <Xue.Lei@windriver.com>
commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 upstream.
When device_register() or mtd_nvmem_add() fails inside
add_mtd_device() for a partition, the error handling triggers
mtd_release() via put_device() or device_unregister(). mtd_release()
calls release_mtd_partition() which frees the mtd_info structure.
However, callers such as mtd_add_partition() and add_mtd_partitions()
also call free_partition() in their error paths, resulting in a double
free.
Additionally, release_mtd_partition() hits WARN_ON(!list_empty(
&mtd->part.node)) because the partition node is still linked in the
parent's partitions list when the release callback fires from the
add_mtd_device() error path.
Fix this by overriding dev->type and dev->release before put_device()
in the error paths, so that device_release() invokes a no-op function
instead of mtd_release(). For the mtd_nvmem_add() failure case,
device_unregister() is replaced with device_del() to separate the
device removal from the final kobject reference drop, allowing the
override to take effect before put_device() is called.
The callers' error paths (list_del + free_partition) remain the sole
owners of mtd_info lifetime on add_mtd_device() failure, which is the
expected contract.
The normal partition teardown path is not affected: del_mtd_device()
goes through kref_put() -> mtd_device_release() -> device_unregister()
with dev->type still set to &mtd_devtype, so mtd_release() ->
release_mtd_partition() continues to work correctly for the regular
removal case.
Reported-by: syzbot+e9c76b56dc05023b8117@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e9c76b56dc05023b8117
Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
Signed-off-by: Xue Lei <Xue.Lei@windriver.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -102,6 +102,15 @@ static void mtd_release(struct device *d
device_destroy(&mtd_class, index + 1);
}
+/*
+ * No-op device release used in add_mtd_device() error paths.
+ * Prevents mtd_release() from being called via device_release(),
+ * which would free the mtd_info that the caller still manages.
+ */
+static void mtd_dev_release_nop(struct device *dev)
+{
+}
+
static void mtd_device_release(struct kref *kref)
{
struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
@@ -752,10 +761,8 @@ int add_mtd_device(struct mtd_info *mtd)
mtd_check_of_node(mtd);
of_node_get(mtd_get_of_node(mtd));
error = device_register(&mtd->dev);
- if (error) {
- put_device(&mtd->dev);
+ if (error)
goto fail_added;
- }
/* Add the nvmem provider */
error = mtd_nvmem_add(mtd);
@@ -782,8 +789,16 @@ int add_mtd_device(struct mtd_info *mtd)
return 0;
fail_nvmem_add:
- device_unregister(&mtd->dev);
+ device_del(&mtd->dev);
fail_added:
+ /*
+ * Clear type and set nop release to prevent mtd_release() ->
+ * release_mtd_partition() -> free_partition() from freeing mtd.
+ * The caller handles cleanup on failure.
+ */
+ mtd->dev.type = NULL;
+ mtd->dev.release = mtd_dev_release_nop;
+ put_device(&mtd->dev);
of_node_put(mtd_get_of_node(mtd));
idr_remove(&mtd_idr, i);
fail_locked:
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0502/1887] dlm: validate length in dlm_search_rsb_tree
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (500 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0501/1887] mtd: fix double free and WARN_ON in add_mtd_device() error paths Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0503/1887] can: fix unique skb identifier regression under RPS Greg Kroah-Hartman
` (496 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ezrak1e, Alexander Aring,
David Teigland, Srikanth C S, Harshit Mogalapalli, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ezrak1e <ezrakiez@gmail.com>
[ Upstream commit 080e5563f878c64e697b89e7439d730d0daad882 ]
The len parameter in dlm_dump_rsb_name() is not validated and comes
from network messages. When it exceeds DLM_RESNAME_MAXLEN, it can
cause out-of-bounds write in dlm_search_rsb_tree().
Add length validation to prevent potential buffer overflow.
Signed-off-by: Ezrak1e <ezrakiez@gmail.com>
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
[ Contextual conflict due to dlm_search_rsb_tree() using the RB-tree
implementation instead of rhashtable.]
Signed-off-by: Srikanth C S <srikanth.c.s@oracle.com>
Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/dlm/lock.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index d5aeda3399f95..8c2d4bc290177 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -456,6 +456,8 @@ int dlm_search_rsb_tree(struct rb_root *tree, const void *name, int len,
struct dlm_rsb *r;
int rc;
+ if (len > DLM_RESNAME_MAXLEN)
+ return -EINVAL;
while (node) {
r = rb_entry(node, struct dlm_rsb, res_hashnode);
rc = rsb_cmp(r, name, len);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0503/1887] can: fix unique skb identifier regression under RPS
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (501 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0502/1887] dlm: validate length in dlm_search_rsb_tree Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0504/1887] drm/amd/display: Dont replace a sink mode that shares the native totals Greg Kroah-Hartman
` (495 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joerg Willmann, Oliver Hartkopp,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 7093c3b8314a4ef7405c4066a2521398c455efe7 upstream.
Commit d4fb6514ff8e ("can: use skb hash instead of private variable in
headroom") moved the per-skb unique identifier used for raw_rcv()
duplicate detection into skb->hash.
With RPS enabled, get_rps_cpu() calls skb_get_hash() before the frame
reaches the CAN subsystem. Since CAN skbs have no L3/L4 headers, the
flow dissector assigns every CAN frame the same non-zero software
hash. can_set_skb_uid() only generated a new identifier when
skb->hash was 0, so it kept this constant hash. When the SLAB
allocator later reused the same skb address, raw_rcv() mistook the
next legitimate frame for a duplicate and dropped it.
Fix this by storing the CAN UID in the CAN skb extension
(struct can_skb_ext::can_skb_uid) instead of skb->hash, decoupling it
from any hash the network stack may compute. can_set_skb_uid() keeps
its "assign only if unset" behaviour, which preserves UIDs set before
transmission (e.g. by isotp to identify echo frames) across the local
loopback path.
Frames whose extension is shared with another clone (e.g. via tc mirred
or netem duplicate) are given a private extension copy before the UID
is assigned, so that independently received skb clones from real CAN
interfaces (skbcnt = 0) don't end up with the same UID.
The limitation that tc mirred/netem skb duplicates might be dropped in
raw_rcv for looped back isotp echo frame skbs is accepted. There is no
valid use-case for tc mirred or netem together with isotp which is not
capable to operate on different CAN interfaces simultaneously.
For routing and modifying CAN frames together with isotp use can-gw.
can-gw and vxcan additionally clear the UID of forwarded/duplicated
frames so each newly routed frame gets its own unique identifier.
[ backport to 6.1: no CAN skb extensions available, so the UID is kept
in struct can_skb_priv::skbcnt in the headroom (effectively reverting
d4fb6514ff8e) and isotp is adapted accordingly. As skb clones share
the headroom, the private extension copy for tc mirred/netem
duplicates is not applicable. The UID resets in can-gw and vxcan are
omitted, as writing to the shared headroom of cloned skbs would also
alter the UID of the original skb. This keeps the pre-d4fb6514ff8e
behaviour for routed and vxcan forwarded frames. ]
Fixes: d4fb6514ff8e ("can: use skb hash instead of private variable in headroom")
Reported-by: Joerg Willmann <joe@clnt.de>
Closes: https://lore.kernel.org/linux-can/2859AD3D-C805-41A0-9036-C5E8EE152419@clnt.de/
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/dev/skb.c | 2 ++
include/linux/can/skb.h | 2 ++
net/can/af_can.c | 6 ++----
net/can/bcm.c | 2 ++
net/can/isotp.c | 11 +++++++----
net/can/j1939/socket.c | 1 +
net/can/j1939/transport.c | 2 ++
net/can/raw.c | 7 ++++---
8 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 0da615afa04de..3ebd4f779b9bd 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -202,6 +202,7 @@ static void init_can_skb_reserve(struct sk_buff *skb)
skb_reset_transport_header(skb);
can_skb_reserve(skb);
+ can_skb_prv(skb)->skbcnt = 0;
}
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
@@ -311,6 +312,7 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
if (skb->ip_summed == CHECKSUM_NONE) {
/* init headroom */
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index 869ea574a40a1..27d0ca115c6c1 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -49,11 +49,13 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb);
/**
* struct can_skb_priv - private additional data inside CAN sk_buffs
* @ifindex: ifindex of the first interface the CAN frame appeared on
+ * @skbcnt: atomic counter to have an unique id together with skb pointer
* @frame_len: length of CAN frame in data link layer
* @cf: align to the following CAN frame at skb->data
*/
struct can_skb_priv {
int ifindex;
+ u32 skbcnt;
unsigned int frame_len;
struct can_frame cf[];
};
diff --git a/net/can/af_can.c b/net/can/af_can.c
index e7bafb2e013a6..de6bb34848432 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -643,10 +643,8 @@ static int can_rcv_filter(struct can_dev_rcv_lists *dev_rcv_lists, struct sk_buf
void can_set_skb_uid(struct sk_buff *skb)
{
/* create non-zero unique skb identifier together with *skb */
- while (!(skb->hash))
- skb->hash = atomic_inc_return(&skbcounter);
-
- skb->sw_hash = 1;
+ while (!(can_skb_prv(skb)->skbcnt))
+ can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter);
}
EXPORT_SYMBOL(can_set_skb_uid);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 35f0037ac48b6..16640650c4338 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -338,6 +338,7 @@ static void bcm_can_tx(struct bcm_op *op, struct canfd_frame *cf)
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
skb_put_data(skb, cf, op->cfsiz);
@@ -1581,6 +1582,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk,
}
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
skb->dev = dev;
can_skb_set_owner(skb, sk);
err = can_send(skb, 1); /* send with loopback */
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 3a2eca45ef437..5a0ecbc4f6b94 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -287,6 +287,7 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
can_skb_reserve(nskb);
can_skb_prv(nskb)->ifindex = dev->ifindex;
+ can_skb_prv(nskb)->skbcnt = 0;
nskb->dev = dev;
can_skb_set_owner(nskb, sk);
@@ -848,6 +849,7 @@ static void isotp_send_cframe(struct isotp_sock *so)
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
/* set uid in tx skb to identify CF echo frames */
can_set_skb_uid(skb);
@@ -876,7 +878,7 @@ static void isotp_send_cframe(struct isotp_sock *so)
pr_notice_once("can-isotp: cfecho is %08X != 0\n", old_cfecho);
/* set consecutive frame echo tag */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, can_skb_prv(skb)->skbcnt);
/* send frame with local echo enabled */
can_send_ret = can_send(skb, 1);
@@ -939,7 +941,7 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
spin_lock(&so->rx_lock);
/* so->cfecho may since belong to a new transfer; recheck under lock */
- if (READ_ONCE(so->cfecho) != skb->hash)
+ if (READ_ONCE(so->cfecho) != can_skb_prv(skb)->skbcnt)
goto out_unlock;
/* cancel local echo timeout */
@@ -1161,6 +1163,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
/* set uid in tx skb to identify CF echo frames */
can_set_skb_uid(skb);
@@ -1202,7 +1205,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
cf->data[ae] |= size;
/* set CF echo tag for isotp_rcv_echo() (SF-mode) */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, can_skb_prv(skb)->skbcnt);
} else {
/* send first frame */
@@ -1219,7 +1222,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
so->txfc.bs = 0;
/* set CF echo tag for isotp_rcv_echo() (CF-mode) */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, can_skb_prv(skb)->skbcnt);
} else {
/* standard flow control check */
new_state = ISOTP_WAIT_FIRST_FC;
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index 1b0086198ba36..00a4ee90cbaa4 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -895,6 +895,7 @@ static struct sk_buff *j1939_sk_alloc_skb(struct net_device *ndev,
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = ndev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
skb_reserve(skb, offsetof(struct can_frame, data));
ret = memcpy_from_msg(skb_put(skb, size), msg, size);
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index a1a28240fec28..b11febe2b5fbb 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -613,6 +613,7 @@ sk_buff *j1939_tp_tx_dat_new(struct j1939_priv *priv,
skb->dev = priv->ndev;
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
/* reserve CAN header */
skb_reserve(skb, offsetof(struct can_frame, data));
@@ -1552,6 +1553,7 @@ j1939_session *j1939_session_fresh_new(struct j1939_priv *priv,
skb->dev = priv->ndev;
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
skcb = j1939_skb_to_cb(skb);
memcpy(skcb, rel_skcb, sizeof(*skcb));
diff --git a/net/can/raw.c b/net/can/raw.c
index c54d3b8ee2152..6d957f1e0fc65 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -75,8 +75,8 @@ MODULE_ALIAS("can-proto-1");
*/
struct uniqframe {
+ u32 skbcnt;
const struct sk_buff *skb;
- u32 hash;
unsigned int join_rx_count;
};
@@ -140,7 +140,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
/* eliminate multiple filter matches for the same skb */
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
- this_cpu_ptr(ro->uniq)->hash == oskb->hash) {
+ this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) {
if (!ro->join_filters)
return;
@@ -150,7 +150,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
return;
} else {
this_cpu_ptr(ro->uniq)->skb = oskb;
- this_cpu_ptr(ro->uniq)->hash = oskb->hash;
+ this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt;
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
/* drop first frame to check all enabled filters? */
if (ro->join_filters && ro->count > 1)
@@ -870,6 +870,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ can_skb_prv(skb)->skbcnt = 0;
/* fill the skb before testing for valid CAN frames */
err = memcpy_from_msg(skb_put(skb, size), msg, size);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0504/1887] drm/amd/display: Dont replace a sink mode that shares the native totals
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (502 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0503/1887] can: fix unique skb identifier regression under RPS Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0505/1887] HID: hid-steam: Fix cleanup in probe() Greg Kroah-Hartman
` (494 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adrian Betschart, Dan Wheeler,
Roman Li, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Betschart <adrian.betschart@cinemaone.ch>
commit 54c998c55fc9cbc391b350d67b86e0c2a0748f1a upstream.
decide_crtc_timing_for_drm_display_mode() copies the native mode's CRTC
timing into the requested mode when clock, htotal and vtotal match.
That is meant for the modes amdgpu inserts itself:
amdgpu_dm_create_common_mode() duplicates the native mode and changes
only hdisplay and vdisplay, so those are sent with the native timing
and scaled.
A sink can also offer a real mode with the same clock and totals as
its native mode. CTA-861 VIC 102 (4096x2160@60) and VIC 97
(3840x2160@60) both use 594 MHz and 4400x2250. With 3840x2160@60 as
the preferred mode, a 4096x2160@60 request goes out with the 3840x2160
timing and the framebuffer scaled into it (dst 3840x2025 at y=67),
while the AVI InfoFrame still carries VIC 102. A JVC projector then
reports 3840x2160 and shows a corrupted right edge. 4096x2160@24,
whose totals differ, is sent and displayed correctly.
Inserted modes keep the native sync positions; a real mode with its
own active width does not. Compare those too, so only inserted modes
are patched.
Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Assisted-by: Claude-Code:claude-opus-5-5
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 22f9a2da101c37f821cd00954f81dc598754f4d5)
Cc: stable@vger.kernel.org
(cherry picked from commit 54c998c55fc9cbc391b350d67b86e0c2a0748f1a)
[ Adrian: this tree keeps the function in amdgpu_dm.c, with the equal-totals
case as its own else-if; added the sync checks there. Dropped the KUnit
test, its file does not exist here. ]
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 86282119252bd..8c150bf0aa1dd 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5607,11 +5607,16 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
const struct drm_display_mode *native_mode,
bool scale_enabled)
{
+ /* Inserted modes copy the native sync; a sink mode with equal totals may not */
if (scale_enabled) {
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
} else if (native_mode->clock == drm_mode->clock &&
native_mode->htotal == drm_mode->htotal &&
- native_mode->vtotal == drm_mode->vtotal) {
+ native_mode->vtotal == drm_mode->vtotal &&
+ native_mode->hsync_start == drm_mode->hsync_start &&
+ native_mode->hsync_end == drm_mode->hsync_end &&
+ native_mode->vsync_start == drm_mode->vsync_start &&
+ native_mode->vsync_end == drm_mode->vsync_end) {
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
} else {
/* no scaling nor amdgpu inserted, no need to patch */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0505/1887] HID: hid-steam: Fix cleanup in probe()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (503 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0504/1887] drm/amd/display: Dont replace a sink mode that shares the native totals Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0506/1887] HID: hid-steam: Make client_opened a counter Greg Kroah-Hartman
` (493 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Vicki Pfau,
Benjamin Tissoires, Lee Jones, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@linaro.org>
[ Upstream commit a9f1da09c69f13ef471db8b22107a28042d230ca ]
There are a number of issues in this code. First of all if
steam_create_client_hid() fails then it leads to an error pointer
dereference when we call hid_destroy_device(steam->client_hdev).
Also there are a number of leaks. hid_hw_stop() is not called if
hid_hw_open() fails for example. And it doesn't call steam_unregister()
or hid_hw_close().
Fixes: 691ead124a0c ("HID: hid-steam: Clean up locking")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Vicki Pfau <vi@endrift.com>
Link: https://lore.kernel.org/r/1fd87904-dabf-4879-bb89-72d13ebfc91e@moroto.mountain
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
[Lee: Move client_hdev creation after steam_register() and omit
mode_switch and rumble_work cancellation as 691ead124a0c and
e133dc99fc07 are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 43 ++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 20 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 8ee43cb225fce..2f5e9d3e64991 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -751,31 +751,20 @@ static int steam_probe(struct hid_device *hdev,
INIT_WORK(&steam->work_connect, steam_work_connect_cb);
INIT_LIST_HEAD(&steam->list);
- steam->client_hdev = steam_create_client_hid(hdev);
- if (IS_ERR(steam->client_hdev)) {
- ret = PTR_ERR(steam->client_hdev);
- goto client_hdev_fail;
- }
- steam->client_hdev->driver_data = steam;
-
/*
* With the real steam controller interface, do not connect hidraw.
* Instead, create the client_hid and connect that.
*/
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW);
if (ret)
- goto hid_hw_start_fail;
-
- ret = hid_add_device(steam->client_hdev);
- if (ret)
- goto client_hdev_add_fail;
+ goto err_cancel_work;
ret = hid_hw_open(hdev);
if (ret) {
hid_err(hdev,
"%s:hid_hw_open\n",
__func__);
- goto hid_hw_open_fail;
+ goto err_hw_stop;
}
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
@@ -791,19 +780,33 @@ static int steam_probe(struct hid_device *hdev,
hid_err(hdev,
"%s:steam_register failed with error %d\n",
__func__, ret);
- goto input_register_fail;
+ goto err_hw_close;
}
}
+ steam->client_hdev = steam_create_client_hid(hdev);
+ if (IS_ERR(steam->client_hdev)) {
+ ret = PTR_ERR(steam->client_hdev);
+ goto err_stream_unregister;
+ }
+ steam->client_hdev->driver_data = steam;
+
+ ret = hid_add_device(steam->client_hdev);
+ if (ret)
+ goto err_destroy;
+
return 0;
-input_register_fail:
-hid_hw_open_fail:
-client_hdev_add_fail:
- hid_hw_stop(hdev);
-hid_hw_start_fail:
+err_destroy:
hid_destroy_device(steam->client_hdev);
-client_hdev_fail:
+err_stream_unregister:
+ if (steam->connected)
+ steam_unregister(steam);
+err_hw_close:
+ hid_hw_close(hdev);
+err_hw_stop:
+ hid_hw_stop(hdev);
+err_cancel_work:
cancel_work_sync(&steam->work_connect);
steam_alloc_fail:
hid_err(hdev, "%s: failed with error %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0506/1887] HID: hid-steam: Make client_opened a counter
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (504 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0505/1887] HID: hid-steam: Fix cleanup in probe() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0507/1887] HID: steam: Fully unregister controller when hidraw is opened Greg Kroah-Hartman
` (492 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vicki Pfau, Jiri Kosina, Lee Jones,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <vi@endrift.com>
[ Upstream commit 555b818adb97eca70210a49ba3f1d27882dde092 ]
The client_opened variable was used to track if the hidraw was opened by any
clients to silence keyboard/mouse events while opened. However, there was no
counting of how many clients were opened, so opening two at the same time and
then closing one would fool the driver into thinking it had no remaining opened
clients.
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[Lee: Adapt steam_client_ll_open() and steam_client_ll_close() as
691ead124a0c and e1147961b214 are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 2f5e9d3e64991..4a0a13b0ae62f 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -114,7 +114,7 @@ struct steam_device {
spinlock_t lock;
struct hid_device *hdev, *client_hdev;
struct mutex mutex;
- bool client_opened;
+ unsigned long client_opened;
struct input_dev __rcu *input;
unsigned long quirks;
struct work_struct work_connect;
@@ -509,7 +509,7 @@ static void steam_battery_unregister(struct steam_device *steam)
static int steam_register(struct steam_device *steam)
{
int ret;
- bool client_opened;
+ unsigned long client_opened;
/*
* This function can be called several times in a row with the
@@ -634,7 +634,7 @@ static int steam_client_ll_open(struct hid_device *hdev)
struct steam_device *steam = hdev->driver_data;
mutex_lock(&steam->mutex);
- steam->client_opened = true;
+ steam->client_opened++;
mutex_unlock(&steam->mutex);
steam_input_unregister(steam);
@@ -654,12 +654,12 @@ static void steam_client_ll_close(struct hid_device *hdev)
spin_unlock_irqrestore(&steam->lock, flags);
mutex_lock(&steam->mutex);
- steam->client_opened = false;
- if (connected)
+ steam->client_opened--;
+ if (connected && !steam->client_opened)
steam_set_lizard_mode(steam, lizard_mode);
mutex_unlock(&steam->mutex);
- if (connected)
+ if (connected && !steam->client_opened)
steam_input_register(steam);
}
@@ -824,7 +824,7 @@ static void steam_remove(struct hid_device *hdev)
}
hid_destroy_device(steam->client_hdev);
- steam->client_opened = false;
+ steam->client_opened = 0;
cancel_work_sync(&steam->work_connect);
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
hid_info(hdev, "Steam wireless receiver disconnected");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0507/1887] HID: steam: Fully unregister controller when hidraw is opened
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (505 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0506/1887] HID: hid-steam: Make client_opened a counter Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0508/1887] HID: steam: Rearrange teardown sequence Greg Kroah-Hartman
` (491 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vicki Pfau, Jiri Kosina, Lee Jones,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <vi@endrift.com>
[ Upstream commit cd33a91d37eb4d7c6ce56aa7f4688066309808eb ]
To avoid conflicts between anything touching the hidraw and the driver we
had previously detached the evdev nodes when the hidraw is opened. However,
this isn't sufficient to avoid FEATURE reports from conflicting, so we
change to fully unregistering the controller internally, leaving only the
hidraw active until it's closed.
This also unifies the unregister and connect callbacks, as now the logic
between these two callbacks is identical.
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[Lee: Convert steam_client_ll_open() and steam_client_ll_close() to
schedule work_connect directly and omit sensors, rumble_work,
mode_switch and unregister_work changes as e133dc99fc07,
e1147961b214 and 1d4549fd1115 are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 78 ++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 36 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 4a0a13b0ae62f..e8f28c59a3033 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -380,6 +380,7 @@ static int steam_battery_register(struct steam_device *steam)
&steam->battery_desc, &battery_cfg);
if (IS_ERR(battery)) {
ret = PTR_ERR(battery);
+ devm_kfree(&steam->hdev->dev, steam->battery_desc.name);
hid_err(steam->hdev,
"%s:power_supply_register failed with error %d\n",
__func__, ret);
@@ -504,12 +505,15 @@ static void steam_battery_unregister(struct steam_device *steam)
RCU_INIT_POINTER(steam->battery, NULL);
synchronize_rcu();
power_supply_unregister(battery);
+ devm_kfree(&steam->hdev->dev, steam->battery_desc.name);
}
static int steam_register(struct steam_device *steam)
{
int ret;
unsigned long client_opened;
+ unsigned long flags;
+ bool do_add;
/*
* This function can be called several times in a row with the
@@ -535,38 +539,47 @@ static int steam_register(struct steam_device *steam)
if (steam->quirks & STEAM_QUIRK_WIRELESS)
steam_battery_register(steam);
- mutex_lock(&steam_devices_lock);
- if (list_empty(&steam->list))
- list_add(&steam->list, &steam_devices);
- mutex_unlock(&steam_devices_lock);
+ do_add = true;
}
- mutex_lock(&steam->mutex);
+ spin_lock_irqsave(&steam->lock, flags);
client_opened = steam->client_opened;
- if (!client_opened)
- steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
+ spin_unlock_irqrestore(&steam->lock, flags);
- if (!client_opened)
+ if (!client_opened) {
+ mutex_lock(&steam->mutex);
+ steam_set_lizard_mode(steam, lizard_mode);
+ mutex_unlock(&steam->mutex);
ret = steam_input_register(steam);
- else
- ret = 0;
+ if (ret != 0)
+ goto steam_register_input_fail;
+ }
+
+ if (do_add) {
+ mutex_lock(&steam_devices_lock);
+ if (list_empty(&steam->list))
+ list_add(&steam->list, &steam_devices);
+ mutex_unlock(&steam_devices_lock);
+ }
+ return 0;
+steam_register_input_fail:
return ret;
}
static void steam_unregister(struct steam_device *steam)
{
+ if (!steam->serial_no[0])
+ return;
+
+ hid_info(steam->hdev, "Steam Controller '%s' disconnected",
+ steam->serial_no);
steam_battery_unregister(steam);
steam_input_unregister(steam);
- if (steam->serial_no[0]) {
- hid_info(steam->hdev, "Steam Controller '%s' disconnected",
- steam->serial_no);
- mutex_lock(&steam_devices_lock);
- list_del_init(&steam->list);
- mutex_unlock(&steam_devices_lock);
- steam->serial_no[0] = 0;
- }
+ mutex_lock(&steam_devices_lock);
+ list_del_init(&steam->list);
+ mutex_unlock(&steam_devices_lock);
+ steam->serial_no[0] = 0;
}
static void steam_work_connect_cb(struct work_struct *work)
@@ -575,19 +588,20 @@ static void steam_work_connect_cb(struct work_struct *work)
work_connect);
unsigned long flags;
bool connected;
+ bool opened;
int ret;
spin_lock_irqsave(&steam->lock, flags);
+ opened = steam->client_opened;
connected = steam->connected;
spin_unlock_irqrestore(&steam->lock, flags);
- if (connected) {
+ if (connected && !opened) {
ret = steam_register(steam);
- if (ret) {
+ if (ret)
hid_err(steam->hdev,
"%s:steam_register failed with error %d\n",
__func__, ret);
- }
} else {
steam_unregister(steam);
}
@@ -632,12 +646,13 @@ static void steam_client_ll_stop(struct hid_device *hdev)
static int steam_client_ll_open(struct hid_device *hdev)
{
struct steam_device *steam = hdev->driver_data;
+ unsigned long flags;
- mutex_lock(&steam->mutex);
+ spin_lock_irqsave(&steam->lock, flags);
steam->client_opened++;
- mutex_unlock(&steam->mutex);
+ spin_unlock_irqrestore(&steam->lock, flags);
- steam_input_unregister(steam);
+ schedule_work(&steam->work_connect);
return 0;
}
@@ -645,22 +660,13 @@ static int steam_client_ll_open(struct hid_device *hdev)
static void steam_client_ll_close(struct hid_device *hdev)
{
struct steam_device *steam = hdev->driver_data;
-
unsigned long flags;
- bool connected;
spin_lock_irqsave(&steam->lock, flags);
- connected = steam->connected;
- spin_unlock_irqrestore(&steam->lock, flags);
-
- mutex_lock(&steam->mutex);
steam->client_opened--;
- if (connected && !steam->client_opened)
- steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
+ spin_unlock_irqrestore(&steam->lock, flags);
- if (connected && !steam->client_opened)
- steam_input_register(steam);
+ schedule_work(&steam->work_connect);
}
static int steam_client_ll_raw_request(struct hid_device *hdev,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0508/1887] HID: steam: Rearrange teardown sequence
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (506 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0507/1887] HID: steam: Fully unregister controller when hidraw is opened Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0509/1887] HID: steam: Refactor registration Greg Kroah-Hartman
` (490 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vicki Pfau, Jiri Kosina, Lee Jones,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <vi@endrift.com>
[ Upstream commit ddce9641ce924ed91ec8304577e463823a29ffaf ]
This fixes a narrow window during the teardown sequence where callbacks
could still be scheduled during cleanup that would then have a dangling
pointer to the now-freed steam struct.
This also puts work canceling for rumble and mode switch in
steam_unregister, as that shouldn't persist while the client hdev is open.
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[Lee: Omit rumble_work, coalesce_rumble_work and mode_switch
cancellation as e133dc99fc07 and 1d4549fd1115 are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index e8f28c59a3033..0e5fba060c913 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -829,15 +829,16 @@ static void steam_remove(struct hid_device *hdev)
return;
}
+ hid_hw_close(hdev);
hid_destroy_device(steam->client_hdev);
+ steam->client_hdev = NULL;
steam->client_opened = 0;
cancel_work_sync(&steam->work_connect);
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
hid_info(hdev, "Steam wireless receiver disconnected");
}
- hid_hw_close(hdev);
- hid_hw_stop(hdev);
steam_unregister(steam);
+ hid_hw_stop(hdev);
}
static void steam_do_connect_event(struct steam_device *steam, bool connected)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0509/1887] HID: steam: Refactor registration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (507 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0508/1887] HID: steam: Rearrange teardown sequence Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0510/1887] HID: steam: Clean up locking Greg Kroah-Hartman
` (489 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vicki Pfau, Jiri Kosina, Lee Jones,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <vi@endrift.com>
[ Upstream commit 6f9b740c31ba7e061b2ebb330d9a3d63f1358f29 ]
This refactors and simplifies the registration/unregistration flow. Since
we now only perform registration when the client isn't opened anymore, the
logic for handling that can be removed, and the rest of the function
streamlined.
We also remove the previous assumption that we have a serial number to show
we're registered, replacing it with a single purpose boolean.
In a previous refactor the code for unregistering a battery if later
registration steps failed was accidentally left out. As a result, a
lingering power_supply object could get left over after the steam object
was torn down. This is also fixed here.
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[Lee: Omit sensors, steam_get_attributes(), rumble_work,
coalesce_rumble_work and mode_switch changes as e133dc99fc07,
a0fbd9437d7d and 1d4549fd1115 are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 70 ++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 39 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 0e5fba060c913..aa001a293a361 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -119,6 +119,7 @@ struct steam_device {
unsigned long quirks;
struct work_struct work_connect;
bool connected;
+ bool registered;
char serial_no[STEAM_SERIAL_LEN + 1];
struct power_supply_desc battery_desc;
struct power_supply __rcu *battery;
@@ -511,9 +512,6 @@ static void steam_battery_unregister(struct steam_device *steam)
static int steam_register(struct steam_device *steam)
{
int ret;
- unsigned long client_opened;
- unsigned long flags;
- bool do_add;
/*
* This function can be called several times in a row with the
@@ -521,59 +519,53 @@ static int steam_register(struct steam_device *steam)
* another client send a get_connection_status command, for example.
* The battery and serial number are set just once per device.
*/
- if (!steam->serial_no[0]) {
- /*
- * Unlikely, but getting the serial could fail, and it is not so
- * important, so make up a serial number and go on.
- */
- mutex_lock(&steam->mutex);
- if (steam_get_serial(steam) < 0)
- strscpy(steam->serial_no, "XXXXXXXXXX",
- sizeof(steam->serial_no));
- mutex_unlock(&steam->mutex);
-
- hid_info(steam->hdev, "Steam Controller '%s' connected",
- steam->serial_no);
+ if (steam->registered)
+ return 0;
- /* ignore battery errors, we can live without it */
- if (steam->quirks & STEAM_QUIRK_WIRELESS)
- steam_battery_register(steam);
+ /*
+ * Unlikely, but getting the serial could fail, and it is not so
+ * important, so make up a serial number and go on.
+ */
+ mutex_lock(&steam->mutex);
+ if (steam_get_serial(steam) < 0 || !steam->serial_no[0])
+ strscpy(steam->serial_no, "XXXXXXXXXX",
+ sizeof(steam->serial_no));
+ mutex_unlock(&steam->mutex);
- do_add = true;
- }
+ hid_info(steam->hdev, "Steam Controller '%s' connected",
+ steam->serial_no);
- spin_lock_irqsave(&steam->lock, flags);
- client_opened = steam->client_opened;
- spin_unlock_irqrestore(&steam->lock, flags);
+ /* ignore battery errors, we can live without it */
+ if (steam->quirks & STEAM_QUIRK_WIRELESS)
+ steam_battery_register(steam);
- if (!client_opened) {
- mutex_lock(&steam->mutex);
- steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
- ret = steam_input_register(steam);
- if (ret != 0)
- goto steam_register_input_fail;
- }
+ mutex_lock(&steam->mutex);
+ steam_set_lizard_mode(steam, lizard_mode);
+ mutex_unlock(&steam->mutex);
+ ret = steam_input_register(steam);
+ if (ret != 0)
+ goto steam_register_input_fail;
- if (do_add) {
- mutex_lock(&steam_devices_lock);
- if (list_empty(&steam->list))
- list_add(&steam->list, &steam_devices);
- mutex_unlock(&steam_devices_lock);
- }
+ steam->registered = true;
+ mutex_lock(&steam_devices_lock);
+ if (list_empty(&steam->list))
+ list_add(&steam->list, &steam_devices);
+ mutex_unlock(&steam_devices_lock);
return 0;
steam_register_input_fail:
+ steam_battery_unregister(steam);
return ret;
}
static void steam_unregister(struct steam_device *steam)
{
- if (!steam->serial_no[0])
+ if (!steam->registered)
return;
hid_info(steam->hdev, "Steam Controller '%s' disconnected",
steam->serial_no);
+ steam->registered = false;
steam_battery_unregister(steam);
steam_input_unregister(steam);
mutex_lock(&steam_devices_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0510/1887] HID: steam: Clean up locking
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (508 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0509/1887] HID: steam: Refactor registration Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0511/1887] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
` (488 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vicki Pfau, Jiri Kosina, Lee Jones,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <vi@endrift.com>
[ Upstream commit de1d341b9b3ec9655f31fb8b44f784cca5e670ad ]
This cleans up several issues with locking behavior, including RCU accesses
not being guarded behind a lock.
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
[Lee: Adapt to steam->mutex and omit Steam Deck sensors, mode_switch,
rumble_work, coalesce_rumble_work and Ibex changes as
691ead124a0c, e133dc99fc07, a0fbd9437d7d, 1d4549fd1115,
fcfa7db89f7a and 0a80b4e8ec6a are not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-steam.c | 59 ++++++++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 22 deletions(-)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index aa001a293a361..bbc150167a7f1 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -114,6 +114,7 @@ struct steam_device {
spinlock_t lock;
struct hid_device *hdev, *client_hdev;
struct mutex mutex;
+ struct mutex registration_mutex;
unsigned long client_opened;
struct input_dev __rcu *input;
unsigned long quirks;
@@ -294,22 +295,30 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
static int steam_input_open(struct input_dev *dev)
{
struct steam_device *steam = input_get_drvdata(dev);
+ unsigned long flags;
+ bool client_opened;
- mutex_lock(&steam->mutex);
- if (!steam->client_opened && lizard_mode)
+ spin_lock_irqsave(&steam->lock, flags);
+ client_opened = steam->client_opened;
+ spin_unlock_irqrestore(&steam->lock, flags);
+ guard(mutex)(&steam->mutex);
+ if (!client_opened && lizard_mode)
steam_set_lizard_mode(steam, false);
- mutex_unlock(&steam->mutex);
return 0;
}
static void steam_input_close(struct input_dev *dev)
{
struct steam_device *steam = input_get_drvdata(dev);
+ unsigned long flags;
+ bool client_opened;
- mutex_lock(&steam->mutex);
- if (!steam->client_opened && lizard_mode)
+ spin_lock_irqsave(&steam->lock, flags);
+ client_opened = steam->client_opened;
+ spin_unlock_irqrestore(&steam->lock, flags);
+ guard(mutex)(&steam->mutex);
+ if (!client_opened && lizard_mode)
steam_set_lizard_mode(steam, true);
- mutex_unlock(&steam->mutex);
}
static enum power_supply_property steam_battery_props[] = {
@@ -513,40 +522,43 @@ static int steam_register(struct steam_device *steam)
{
int ret;
+ mutex_lock(&steam->registration_mutex);
/*
* This function can be called several times in a row with the
* wireless adaptor, without steam_unregister() between them, because
* another client send a get_connection_status command, for example.
* The battery and serial number are set just once per device.
*/
- if (steam->registered)
+ if (steam->registered) {
+ mutex_unlock(&steam->registration_mutex);
return 0;
+ }
+ mutex_lock(&steam->mutex);
/*
* Unlikely, but getting the serial could fail, and it is not so
* important, so make up a serial number and go on.
*/
- mutex_lock(&steam->mutex);
if (steam_get_serial(steam) < 0 || !steam->serial_no[0])
strscpy(steam->serial_no, "XXXXXXXXXX",
sizeof(steam->serial_no));
- mutex_unlock(&steam->mutex);
hid_info(steam->hdev, "Steam Controller '%s' connected",
steam->serial_no);
+ steam_set_lizard_mode(steam, lizard_mode);
+ mutex_unlock(&steam->mutex);
+
/* ignore battery errors, we can live without it */
if (steam->quirks & STEAM_QUIRK_WIRELESS)
steam_battery_register(steam);
- mutex_lock(&steam->mutex);
- steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
ret = steam_input_register(steam);
if (ret != 0)
goto steam_register_input_fail;
steam->registered = true;
+ mutex_unlock(&steam->registration_mutex);
mutex_lock(&steam_devices_lock);
if (list_empty(&steam->list))
list_add(&steam->list, &steam_devices);
@@ -555,6 +567,7 @@ static int steam_register(struct steam_device *steam)
steam_register_input_fail:
steam_battery_unregister(steam);
+ mutex_unlock(&steam->registration_mutex);
return ret;
}
@@ -565,9 +578,11 @@ static void steam_unregister(struct steam_device *steam)
hid_info(steam->hdev, "Steam Controller '%s' disconnected",
steam->serial_no);
+ mutex_lock(&steam->registration_mutex);
steam->registered = false;
steam_battery_unregister(steam);
steam_input_unregister(steam);
+ mutex_unlock(&steam->registration_mutex);
mutex_lock(&steam_devices_lock);
list_del_init(&steam->list);
mutex_unlock(&steam_devices_lock);
@@ -745,6 +760,7 @@ static int steam_probe(struct hid_device *hdev,
hid_set_drvdata(hdev, steam);
spin_lock_init(&steam->lock);
mutex_init(&steam->mutex);
+ mutex_init(&steam->registration_mutex);
steam->quirks = id->driver_data;
INIT_WORK(&steam->work_connect, steam_work_connect_cb);
INIT_LIST_HEAD(&steam->list);
@@ -835,13 +851,10 @@ static void steam_remove(struct hid_device *hdev)
static void steam_do_connect_event(struct steam_device *steam, bool connected)
{
- unsigned long flags;
bool changed;
- spin_lock_irqsave(&steam->lock, flags);
changed = steam->connected != connected;
steam->connected = connected;
- spin_unlock_irqrestore(&steam->lock, flags);
if (changed && schedule_work(&steam->work_connect) == 0)
dbg_hid("%s: connected=%d event already queued\n",
@@ -1008,8 +1021,6 @@ static void steam_do_input_event(struct steam_device *steam,
static void steam_do_battery_event(struct steam_device *steam,
struct power_supply *battery, u8 *data)
{
- unsigned long flags;
-
s16 volts = steam_le16(data + 12);
u8 batt = data[14];
@@ -1017,10 +1028,8 @@ static void steam_do_battery_event(struct steam_device *steam,
rcu_read_lock();
battery = rcu_dereference(steam->battery);
if (likely(battery)) {
- spin_lock_irqsave(&steam->lock, flags);
steam->voltage = volts;
steam->battery_charge = batt;
- spin_unlock_irqrestore(&steam->lock, flags);
power_supply_changed(battery);
}
rcu_read_unlock();
@@ -1037,6 +1046,7 @@ static int steam_raw_event(struct hid_device *hdev,
if (!steam)
return 0;
+ guard(spinlock_irqsave)(&steam->lock);
if (steam->client_opened)
hid_input_report(steam->client_hdev, HID_FEATURE_REPORT,
data, size, 0);
@@ -1108,6 +1118,8 @@ static int steam_param_set_lizard_mode(const char *val,
{
struct steam_device *steam;
int ret;
+ bool client_opened;
+ unsigned long flags;
ret = param_set_bool(val, kp);
if (ret)
@@ -1115,10 +1127,13 @@ static int steam_param_set_lizard_mode(const char *val,
mutex_lock(&steam_devices_lock);
list_for_each_entry(steam, &steam_devices, list) {
- mutex_lock(&steam->mutex);
- if (!steam->client_opened)
+ spin_lock_irqsave(&steam->lock, flags);
+ client_opened = steam->client_opened;
+ spin_unlock_irqrestore(&steam->lock, flags);
+ if (!client_opened) {
+ guard(mutex)(&steam->mutex);
steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
+ }
}
mutex_unlock(&steam_devices_lock);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0511/1887] tracing: Set the trace clock before registering the histogram trigger
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (509 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0510/1887] HID: steam: Clean up locking Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0512/1887] ip6_gre: remove obsolete ERSPAN PMTU update Greg Kroah-Hartman
` (487 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt,
Lee Jones, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit 6ede78d0563a2a3ae3e46f9c07cedb5d79645429 ]
hist_register_trigger() puts the trigger on the global named_triggers
list in cmd_ops->init(), and only then sets the trace clock:
if (data->cmd_ops->init) {
ret = data->cmd_ops->init(data);
if (ret < 0)
goto out;
}
if (hist_data->enable_timestamps) {
ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
if (ret) {
hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
goto out;
}
The clock string is not checked anywhere before that call, so a named
trigger using common_timestamp with an unknown clock fails after it has
already become findable. event_hist_trigger_parse() then frees it
without taking it off the list, and the next lookup by name reads the
freed object:
~# cd /sys/kernel/tracing/events/sched/sched_switch
~# echo 'hist:name=foo:keys=common_pid:ts=common_timestamp:clock=bogus' > trigger
bash: echo: write error: Invalid argument
~# echo 'hist:name=foo:keys=common_pid' > trigger
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff88800915d760 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0x900
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 63:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Set the clock before the trigger is registered, so that nothing which
can fail runs after it is published, the way commit 6f86bdeab633
("tracing: Fix bad hist from corrupting named_triggers list") moved the
registration below the rest of the setup.
tracing_set_filter_buffering() is reference counted, so the init failure
path has to drop the reference that the clock block now takes first.
Cc: stable@vger.kernel.org
Fixes: a4072fe85ba3 ("tracing: Add a clock attribute for hist triggers")
Link: https://patch.msgid.link/20260907091415.554535-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[Lee: Call data->ops->init(data) as b052d70f7c9c ("tracing: Merge struct
event_trigger_ops into struct event_command") is not present]
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace_events_hist.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 8e5efdfa0fc7a..7753a024829b8 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6244,12 +6244,6 @@ static int hist_register_trigger(char *glob,
data->ops = &event_hist_trigger_named_ops;
}
- if (data->ops->init) {
- ret = data->ops->init(data);
- if (ret < 0)
- goto out;
- }
-
if (hist_data->enable_timestamps) {
char *clock = hist_data->attrs->clock;
@@ -6262,6 +6256,15 @@ static int hist_register_trigger(char *glob,
tracing_set_filter_buffering(file->tr, true);
}
+ if (data->ops->init) {
+ ret = data->ops->init(data);
+ if (ret < 0) {
+ if (hist_data->enable_timestamps)
+ tracing_set_filter_buffering(file->tr, false);
+ goto out;
+ }
+ }
+
if (named_data) {
remove_hist_vars(hist_data);
destroy_hist_data(hist_data);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0512/1887] ip6_gre: remove obsolete ERSPAN PMTU update
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (510 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0511/1887] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0513/1887] ice: fix metadata_dst refcount handling on representor teardown Greg Kroah-Hartman
` (486 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit 8bc60db48e8cba35488bbd6e1f94aa990afa275a ]
A tc tunnel_key action can attach a METADATA_IP_TUNNEL dst to an skb,
and mirred can redirect it to a native ip6erspan device. The legacy PMTU
update in ip6erspan_tunnel_xmit() treats that metadata dst as a route.
Since it has no output device, dst_dev(dst)->mtu dereferences NULL.
On v7.2 with KASAN, an initial UID/GID 65534 process with CapEff 0 used
self-created user and network namespaces to trigger:
KASAN: null-ptr-deref
RIP: ip6erspan_tunnel_xmit+0x10fc/0x2cc0
Kernel panic - not syncing: Fatal exception in interrupt
The update is obsolete. Commit fe1a4ca0a2b7 ("ip6_gre: process toobig
in a better way") changed IPv6 GRE Too Big handling to update the
underlay route and removed the equivalent block from __gre6_xmit().
ip6_tnl_xmit() then propagates the underlay PMTU to the overlay route.
Remove the stale ERSPAN copy and its now-unused dst variable. This
eliminates the metadata-dst dereference and keeps ERSPAN aligned with
IPv6 GRE PMTU handling.
Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
Cc: stable@vger.kernel.org
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261002033058.358137-1-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ sashal: Adapted the removal to the PMTU check using dst->dev->mtu directly. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ip6_gre.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 950d5e74b094e..73ec4641f2201 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -962,7 +962,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
{
struct ip_tunnel_info *tun_info = NULL;
struct ip6_tnl *t = netdev_priv(dev);
- struct dst_entry *dst = skb_dst(skb);
bool truncate = false;
int encap_limit = -1;
__u8 dsfield = false;
@@ -1094,10 +1093,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
/* Push GRE header. */
gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(atomic_fetch_inc(&t->o_seqno)));
- /* TooBig packet may have updated dst->dev's mtu */
- if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
- dst->ops->update_pmtu(dst, NULL, skb, dst->dev->mtu, false);
-
err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
NEXTHDR_GRE);
if (err != 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0513/1887] ice: fix metadata_dst refcount handling on representor teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (511 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0512/1887] ip6_gre: remove obsolete ERSPAN PMTU update Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0514/1887] selinux: fix data race on AVC latest_notif Greg Kroah-Hartman
` (485 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tristan Madani, Simon Horman,
Tony Nguyen, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <tristan@talencesecurity.com>
[ Upstream commit 58858b8f14803a7eeac297b3ce20f3b21bf2ff66 ]
ice_eswitch_release_repr() uses metadata_dst_free() to release the
representor's metadata_dst. metadata_dst_free() directly frees the
underlying memory without checking the dst_entry refcount.
When ice_eswitch_port_start_xmit() processes a packet, it takes a
reference via dst_hold() and attaches the metadata_dst to the skb.
If the representor is torn down while packets are still queued on
the lower device (e.g. in a qdisc), the metadata_dst is freed while
references are still held.
Use dst_release() instead, which correctly decrements the refcount
and only frees the object when all references are dropped. The dst
subsystem already handles metadata_dst cleanup in dst_destroy() when
DST_METADATA is set.
Other drivers sharing this pattern (nfp, airoha, bnxt) already use
dst_release() for their metadata_dst lifecycle.
Fixes: f5396b8a663f7 ("ice: switchdev slow path")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20260928230429.495442-5-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ sashal: Adapted repr->dst access to vf->repr->dst in ice_eswitch_release_reprs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_eswitch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
index 7de4a8a4b563c..569d1b95ec1ef 100644
--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
@@ -235,7 +235,7 @@ ice_eswitch_release_reprs(struct ice_pf *pf, struct ice_vsi *ctrl_vsi)
continue;
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
- metadata_dst_free(vf->repr->dst);
+ dst_release(&vf->repr->dst->dst);
vf->repr->dst = NULL;
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr,
ICE_FWD_TO_VSI);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0514/1887] selinux: fix data race on AVC latest_notif
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (512 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0513/1887] ice: fix metadata_dst refcount handling on representor teardown Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0515/1887] EDAC/amd64: Mask UMC chip select to the four implemented selects Greg Kroah-Hartman
` (484 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+a7f7cb0737bd91aa698c,
Christian Göttsche, Stephen Smalley, Paul Moore, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Göttsche <cgzones@googlemail.com>
[ Upstream commit 1ca924044bf0de879a1648be93a56939652267d3 ]
avc_policy_seqno() reads latest_notif without holding notif_lock, while
avc_latest_notif_update() can update it under that lock. KCSAN reports
these concurrent accesses during policy boolean updates and permission
checks.
Use READ_ONCE() for the lockless read and WRITE_ONCE() for the update.
The spinlock continues to serialize the comparison and update against
other writers. Reads made while holding notif_lock cannot race with a
writer and can remain plain accesses.
This marks both sides of the intentional concurrent access and constrains
compiler transformations, without suppressing checking with data_race().
Cc: stable@vger.kernel.org
Fixes: 788e7dd4c22e ("SELinux: Improve read/write performance")
Reported-by: syzbot+a7f7cb0737bd91aa698c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a7f7cb0737bd91aa698c
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
[ sashal: Adapted direct selinux_avc accesses to the existing avc and state->avc pointers. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/selinux/avc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index dcc8e1df4d7c5..e26f9b01b7305 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -589,7 +589,7 @@ static int avc_latest_notif_update(struct selinux_avc *avc,
}
} else {
if (seqno > avc->avc_cache.latest_notif)
- avc->avc_cache.latest_notif = seqno;
+ WRITE_ONCE(avc->avc_cache.latest_notif, seqno);
}
spin_unlock_irqrestore(¬if_lock, flag);
@@ -1202,7 +1202,8 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
u32 avc_policy_seqno(struct selinux_state *state)
{
- return state->avc->avc_cache.latest_notif;
+ /* Writers hold notif_lock; readers only sample the sequence number. */
+ return READ_ONCE(state->avc->avc_cache.latest_notif);
}
void avc_disable(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0515/1887] EDAC/amd64: Mask UMC chip select to the four implemented selects
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (513 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0514/1887] selinux: fix data race on AVC latest_notif Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0516/1887] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP Greg Kroah-Hartman
` (483 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yazen Ghannam, Vishal Badole,
Borislav Petkov (AMD), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishal Badole <Vishal.Badole@amd.com>
[ Upstream commit 7484bc43ba6b8e189b482db5b75e7842890a82b1 ]
For DRAM ECC errors, the chip select value can be found in the
MCA_SYND[ErrorInformation] field.
ErrorInformation[2:0] was first documented in Zen1. The 3 bit field
implied that up to 8 chip selects may be used.
However, all Zen-based systems have only ever had up to 4 chip selects.
So only bits [1:0] would contain a valid chip select value.
Future systems are redefining the field to ErrorInformation[1:0]. This
matches the existing 'up to 4 chip selects' implementations. And it
frees up the extra bit for other decoding.
Change the current chip select mask from 0x7 to 0x3 to prepare for the
decode change.
Fixes: 713ad54675fd ("EDAC, amd64: Define and register UMC error decode function")
Suggested-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Vishal Badole <Vishal.Badole@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20261002113204.3358815-2-Vishal.Badole@amd.com
[ sashal: Applied the change in decode_umc_error() instead of the absent umc_get_err_info() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/amd64_edac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 2f854feeeb237..7b3d3615de5cd 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -3300,7 +3300,7 @@ static void decode_umc_error(int node_id, struct mce *m)
err.err_code = ERR_CHANNEL;
}
- err.csrow = m->synd & 0x7;
+ err.csrow = m->synd & 0x3;
if (umc_normaddr_to_sysaddr(m->addr, pvt->mc_node_id, err.channel, &sys_addr)) {
err.err_code = ERR_NORM_ADDR;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0516/1887] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (514 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0515/1887] EDAC/amd64: Mask UMC chip select to the four implemented selects Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0517/1887] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge Greg Kroah-Hartman
` (482 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Pedro Falcato, Kiryl Shutsemau (Meta), Jose A. Perez de Azpillaga,
Anirudh Srinivasan, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Brian Geffon, Minchan Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 597e4b9ab48a3f841080f627722064853d3f650e ]
The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.
Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.
Fix another of these - partial copies.
The long-standing mremap() partial VMA logic has the baked-in assumption
that the originating VMA is unmapped and thus moved.
However MREMAP_DONTUNMAP defeats this by performing a partial copy
instead since it keeps the source VMA around.
An mremap(..., MREMAP_DONTUNMAP) operation disallows resizing of the VMA,
but the operation can be performed partially:
|-----------------|
| |
| v
<------> <------>
.new_sz. new_sz
|--.------.--| |------|
| .source. | | dest |
|--.------.--| |------|
<------------>
old_sz
The page tables in the specified range are moved, but the original VMA is
kept intact.
This interacts poorly with mlock()'d VMAs, as the VMA_LOCKED_BIT flag is
cleared for the entire source VMA and set for the entire destination VMA.
This results in an mm->locked_vm leak as the change is therefore not
accounted correctly.
The clear solution here is to make the portion of the source VMA which is
mremap()'d distinct from the rest of it, a.k.a. split it.
Therefore resolve this issue by splitting it ahead of the rest of the
mremap() operation if the VMA is mlock()'d.
This is valid, as the source VMA will lose its VMA_LOCKED_BIT flag, so if a
partial remap it will become distinct from the rest of the VMA.
In order to make this change re-expose split_vma() in vma.h for
CONFIG_MMU (nommu doesn't compile mremap.c and uses a static helper
instead).
Finally, update the sys_map_count check to account for this case.
Note that the early check does not use needs_pre_split() - this is because
the VMA has not been looked up by this point, so be conservative and assume
that the VMA is mlock()'d in this case for the purposes of the
sys_map_count check.
Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-2-f388985a0f0a@kernel.org
Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
[ sashal: Moved split preparation into move_vma() because prep_move_vma() is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mremap.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index 7e39614d2e0e6..e1d7047f6ee5e 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -585,6 +585,8 @@ static unsigned long move_vma(struct vm_area_struct *vma,
int split = 0;
int err = 0;
bool need_rmap_locks;
+ const bool split_before = vma->vm_start != old_addr;
+ const bool split_after = vma->vm_end != old_addr + old_len;
/*
* We'd prefer to avoid failure later on in do_munmap:
@@ -597,9 +599,9 @@ static unsigned long move_vma(struct vm_area_struct *vma,
to_account = new_len;
if (vma->vm_ops && vma->vm_ops->may_split) {
- if (vma->vm_start != old_addr)
+ if (split_before)
err = vma->vm_ops->may_split(vma, old_addr);
- if (!err && vma->vm_end != old_addr + old_len)
+ if (!err && split_after)
err = vma->vm_ops->may_split(vma, old_addr + old_len);
if (err)
return err;
@@ -617,6 +619,19 @@ static unsigned long move_vma(struct vm_area_struct *vma,
if (err)
return err;
+ /*
+ * To account mlock()'d pages correctly in the MREMAP_DONTUNMAP
+ * case perform any split ahead of time for an mlock()'d VMA.
+ */
+ if ((flags & MREMAP_DONTUNMAP) && (vma->vm_flags & VM_LOCKED)) {
+ if (split_before)
+ err = split_vma(mm, vma, old_addr, 1);
+ if (!err && split_after)
+ err = split_vma(mm, vma, old_addr + old_len, 0);
+ if (err)
+ return err;
+ }
+
if (vm_flags & VM_ACCOUNT) {
if (security_vm_enough_memory_mm(mm, to_account >> PAGE_SHIFT))
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0517/1887] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (515 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0516/1887] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0518/1887] wireguard: queueing: preserve tstamp_type when encapsulating packet Greg Kroah-Hartman
` (481 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Pedro Falcato, Kiryl Shutsemau (Meta), Jose A. Perez de Azpillaga,
Anirudh Srinivasan, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 838bb60dc21553e32df90f2f3bac5b905376e7aa ]
The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.
Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.
Fix another of these - self-merge.
Self-merge occurs when a VMA is moved in front of or behind itself and the
attributes of the VMA permit such a merge.
Practically this can only happen for unfaulted anonymous VMAs due to the
page offset equality requirement for merge:
|------------|
| |
| v
|...........||-----------||...........|
| || unfaulted || |
|...........||-----------||...........|
^ |
| |
|------------|
This becomes problematic if the VMA is configured by the user to
mlock-on-fault, i.e. the VMA_LOCKED_BIT, VMA_LOCKONFAULT_BIT VMA flags are
set.
MREMAP_DONTUNMAP clears mlock flags for the source VMA and maintains them
for the destination VMA.
Self-merge makes this impossible (there is only one VMA) and incorrectly
clears the destination VMA's mlock flags.
This causes a leak in mm->locked_vm as clearing this flag does not
decrement the counter and the VMA no longer has VMA_LOCKED_BIT set so it
is not decremented on unmap.
Resolve this by simply disallowing a self-merge in this case - the source
and destination VMAs are kept distinct and then are able to have distinct
mlock() flags.
Update to make the now-redundant self-merge check a VM_WARN_ON_ONCE()
instead to guard against future regressions.
Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Cc: <stable@vger.kernel.org>
[ ljs - Converted to work with vma_merge(), tweaked commit msg. ]
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/mm.h | 2 +-
mm/mmap.c | 23 +++++++++++++++++++----
mm/mremap.c | 7 +++++--
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 4f0aa81257c58..279c121ef6b3c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2822,7 +2822,7 @@ extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void unlink_file_vma(struct vm_area_struct *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
unsigned long addr, unsigned long len, pgoff_t pgoff,
- bool *need_rmap_locks);
+ bool *need_rmap_locks, bool keep_source);
extern void exit_mmap(struct mm_struct *);
void vma_mas_store(struct vm_area_struct *vma, struct ma_state *mas);
diff --git a/mm/mmap.c b/mm/mmap.c
index d39e31f15e86c..54c73823fba33 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3337,13 +3337,14 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
*/
struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
unsigned long addr, unsigned long len, pgoff_t pgoff,
- bool *need_rmap_locks)
+ bool *need_rmap_locks, bool keep_source)
{
struct vm_area_struct *vma = *vmap;
unsigned long vma_start = vma->vm_start;
struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *new_vma, *prev;
bool faulted_in_anon_vma = true;
+ bool can_self_merge = false;
validate_mm_mt(mm);
/*
@@ -3353,15 +3354,29 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
if (unlikely(vma_is_anonymous(vma) && !vma->anon_vma)) {
pgoff = addr >> PAGE_SHIFT;
faulted_in_anon_vma = false;
+ can_self_merge = true;
}
new_vma = find_vma_prev(mm, addr, &prev);
if (new_vma && new_vma->vm_start < addr + len)
return NULL; /* should never get here */
- new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
- vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
- vma->vm_userfaultfd_ctx, anon_vma_name(vma));
+ /*
+ * If the original VMA is kept (MREMAP_DONTUNMAP), the source and
+ * destination VMA must be treated distinctly.
+ *
+ * A merge violates this, so in this case disallow a self-merge. A
+ * self-merge can only occur if the new range is immediately adjacent to
+ * the source VMA, so simply do not attempt to merge in that case.
+ */
+ if (can_self_merge && keep_source &&
+ (addr == vma->vm_end || vma->vm_start == addr + len))
+ new_vma = NULL;
+ else
+ new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
+ vma->anon_vma, vma->vm_file, pgoff,
+ vma_policy(vma), vma->vm_userfaultfd_ctx,
+ anon_vma_name(vma));
if (new_vma) {
/*
* Source vma may have been merged into new_vma
diff --git a/mm/mremap.c b/mm/mremap.c
index e1d7047f6ee5e..5eca7534e8706 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -639,7 +639,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT);
new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff,
- &need_rmap_locks);
+ &need_rmap_locks, flags & MREMAP_DONTUNMAP);
if (!new_vma) {
if (vm_flags & VM_ACCOUNT)
vm_unacct_memory(to_account >> PAGE_SHIFT);
@@ -700,6 +700,9 @@ static unsigned long move_vma(struct vm_area_struct *vma,
untrack_pfn_clear(vma);
if (unlikely(!err && (flags & MREMAP_DONTUNMAP))) {
+ /* Self-merge is disallowed. */
+ VM_WARN_ON_ONCE(new_vma == vma);
+
/* We always clear VM_LOCKED[ONFAULT] on the old vma */
vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
@@ -707,7 +710,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
* anon_vma links of the old vma is no longer needed after its page
* table has been moved.
*/
- if (new_vma != vma && vma->vm_start == old_addr &&
+ if (vma->vm_start == old_addr &&
vma->vm_end == (old_addr + old_len)) {
const pgoff_t pgoff_unfaulted = vma->vm_start >> PAGE_SHIFT;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0518/1887] wireguard: queueing: preserve tstamp_type when encapsulating packet
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (516 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0517/1887] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0519/1887] xfrm: prevent policy_hthresh.work from racing with netns teardown Greg Kroah-Hartman
` (480 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ramses de Norre,
Toke Høiland-Jørgensen, Eric Dumazet,
Jason A. Donenfeld, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ramses de Norre <ramses@well-founded.dev>
[ Upstream commit 65ab9de4bdd4c05d8277cfc20ae0b9f5aff60897 ]
Sending traffic through a wireguard tunnel on a host using the fq
qdisc fills the log with:
fq: likely mono tstamp with tstamp_type 0
An skb carries a timestamp in skb->tstamp and, separately, a
skb->tstamp_type field recording which clock that timestamp came from.
The two have to agree.
When wireguard encapsulates a packet it calls wg_reset_packet(), which
clears the fields that must not leak from the inner packet into the
tunnel packet. It does so in two steps:
skb_scrub_packet(skb, true);
memset(&skb->headers, 0, sizeof(skb->headers));
skb_scrub_packet() deliberately keeps skb->tstamp when it holds a
monotonic timestamp: that value is the time the packet is scheduled to
be sent, and the qdisc still needs it. The memset then zeroes
skb->tstamp_type, because that field sits inside the headers group
while skb->tstamp does not. The packet therefore leaves wireguard
carrying a monotonic timestamp labelled as a realtime one.
Nothing noticed until commit c4f796c4f16b ("net_sched: sch_fq: convert
skb->tstamp if not monotonic"): fq used to assume every timestamp was
monotonic. It now consults tstamp_type, spots the mismatch, warns, and
falls back to treating the value as monotonic. Pacing still ends up
correct, so the log spam is the actual problem.
Save tstamp_type before the memset and restore it when encapsulating,
next to the hash fields that are already carried over this way. When
decapsulating it stays zeroed, which is right: an incoming packet's
timestamp is a realtime receive timestamp.
Fixes: d98d58a00261 ("net: Set skb->mono_delivery_time and clear it after sch_handle_ingress()")
Signed-off-by: Ramses de Norre <ramses@well-founded.dev>
Reviewed-by: Toke Høiland-Jørgensen <toke@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261008130124.724119-3-Jason@zx2c4.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ sashal: Replaced `skb->tstamp_type` with the older `skb->mono_delivery_time` field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireguard/queueing.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h
index 3ce70db9dd3fe..50ceff8d107ec 100644
--- a/drivers/net/wireguard/queueing.h
+++ b/drivers/net/wireguard/queueing.h
@@ -78,12 +78,14 @@ static inline void wg_reset_packet(struct sk_buff *skb, bool encapsulating)
u8 l4_hash = skb->l4_hash;
u8 sw_hash = skb->sw_hash;
u32 hash = skb->hash;
+ u8 mono_delivery_time = skb->mono_delivery_time;
skb_scrub_packet(skb, true);
memset(&skb->headers, 0, sizeof(skb->headers));
if (encapsulating) {
skb->l4_hash = l4_hash;
skb->sw_hash = sw_hash;
skb->hash = hash;
+ skb->mono_delivery_time = mono_delivery_time;
}
skb->queue_mapping = 0;
skb->nohdr = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0519/1887] xfrm: prevent policy_hthresh.work from racing with netns teardown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (517 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0518/1887] wireguard: queueing: preserve tstamp_type when encapsulating packet Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0520/1887] netfilter: nf_tables: fix bidirectional offload regression Greg Kroah-Hartman
` (479 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tahera Fahimi, Allen Pais,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tahera Fahimi <taherafahimi@linux.microsoft.com>
An XFRM_MSG_NEWSPDINFO request can queue the per-net work item
policy_hthresh.work onto the system workqueue. xfrm_hash_rebuild()
retrieves the enclosing struct net from the work item, so the callback
can dereference freed memory if it runs after net namespace teardown.
Mainline commit 29fe3a61bcdc ("xfrm: prevent policy_hthresh.work
from racing with netns teardown") fixes this issue using
disable_work_sync(). That API is not available in Linux 6.1, so the
mainline change cannot be directly backported.
Provide the same guarantee with an XFRM-local work_disabled flag. Protect
the flag and schedule_work() with the existing policy_hthresh seqlock so
teardown can atomically stop new queueing attempts. Then use
cancel_work_sync() to synchronize work that was queued before the flag was
set. This ensures policy_hthresh.work cannot outlive its struct net.
Fixes: 880a6fab8f6b ("xfrm: configure policy hash table thresholds by netlink")
Assisted-by: GitHub-Copilot:GPT-5.6 Sol
Signed-off-by: Tahera Fahimi <taherafahimi@linux.microsoft.com>
Reviewed-by: Allen Pais <apais@linux.microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netns/xfrm.h | 1 +
net/xfrm/xfrm_policy.c | 19 ++++++++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 7922ec72eaa68..eb9edddd73092 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -23,6 +23,7 @@ struct xfrm_policy_hash {
struct xfrm_policy_hthresh {
struct work_struct work;
seqlock_t lock;
+ bool work_disabled;
u8 lbits4;
u8 rbits4;
u8 lbits6;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2a47f5b5776e8..76b7b94132c00 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1381,7 +1381,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
void xfrm_policy_hash_rebuild(struct net *net)
{
- schedule_work(&net->xfrm.policy_hthresh.work);
+ write_seqlock(&net->xfrm.policy_hthresh.lock);
+ if (!net->xfrm.policy_hthresh.work_disabled)
+ schedule_work(&net->xfrm.policy_hthresh.work);
+ write_sequnlock(&net->xfrm.policy_hthresh.lock);
}
EXPORT_SYMBOL(xfrm_policy_hash_rebuild);
@@ -4094,6 +4097,7 @@ static int __net_init xfrm_policy_init(struct net *net)
net->xfrm.policy_hthresh.rbits6 = 128;
seqlock_init(&net->xfrm.policy_hthresh.lock);
+ net->xfrm.policy_hthresh.work_disabled = false;
INIT_LIST_HEAD(&net->xfrm.policy_all);
INIT_LIST_HEAD(&net->xfrm.inexact_bins);
@@ -4119,6 +4123,19 @@ static void xfrm_policy_fini(struct net *net)
unsigned int sz;
int dir;
+ /* Prevent new policy hash rebuilds before draining the work item.
+ *
+ * The upstream fix uses disable_work_sync(), which is unavailable
+ * in v6.6. Protecting work_disabled and schedule_work() with the
+ * same seqlock closes the check-to-queue race, while the subsequent
+ * cancel_work_sync() drains work that was queued or running before
+ * teardown disabled it.
+ */
+ write_seqlock(&net->xfrm.policy_hthresh.lock);
+ net->xfrm.policy_hthresh.work_disabled = true;
+ write_sequnlock(&net->xfrm.policy_hthresh.lock);
+ cancel_work_sync(&net->xfrm.policy_hthresh.work);
+
flush_work(&net->xfrm.policy_hash_work);
#ifdef CONFIG_XFRM_SUB_POLICY
xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, false);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0520/1887] netfilter: nf_tables: fix bidirectional offload regression
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (518 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0519/1887] xfrm: prevent policy_hthresh.work from racing with netns teardown Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0521/1887] net: team: Remove unused team_mode_op, port_enabled Greg Kroah-Hartman
` (478 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vlad Buslov, Daniel Golle,
Felix Fietkau, Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 84443741faab9045d53f022a9ac6a6633067a481 ]
Commit 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
made unidirectional flow offload possible, while completely ignoring (and
breaking) bidirectional flow offload for nftables.
Add the missing flag that was left out as an exercise for the reader :)
Cc: Vlad Buslov <vladbu@nvidia.com>
Fixes: 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules")
Reported-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_flow_offload.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 4bc2664f33958..c65175ef47816 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -374,6 +374,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
if (tcph)
flow_offload_ct_tcp(ct);
+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
ret = flow_offload_add(flowtable, flow);
if (ret < 0)
goto err_flow_add;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0521/1887] net: team: Remove unused team_mode_op, port_enabled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (519 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0520/1887] netfilter: nf_tables: fix bidirectional offload regression Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0522/1887] net: team: Rename port_disabled team mode op to port_tx_disabled Greg Kroah-Hartman
` (477 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiri Pirko, Marc Harvey,
Kuniyuki Iwashima, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Harvey <marcharvey@google.com>
[ Upstream commit 014f249121d73909528df320818fba7693d0ec92 ]
This team_mode_op wasn't used by any of the team modes, so remove it.
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Marc Harvey <marcharvey@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-2-f47e7589685d@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: b7454f1940c5 ("net: team: stop reusing skb after queue override")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 2 --
include/linux/if_team.h | 1 -
2 files changed, 3 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index ea2a7cea3f6a0..32ca12211e7e6 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -945,8 +945,6 @@ static void team_port_enable(struct team *team,
team_port_index_hash(team, port->index));
team_adjust_ops(team);
team_queue_override_port_add(team, port);
- if (team->ops.port_enabled)
- team->ops.port_enabled(team, port);
team_notify_peers(team);
team_mcast_rejoin(team);
team_lower_state_changed(port);
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 34bcba5a70677..1e378d3a7eaa0 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -121,7 +121,6 @@ struct team_mode_ops {
int (*port_enter)(struct team *team, struct team_port *port);
void (*port_leave)(struct team *team, struct team_port *port);
void (*port_change_dev_addr)(struct team *team, struct team_port *port);
- void (*port_enabled)(struct team *team, struct team_port *port);
void (*port_disabled)(struct team *team, struct team_port *port);
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0522/1887] net: team: Rename port_disabled team mode op to port_tx_disabled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (520 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0521/1887] net: team: Remove unused team_mode_op, port_enabled Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0523/1887] net: team: fix NULL pointer dereference in team_xmit during mode change Greg Kroah-Hartman
` (476 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiri Pirko, Marc Harvey,
Kuniyuki Iwashima, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Harvey <marcharvey@google.com>
[ Upstream commit cfa477df2cc62ba53cb936669886361152b594a7 ]
This team mode op is only used by the load balance mode, and it only
uses it in the tx path.
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Marc Harvey <marcharvey@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-3-f47e7589685d@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: b7454f1940c5 ("net: team: stop reusing skb after queue override")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 4 ++--
drivers/net/team/team_mode_loadbalance.c | 4 ++--
include/linux/if_team.h | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 32ca12211e7e6..b552c79411254 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -969,8 +969,8 @@ static void team_port_disable(struct team *team,
{
if (!team_port_enabled(port))
return;
- if (team->ops.port_disabled)
- team->ops.port_disabled(team, port);
+ if (team->ops.port_tx_disabled)
+ team->ops.port_tx_disabled(team, port);
hlist_del_rcu(&port->hlist);
__reconstruct_port_hlist(team, port->index);
port->index = -1;
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
index b095a4b4957bb..89ee6bee049c1 100644
--- a/drivers/net/team/team_mode_loadbalance.c
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -672,7 +672,7 @@ static void lb_port_leave(struct team *team, struct team_port *port)
free_percpu(lb_port_priv->pcpu_stats);
}
-static void lb_port_disabled(struct team *team, struct team_port *port)
+static void lb_port_tx_disabled(struct team *team, struct team_port *port)
{
lb_tx_hash_to_port_mapping_null_port(team, port);
}
@@ -682,7 +682,7 @@ static const struct team_mode_ops lb_mode_ops = {
.exit = lb_exit,
.port_enter = lb_port_enter,
.port_leave = lb_port_leave,
- .port_disabled = lb_port_disabled,
+ .port_tx_disabled = lb_port_tx_disabled,
.receive = lb_receive,
.transmit = lb_transmit,
};
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 1e378d3a7eaa0..7a69cd251bfb3 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -121,7 +121,7 @@ struct team_mode_ops {
int (*port_enter)(struct team *team, struct team_port *port);
void (*port_leave)(struct team *team, struct team_port *port);
void (*port_change_dev_addr)(struct team *team, struct team_port *port);
- void (*port_disabled)(struct team *team, struct team_port *port);
+ void (*port_tx_disabled)(struct team *team, struct team_port *port);
};
extern int team_modeop_port_enter(struct team *team, struct team_port *port);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0523/1887] net: team: fix NULL pointer dereference in team_xmit during mode change
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (521 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0522/1887] net: team: Rename port_disabled team mode op to port_tx_disabled Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0524/1887] net: team: stop reusing skb after queue override Greg Kroah-Hartman
` (475 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi, Jiayuan Chen,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit 25fe708bbc59289d3d1ea4b126fbc1b460a072a5 ]
__team_change_mode() clears team->ops with memset() before restoring
safe dummy handlers via team_adjust_ops(). A concurrent team_xmit()
running under RCU on another CPU can read team->ops.transmit during
this window and call a NULL function pointer, crashing the kernel.
The race requires a mode change (CAP_NET_ADMIN) concurrent with
transmit on the team device.
BUG: kernel NULL pointer dereference, address: 0000000000000000
Oops: 0010 [#1] SMP KASAN NOPTI
RIP: 0010:0x0
Call Trace:
team_xmit (drivers/net/team/team_core.c:1853)
dev_hard_start_xmit (net/core/dev.c:3904)
__dev_queue_xmit (net/core/dev.c:4871)
packet_sendmsg (net/packet/af_packet.c:3109)
__sys_sendto (net/socket.c:2265)
The original code assumed that no ports means no traffic, so mode
changes could freely memset()/memcpy() the ops. AF_PACKET with
forced carrier breaks that assumption.
Prevent the race instead of making it safe: replace memset()/memcpy()
with per-field updates that never touch transmit or receive. Those
two handlers are managed solely by team_adjust_ops(), which already
installs dummies when tx_en_port_count == 0 (always true during mode
change since no ports are present). WRITE_ONCE/READ_ONCE prevent
store/load tearing on the handler pointers.
synchronize_net() before exit_op() drains in-flight readers that may
still reference old mode state from before port removal switched the
handlers to dummies.
Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260521081159.1491563-3-bestswngs@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: b7454f1940c5 ("net: team: stop reusing skb after queue override")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 45 +++++++++++++++++++++++++++++------------
1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index b552c79411254..1812b8b2f73a6 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -535,21 +535,23 @@ static void team_adjust_ops(struct team *team)
if (!team->en_port_count || !team_is_mode_set(team) ||
!team->mode->ops->transmit)
- team->ops.transmit = team_dummy_transmit;
+ WRITE_ONCE(team->ops.transmit, team_dummy_transmit);
else
- team->ops.transmit = team->mode->ops->transmit;
+ WRITE_ONCE(team->ops.transmit, team->mode->ops->transmit);
if (!team->en_port_count || !team_is_mode_set(team) ||
!team->mode->ops->receive)
- team->ops.receive = team_dummy_receive;
+ WRITE_ONCE(team->ops.receive, team_dummy_receive);
else
- team->ops.receive = team->mode->ops->receive;
+ WRITE_ONCE(team->ops.receive, team->mode->ops->receive);
}
/*
- * We can benefit from the fact that it's ensured no port is present
- * at the time of mode change. Therefore no packets are in fly so there's no
- * need to set mode operations in any special way.
+ * team_change_mode() ensures no ports are present during mode change,
+ * but lockless readers can still reach team_xmit(). Avoid touching
+ * transmit/receive -- they are already set to dummies by
+ * team_adjust_ops() since no ports are enabled. synchronize_net()
+ * drains in-flight readers before destroying old mode state.
*/
static int __team_change_mode(struct team *team,
const struct team_mode *new_mode)
@@ -558,9 +560,21 @@ static int __team_change_mode(struct team *team,
if (team_is_mode_set(team)) {
void (*exit_op)(struct team *team) = team->ops.exit;
- /* Clear ops area so no callback is called any longer */
- memset(&team->ops, 0, sizeof(struct team_mode_ops));
- team_adjust_ops(team);
+ /* Clear cold-path ops used only under RTNL. transmit and
+ * receive are already dummies (no ports) so leave them
+ * alone -- overwriting them is the source of the race.
+ */
+ team->ops.init = NULL;
+ team->ops.exit = NULL;
+ team->ops.port_enter = NULL;
+ team->ops.port_leave = NULL;
+ team->ops.port_change_dev_addr = NULL;
+ team->ops.port_tx_disabled = NULL;
+
+ /* Wait for in-flight readers before tearing down mode
+ * state they may reference.
+ */
+ synchronize_net();
if (exit_op)
exit_op(team);
@@ -583,7 +597,12 @@ static int __team_change_mode(struct team *team,
}
team->mode = new_mode;
- memcpy(&team->ops, new_mode->ops, sizeof(struct team_mode_ops));
+ team->ops.init = new_mode->ops->init;
+ team->ops.exit = new_mode->ops->exit;
+ team->ops.port_enter = new_mode->ops->port_enter;
+ team->ops.port_leave = new_mode->ops->port_leave;
+ team->ops.port_change_dev_addr = new_mode->ops->port_change_dev_addr;
+ team->ops.port_tx_disabled = new_mode->ops->port_tx_disabled;
team_adjust_ops(team);
return 0;
@@ -744,7 +763,7 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
/* allow exact match delivery for disabled ports */
res = RX_HANDLER_EXACT;
} else {
- res = team->ops.receive(team, port, skb);
+ res = READ_ONCE(team->ops.receive)(team, port, skb);
}
if (res == RX_HANDLER_ANOTHER) {
struct team_pcpu_stats *pcpu_stats;
@@ -1742,7 +1761,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
tx_success = team_queue_override_transmit(team, skb);
if (!tx_success)
- tx_success = team->ops.transmit(team, skb);
+ tx_success = READ_ONCE(team->ops.transmit)(team, skb);
if (tx_success) {
struct team_pcpu_stats *pcpu_stats;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0524/1887] net: team: stop reusing skb after queue override
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (522 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0523/1887] net: team: fix NULL pointer dereference in team_xmit during mode change Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0525/1887] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex Greg Kroah-Hartman
` (474 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+2cf741c3005abc20, Weiming Shi,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit b7454f1940c5e6d92e753853c476a769e452f30a ]
A nonzero dev_queue_xmit() result does not return ownership of the skb.
When an override port's qdisc drops it, the queue override helper used to
try another port or the mode transmit op with the freed skb.
Return the handoff decision separately from transmit success. Select only
the first override port under RCU and stop after handing it the skb,
regardless of the lower transmit result. Keep the existing success and
drop accounting.
BUG: KASAN: slab-use-after-free in sk_skb_reason_drop
Write of size 4 by task poc/5040
sk_skb_reason_drop (net/core/skbuff.c:1240)
dev_kfree_skb_any_reason (net/core/dev.c:3470)
ab_transmit (drivers/net/team/team_mode_activebackup.c:49)
team_xmit (drivers/net/team/team_core.c:1849)
__dev_direct_xmit (net/core/dev.c:4934)
Freed by task 5040:
__tcf_kfree_skb_list (net/sched/sch_generic.c:43)
__dev_queue_xmit (net/core/dev.c:4831)
team_xmit (drivers/net/team/team_core.c:1846)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Cc: stable@vger.kernel.org
Fixes: 8ff5105a2b9d ("team: add support for queue override by setting queue_id for port")
Reported-by: <co+2cf741c3005abc20@bugs.sh>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20261001182326.572045-2-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 1812b8b2f73a6..874a8b78803c4 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -822,7 +822,8 @@ static struct list_head *__team_get_qom_list(struct team *team, u16 queue_id)
/*
* note: already called with rcu_read_lock
*/
-static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
+static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb,
+ bool *tx_success)
{
struct list_head *qom_list;
struct team_port *port;
@@ -830,11 +831,11 @@ static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
if (!team->queue_override_enabled || !skb->queue_mapping)
return false;
qom_list = __team_get_qom_list(team, skb->queue_mapping);
- list_for_each_entry_rcu(port, qom_list, qom_list) {
- if (!team_dev_queue_xmit(team, port, skb))
- return true;
- }
- return false;
+ port = list_first_or_null_rcu(qom_list, struct team_port, qom_list);
+ if (!port)
+ return false;
+ *tx_success = !team_dev_queue_xmit(team, port, skb);
+ return true;
}
static void __team_queue_override_port_del(struct team *team,
@@ -1759,8 +1760,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
bool tx_success;
unsigned int len = skb->len;
- tx_success = team_queue_override_transmit(team, skb);
- if (!tx_success)
+ if (!team_queue_override_transmit(team, skb, &tx_success))
tx_success = READ_ONCE(team->ops.transmit)(team, skb);
if (tx_success) {
struct team_pcpu_stats *pcpu_stats;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0525/1887] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (523 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0524/1887] net: team: stop reusing skb after queue override Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0526/1887] drm/vmwgfx: validate pitch coming from userspace Greg Kroah-Hartman
` (473 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
syzbot+74071deb72339c215b2e, Jiaming Zhang, Mikhail Gavrilov,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
[ Upstream commit ac022970e9fb0a5f7e7d1f6c8e104c1ed924dd1c ]
An RFCOMM connect() issued while a BR/EDR link is being authenticated
makes lockdep report a circular dependency, and the reported cycle is a
real AB/BA between rfcomm_mutex and hdev->lock.
rfcomm_security_cfm() is called from the HCI event path, which already
holds hdev->lock:
hci_rx_work()
hci_event_packet()
hci_cc_read_enc_key_size() [hdev->lock]
hci_encrypt_cfm() [hci_cb_list_lock]
rfcomm_security_cfm() [rfcomm_mutex]
while an RFCOMM connect() from userspace takes the same two locks the
other way round:
rfcomm_sock_connect()
rfcomm_dlc_open() [rfcomm_mutex]
__rfcomm_dlc_open()
rfcomm_session_create()
kernel_connect()
l2cap_sock_connect()
l2cap_chan_connect() [hdev->lock]
WARNING: possible circular locking dependency detected
kworker/u131:1/1128 is trying to acquire lock:
rfcomm_mutex, at: rfcomm_security_cfm+0x31/0x3e0 [rfcomm]
but task is already holding lock:
hci_cb_list_lock, at: hci_cc_read_enc_key_size+0x1d2/0xcc0
Chain exists of:
rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock
hci_auth_complete_evt() and hci_encrypt_change_evt() reach the callback
the same way.
Both orders have to be seen in the same boot, which is why a BR/EDR
connection alone is not enough to show it: a session set up by the
remote side is created by rfcomm_accept_connection() in krfcommd, which
calls kernel_accept() and never takes hdev->lock under rfcomm_mutex.
Connecting a device that authenticates and encrypts the link and then
calling connect() on an RFCOMM socket towards any address - the connect
does not have to succeed, the order is recorded before the page timeout
- reports it every time.
Only the session socket has to be connected with the lock held, and it
does not: nothing else can see the socket before it is put on the
session list. So connect it first and take rfcomm_mutex afterwards,
which removes the rfcomm_mutex -> hdev->lock order for good, rather
than keeping the HCI event path out of rfcomm_mutex.
rfcomm_session_create() becomes rfcomm_session_connect(), which returns
the connected socket without touching the session list, and
rfcomm_dlc_open() adds the session once it holds the lock again. If
another opener added a session for the same pair while this socket was
connecting, that session is used and this socket is dropped.
__rfcomm_dlc_open() now takes the session it should use, and its state
check runs after the lock is re-acquired, so a DLC that was opened or
closed in the meantime is still handled.
Over an existing ACL link the connection can complete before the
session reaches the list, and the wakeup from the socket callback is
then lost, so krfcommd is woken once the session is visible.
Connecting without the lock opens a window in which the socket can be
closed. The DLC is not on a session yet, so rfcomm_dlc_close() finds
nothing to do and returns without touching it, and rfcomm_dlc_open()
would then attach a DLC whose owner is gone. rfcomm_dlc_close() now
marks such a DLC with RFCOMM_CLOSED, and rfcomm_dlc_open() checks the
mark once it holds rfcomm_mutex again and drops the socket instead of
attaching the DLC. The mark is cleared when an open starts, so a DLC
that is reused is not affected. This covers both callers of
rfcomm_dlc_open(), the socket and the tty layer.
Fixes: 759c185d0bbd ("Bluetooth: RFCOMM: serialize security confirmation handling")
Suggested-by: Pauli Virtanen <pav@iki.fi>
Reported-by: Pauli Virtanen <pav@iki.fi>
Closes: https://lore.kernel.org/linux-bluetooth/5e76a95e934e451e7006db28827c2d64af5a88be.camel@iki.fi/
Reported-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-bluetooth/6a92fadc.08e933ee.dbf97.008f.GAE@google.com/
Reported-by: Jiaming Zhang <r772577952@gmail.com>
Closes: https://lore.kernel.org/all/CANypQFabseTuRiyz2pGkc_Qj0moGDnY7KEp1qdTOqkw6gAL3hw@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tested-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ sashal: Changed the kernel_connect() address cast from struct sockaddr_unsized to struct sockaddr. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/bluetooth/rfcomm.h | 1 +
net/bluetooth/rfcomm/core.c | 134 +++++++++++++++++++++++----------
2 files changed, 96 insertions(+), 39 deletions(-)
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index ba8d3702853d2..d483830188f38 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -210,6 +210,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
#define RFCOMM_ENC_DROP 9
+#define RFCOMM_CLOSED 10
/* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 6324e03ff0d07..1e21e1e38543f 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -63,10 +63,9 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
static void rfcomm_process_connect(struct rfcomm_session *s);
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
- bdaddr_t *dst,
- u8 sec_level,
- int *err);
+static struct socket *rfcomm_session_connect(bdaddr_t *src, bdaddr_t *dst,
+ u8 sec_level, int *err);
+static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
@@ -364,28 +363,17 @@ static int rfcomm_check_channel(u8 channel)
return channel < 1 || channel > 30;
}
-static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, struct rfcomm_session *s,
+ u8 channel)
{
- struct rfcomm_session *s;
- int err = 0;
u8 dlci;
- BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
- d, d->state, src, dst, channel);
-
- if (rfcomm_check_channel(channel))
- return -EINVAL;
+ BT_DBG("dlc %p state %ld session %p channel %d",
+ d, d->state, s, channel);
if (d->state != BT_OPEN && d->state != BT_CLOSED)
return 0;
- s = rfcomm_session_get(src, dst);
- if (!s) {
- s = rfcomm_session_create(src, dst, d->sec_level, &err);
- if (!s)
- return err;
- }
-
dlci = __dlci(__session_dir(s), channel);
/* Check if DLCI already exists */
@@ -420,14 +408,84 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
{
- int r;
+ struct rfcomm_session *s;
+ struct socket *sock;
+ int err;
+
+ BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
+ d, d->state, src, dst, channel);
+
+ if (rfcomm_check_channel(channel))
+ return -EINVAL;
rfcomm_lock();
- r = __rfcomm_dlc_open(d, src, dst, channel);
+ clear_bit(RFCOMM_CLOSED, &d->flags);
+ /* Do not page the remote device for a DLC that cannot be opened
+ * anyway. __rfcomm_dlc_open() looks at the state again once the
+ * lock has been re-acquired below.
+ */
+ if (d->state != BT_OPEN && d->state != BT_CLOSED) {
+ rfcomm_unlock();
+ return 0;
+ }
+
+ s = rfcomm_session_get(src, dst);
+ if (s) {
+ err = __rfcomm_dlc_open(d, s, channel);
+ rfcomm_unlock();
+ return err;
+ }
rfcomm_unlock();
- return r;
+
+ /* There is no session for this pair yet. kernel_connect() ends up in
+ * l2cap_chan_connect(), which takes hdev->lock, and the HCI event
+ * path takes rfcomm_mutex while holding hdev->lock, so the socket has
+ * to be connected with rfcomm_mutex released.
+ */
+ sock = rfcomm_session_connect(src, dst, d->sec_level, &err);
+ if (!sock)
+ return err;
+
+ rfcomm_lock();
+
+ /* The DLC may have been closed while the socket was connecting. It
+ * was not on a session, so rfcomm_dlc_close() could only mark it;
+ * attaching it now would leave it with no owner.
+ */
+ if (test_bit(RFCOMM_CLOSED, &d->flags)) {
+ rfcomm_unlock();
+ sock_release(sock);
+ return -ECONNRESET;
+ }
+
+ /* Another opener may have added a session for the same pair in the
+ * meantime; that one is used and this socket is dropped.
+ */
+ s = rfcomm_session_get(src, dst);
+ if (!s) {
+ s = rfcomm_session_add(sock, BT_BOUND);
+ if (s) {
+ s->initiator = 1;
+ sock = NULL;
+ }
+ }
+
+ err = s ? __rfcomm_dlc_open(d, s, channel) : -ENOMEM;
+
+ rfcomm_unlock();
+
+ if (sock)
+ sock_release(sock);
+
+ /* Over an existing ACL link the connection can complete before the
+ * session reaches the list, and that wakeup is then lost, so let
+ * krfcommd look at the socket state now.
+ */
+ rfcomm_schedule();
+
+ return err;
}
static void __rfcomm_dlc_disconn(struct rfcomm_dlc *d)
@@ -507,8 +565,14 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
rfcomm_lock();
s = d->session;
- if (!s)
+ if (!s) {
+ /* Not on a session yet: rfcomm_dlc_open() may be connecting a
+ * socket for it with rfcomm_mutex released. Leave a mark so
+ * that it does not attach the DLC once it holds the lock again.
+ */
+ set_bit(RFCOMM_CLOSED, &d->flags);
goto no_session;
+ }
/* after waiting on the mutex check the session still exists
* then check the dlc still exists
@@ -756,12 +820,12 @@ static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
return rfcomm_session_del(s);
}
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
- bdaddr_t *dst,
- u8 sec_level,
- int *err)
+/* Creates the L2CAP socket a new session will run on and starts connecting
+ * it. Must be called with rfcomm_mutex released.
+ */
+static struct socket *rfcomm_session_connect(bdaddr_t *src, bdaddr_t *dst,
+ u8 sec_level, int *err)
{
- struct rfcomm_session *s = NULL;
struct sockaddr_l2 addr;
struct socket *sock;
struct sock *sk;
@@ -791,24 +855,16 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
release_sock(sk);
- s = rfcomm_session_add(sock, BT_BOUND);
- if (!s) {
- *err = -ENOMEM;
- goto failed;
- }
-
- s->initiator = 1;
-
bacpy(&addr.l2_bdaddr, dst);
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = cpu_to_le16(L2CAP_PSM_RFCOMM);
addr.l2_cid = 0;
addr.l2_bdaddr_type = BDADDR_BREDR;
*err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
- if (*err == 0 || *err == -EINPROGRESS)
- return s;
+ if (*err && *err != -EINPROGRESS)
+ goto failed;
- return rfcomm_session_del(s);
+ return sock;
failed:
sock_release(sock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0526/1887] drm/vmwgfx: validate pitch coming from userspace
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (524 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0525/1887] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0527/1887] Bluetooth: ISO: Serialize concurrent connect calls Greg Kroah-Hartman
` (472 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Youness HFA, Zack Rusin,
Maaz Mombasawala, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin <zack.rusin@broadcom.com>
[ Upstream commit 21bc51cb89ced74d6645a138cc2f21184bc75094 ]
Validate the pitch, alongside the box dimensions before trying
to copy data from the underlying surface. Fixes possible
out of bounds reads with cursor snooping.
Fixes: 2ac863719e51 ("vmwgfx: Snoop DMA transfers with non-covering sizes")
Cc: stable@vger.kernel.org
Reported-by: Youness HFA <hfa.youness@gmail.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Reviewed-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
Link: https://patch.msgid.link/20260809204515.211045-1-zack.rusin@broadcom.com
[ sashal: Adapted the changes to the existing cursor snooping function using fixed 64×64 dimensions and four-byte pixels. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 5210b8084217c..38abdaf663ff6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -277,6 +277,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
unsigned long kmap_num;
SVGA3dCopyBox *box;
unsigned box_count;
+ u64 src_extent;
void *virtual;
bool dummy;
struct vmw_dma_cmd {
@@ -285,6 +286,8 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
} *cmd;
int i, ret;
+ BUILD_BUG_ON(sizeof(*srf->snooper.image) != 4);
+
cmd = container_of(header, struct vmw_dma_cmd, header);
/* No snooper installed */
@@ -322,8 +325,19 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
return;
}
+ if (box->w == 0 || box->h == 0)
+ return;
+
+ src_extent = (u64)(box->h - 1) * cmd->dma.guest.pitch +
+ (u64)box->w * 4;
+ if (src_extent > bo->base.size) {
+ DRM_ERROR("Cursor snoop source of %llu bytes exceeds the %zu byte buffer\n",
+ src_extent, bo->base.size);
+ return;
+ }
+
kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
- kmap_num = (64*64*4) >> PAGE_SHIFT;
+ kmap_num = PFN_UP(src_extent);
ret = ttm_bo_reserve(bo, true, false, NULL);
if (unlikely(ret != 0)) {
@@ -337,13 +351,13 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
virtual = ttm_kmap_obj_virtual(&map, &dummy);
- if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
+ if (box->w == 64 && box->h == 64 && cmd->dma.guest.pitch == 64*4) {
memcpy(srf->snooper.image, virtual, 64*64*4);
} else {
- /* Image is unsigned pointer. */
+ /* The destination stride is in pixels. */
for (i = 0; i < box->h; i++)
memcpy(srf->snooper.image + i * 64,
- virtual + i * cmd->dma.guest.pitch,
+ virtual + (size_t)i * cmd->dma.guest.pitch,
box->w * 4);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0527/1887] Bluetooth: ISO: Serialize concurrent connect calls
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (525 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0526/1887] drm/vmwgfx: validate pitch coming from userspace Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0528/1887] namespace: dont inherit MNT_UMOUNT in clone_mnt() Greg Kroah-Hartman
` (471 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen, Chengfeng Ye,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
[ Upstream commit e32d80293a0e1a160d5e5101daa8c82148c07510 ]
iso_sock_connect() checks the socket state before taking the socket lock
and drops the lock again before setting up a connection. Two callers can
both pass the admission check while the socket is open or bound.
Caller A can copy its destination for route selection, then caller B can
replace the socket destination before A binds or connects the CIS. A
then uses B's destination with the route selected for its own request.
B can also proceed after A attaches a connection and sets BT_CONNECT.
For deferred BIS setup, B can bind a second BIS and overwrite
iso_pi(sk)->conn, leaving the first connection's reference and conn->sk
back-pointer stranded. Concurrent CIS connects can likewise replace the
socket's connection. Later teardown only detaches the current connection,
so a callback on the old connection can race with socket release and
access a freed socket.
KASAN reported:
BUG: KASAN: slab-use-after-free in iso_sock_hold+0xf7/0x1b0
Call Trace:
iso_sock_hold+0xf7/0x1b0
iso_conn_del+0x7b/0x1d0
iso_connect_cfm+0x186/0x16a0
hci_conn_failed+0x154/0x280
hci_abort_conn_sync+0x3dc/0x7d0
hci_cmd_sync_work+0x173/0x300
Allocated by task 121:
sk_alloc+0x2b/0x6d0
bt_sock_alloc+0x29/0x370
iso_sock_alloc.constprop.0+0x19/0x300
iso_sock_create+0x94/0x100
Freed by task 121:
kfree+0x121/0x3c0
__sk_destruct+0x42b/0x540
iso_sock_release+0x29d/0x340
__sock_release+0xa1/0x260
Check admission under the socket lock and mark the connect operation in
progress before publishing its destination. Keep that flag set across
route lookup and connection setup, rejecting another connect with
-EBADFD before it can change the destination or attach a connection.
Clear the flag after either helper returns, including on failure, so a
failed setup can be retried.
A separate flag is needed because the socket lock must be released before
acquiring the HCI device lock, while BT_CONNECT requires an attached
connection. Keep the existing state transitions and the deferred CIS
completion through iso_sock_recvmsg().
Reject an existing socket attachment in __iso_chan_add() before taking
a new reference or publishing either pointer, so every caller preserves
the connection association. Keep the same-socket, same-connection success
case for deferred CIS setup. Reject an attached socket before BIS setup
so a reusable BIS is not claimed before the attachment is rejected.
In CIS setup, reject a different HCI connection before iso_conn_add()
and drop the per-attempt HCI hold directly. An unowned iso_conn may still
carry another reference after detachment, so its destruction cannot be
relied on to release that hold.
iso_listen_bis() creates a fresh PA HCI/ISO pair under the device lock,
so the temporary iso_conn_put() frees the ISO candidate and drops its
HCI hold on rejection. iso_conn_ready() uses a freshly allocated,
unpublished child with no connection, making the socket-side rejection
unreachable.
Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Cc: stable@vger.kernel.org
Suggested-by: Pauli Virtanen <pav@iki.fi>
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ sashal: adapted attachment checks to direct connection assignment by moving socket locking earlier. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/iso.c | 73 +++++++++++++++++++++++++++++----------------
1 file changed, 48 insertions(+), 25 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 7ffb47a12dd3d..d809c5c13319c 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -49,6 +49,11 @@ static void iso_sock_kill(struct sock *sk);
#define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
#define EIR_BAA_SERVICE_UUID 0x1851
+/* iso_pinfo flags values */
+enum {
+ BT_SK_CONNECTING,
+};
+
struct iso_pinfo {
struct bt_sock bt;
bdaddr_t src;
@@ -59,7 +64,7 @@ struct iso_pinfo {
__u8 bc_num_bis;
__u8 bc_bis[ISO_MAX_NUM_BIS];
__u16 sync_handle;
- __u32 flags;
+ unsigned long flags;
struct bt_iso_qos qos;
__u8 base_len;
__u8 base[BASE_MAX_LENGTH];
@@ -225,6 +230,9 @@ static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
return -EBUSY;
}
+ if (iso_pi(sk)->conn)
+ return -EISCONN;
+
iso_pi(sk)->conn = conn;
conn->sk = sk;
@@ -269,6 +277,12 @@ static int iso_connect_bis(struct sock *sk)
return -EHOSTUNREACH;
hci_dev_lock(hdev);
+ lock_sock(sk);
+
+ if (iso_pi(sk)->conn) {
+ err = -EISCONN;
+ goto unlock;
+ }
if (!bis_capable(hdev)) {
err = -EOPNOTSUPP;
@@ -296,13 +310,9 @@ static int iso_connect_bis(struct sock *sk)
goto unlock;
}
- lock_sock(sk);
-
err = iso_chan_add(conn, sk, NULL);
- if (err) {
- release_sock(sk);
+ if (err)
goto unlock;
- }
/* Update source addr of the socket */
bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -315,9 +325,8 @@ static int iso_connect_bis(struct sock *sk)
iso_sock_set_timer(sk, sk->sk_sndtimeo);
}
- release_sock(sk);
-
unlock:
+ release_sock(sk);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -338,6 +347,7 @@ static int iso_connect_cis(struct sock *sk)
return -EHOSTUNREACH;
hci_dev_lock(hdev);
+ lock_sock(sk);
if (!cis_central_capable(hdev)) {
err = -EOPNOTSUPP;
@@ -369,6 +379,13 @@ static int iso_connect_cis(struct sock *sk)
}
}
+ /* The socket lock keeps the current attachment and its hcon stable. */
+ if (iso_pi(sk)->conn && iso_pi(sk)->conn->hcon != hcon) {
+ hci_conn_drop(hcon);
+ err = -EISCONN;
+ goto unlock;
+ }
+
conn = iso_conn_add(hcon);
if (!conn) {
hci_conn_drop(hcon);
@@ -376,13 +393,9 @@ static int iso_connect_cis(struct sock *sk)
goto unlock;
}
- lock_sock(sk);
-
err = iso_chan_add(conn, sk, NULL);
- if (err) {
- release_sock(sk);
+ if (err)
goto unlock;
- }
/* Update source addr of the socket */
bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -398,9 +411,8 @@ static int iso_connect_cis(struct sock *sk)
iso_sock_set_timer(sk, sk->sk_sndtimeo);
}
- release_sock(sk);
-
unlock:
+ release_sock(sk);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -847,17 +859,26 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
- return -EBADFD;
+ lock_sock(sk);
- if (sk->sk_type != SOCK_SEQPACKET)
- return -EINVAL;
+ if ((sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) ||
+ test_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags)) {
+ err = -EBADFD;
+ goto done;
+ }
+
+ if (sk->sk_type != SOCK_SEQPACKET) {
+ err = -EINVAL;
+ goto done;
+ }
/* Check if the address type is of LE type */
- if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
- return -EINVAL;
+ if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
+ err = -EINVAL;
+ goto done;
+ }
- lock_sock(sk);
+ set_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags);
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
@@ -869,16 +890,18 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
else
err = iso_connect_bis(sk);
- if (err)
- return err;
-
lock_sock(sk);
+ clear_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags);
+ if (err)
+ goto done;
+
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
}
+done:
release_sock(sk);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0528/1887] namespace: dont inherit MNT_UMOUNT in clone_mnt()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (526 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0527/1887] Bluetooth: ISO: Serialize concurrent connect calls Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0529/1887] namespace: check the mounts before reading their parents in pivot_root() Greg Kroah-Hartman
` (470 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit e2c6d326216642011da318b9edfd5d57ebd5a56f ]
MNT_UMOUNT gets raised on a mount that umount_tree() or umount_one() has
taken out of its namespace. It's never cleared. __detach_mounts()
unhooks a mount that carries it instead of unmounting it.
disconnect_mount() lets an unmounted child stay attached only if its
parent carries it. propagate_umount() takes it as the sign that a mount
is going to be unmounted when it decides what else can be unmounted,
where a chain of locked mounts ends and where a for reparenting an
overmount.
clone_mnt() copies the flags of the source and only masks
MNT_INTERNAL_FLAGS which doesn't include MNT_UMOUNT. A mount that was
lazily unmounted but is kept alive by a file descriptor can still be
copied when its root is an nsfs or pidfs file because may_copy_tree()
accepts those before checking whether the source is mounted at all:
mount --bind /proc/self/ns/net /tmp/x
exec 3< /tmp/x
umount -l /tmp/x
mount --bind /proc/self/fd/3 /tmp/y
The mount on /tmp/y is attached to the caller's namespace with
MNT_UMOUNT already set and every copy of it inherits the flag again.
That causes a number of bugs:
- Unlink its mountpoint from a mount namespace where it isn't one.
__detach_mounts() takes it for a mount that was unmounted earlier,
unhooks it from its parent and drops the reference the namespace
holds on it. It stays in the namespace with one reference too few
and as its own parent, so it can't be unmounted through the file
descriptor anymore and the namespace never finds it again. When the
namespace goes away it's leaked and points to a freed struct
mnt_namespace that may_change_propagation() and anon_ns_root() read
on the next propagation change or mount_setattr() through the file
descriptor.
- Make it shared and unmount a peer. trace_transfers() follows the
flag from the peer into it and strips it from its peer group.
- Let a propagated umount reach it. gather_candidates() marks it with
T_UMOUNT_CANDIDATE but never puts it on the candidate list, so the
mark is never cleared and every later propagated umount skips it. If
it's the parent of a locked mount handle_locked() takes it as the
cutoff and commits the locked child that should have stayed and
disconnect_mount() leaves that child attached to it, unmounted under
a mounted parent, which is what disconnect_mount() exists to
prevent. When the namespace goes away umount_tree() visits the child
a second time. And once __detach_mounts() has made it its own parent
reparent() never finds the end of the chain of unmounted parents.
A clone is a new mount that has never been unmounted. Add MNT_UMOUNT
to MNT_INTERNAL_FLAGS so clone_mnt() never copies it. And warn when
umount_tree() reaches a mount that already has it set.
Fixes: 590ce4bcbfb4 ("mnt: Add MNT_UMOUNT flag")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-3-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: adapted mount-flag handling to the explicit flag-clearing mask in clone_mnt() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 4 +++-
include/linux/mount.h | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 42ecf070b6f76..2492d5286cef6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1122,7 +1122,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
}
mnt->mnt.mnt_flags = old->mnt.mnt_flags;
- mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
+ mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL|MNT_UMOUNT);
atomic_inc(&sb->s_active);
mnt->mnt.mnt_userns = mnt_user_ns(&old->mnt);
@@ -1561,6 +1561,8 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
/* Gather the mounts to umount */
for (p = mnt; p; p = next_mnt(p, mnt)) {
+ /* A mount is unmounted once. */
+ WARN_ON_ONCE(p->mnt.mnt_flags & MNT_UMOUNT);
p->mnt.mnt_flags |= MNT_UMOUNT;
list_move(&p->mnt_list, &tmp_list);
}
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 55a4abaf67155..76c21958e8426 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -50,7 +50,7 @@ struct path;
#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED | \
- MNT_CURSOR)
+ MNT_CURSOR | MNT_UMOUNT)
#define MNT_INTERNAL 0x4000
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0529/1887] namespace: check the mounts before reading their parents in pivot_root()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (527 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0528/1887] namespace: dont inherit MNT_UMOUNT in clone_mnt() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0530/1887] dm: fix reading free memory in do_resume Greg Kroah-Hartman
` (469 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 6b7c001eb5857fa09041f47673666060a2e5fc1c ]
path_pivot_root() reads the parents of new_root and of the caller's root
and checks whether they are shared before it checks that either mount is
in the caller's mount namespace. Only namespace_sem is held. That's fine
for a mount that is in the caller's mount namespace.
But new_root can be a file descriptor to a mount that has been unmounted
and that only the file descriptor keeps alive. If that mount stayed
attached to its parent when it was unmounted nothing pins the parent for
it. The final mntput() of the parent unhooks the children under
mount_lock alone and frees the parent afterwards:
pivot_root() close(fd), last ref on the parent
------------ ---------------------------------
ex_parent = new_mnt->mnt_parent
mntput_no_expire_slowpath()
__umount_mnt(new_mnt)
cleanup_mnt()
call_rcu()
IS_MNT_SHARED(ex_parent)
BUG: KASAN: slab-use-after-free in path_pivot_root+0xf1a/0x1840
Read of size 4 at addr ffff8881047382f8 by task pivot_widen/157
path_pivot_root+0xf1a/0x1840
__x64_sys_pivot_root+0x165/0x190
The same goes for the caller's root via chroot(). Both outcomes of the
check end in EINVAL so nothing but the read itself goes wrong. It's the
same thing commit bb4609405752 ("statmount: read the parent of an
unmounted mount under mount_lock") fixed for statmount().
Check that both mounts are in the caller's namespace before their
parents are read. Every path returns EINVAL either way.
Fixes: e0c9c0afd2fc ("mnt: Update detach_mounts to leave mounts connected")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-10-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: adapted the check to the inline pivot_root() syscall using goto out4 instead of returning -EINVAL. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 2492d5286cef6..f9c3f91277244 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3973,14 +3973,15 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
new_mnt = real_mount(new.mnt);
root_mnt = real_mount(root.mnt);
old_mnt = real_mount(old.mnt);
+ /* only a mounted mount has a parent that namespace_sem pins */
+ if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
+ goto out4;
ex_parent = new_mnt->mnt_parent;
root_parent = root_mnt->mnt_parent;
if (IS_MNT_SHARED(old_mnt) ||
IS_MNT_SHARED(ex_parent) ||
IS_MNT_SHARED(root_parent))
goto out4;
- if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
- goto out4;
if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
goto out4;
error = -ENOENT;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0530/1887] dm: fix reading free memory in do_resume
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (528 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0529/1887] namespace: check the mounts before reading their parents in pivot_root() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0531/1887] pmdomain: rockchip: fix clock leak on domain probe failure Greg Kroah-Hartman
` (468 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikulas Patocka,
syzbot+bdff1ecf726d2af66afd, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <mpatocka@redhat.com>
[ Upstream commit c9417c1c5269e2bd0570fbe53e4ec03a8d31f008 ]
When do_resume calls dm_table_get_mode(new_map), the call is done without
holding any locks (it only holds a reference to the md). It may be
possible that another concurrent ioctl on the same device will swap table
after dm_swap_table and before dm_table_get_mode. In this case,
dm_table_get_mode(new_map) reads freed memory.
This race condition was triggered by syzbot.
This commit fixes the race by reading mode of the new table before
dm_swap_table. Note that new_map is also passed to dm_ima_need_measure,
but this function doesn't attempt to dereference it, so this call should
be safe.
Note that this is not a security bug because only root can trigger it and
the commonly used tools such as lvm or cryptsetup do not call the ioctls
concurrently, so that they can't trigger it acceidentally.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: syzbot+bdff1ecf726d2af66afd@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
[ sashal: Replaced blk_mode_t and BLK_OPEN_WRITE with fmode_t and FMODE_WRITE. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/md/dm-ioctl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 4cfdd50e32d70..57d0bc1545b73 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1166,6 +1166,7 @@ static int do_resume(struct dm_ioctl *param)
/* Do we need to load a new map ? */
if (new_map) {
sector_t old_size, new_size;
+ fmode_t new_map_mode;
/* Suspend if it isn't already suspended */
if (param->flags & DM_SKIP_LOCKFS_FLAG)
@@ -1193,6 +1194,7 @@ static int do_resume(struct dm_ioctl *param)
}
}
+ new_map_mode = dm_table_get_mode(new_map);
old_size = dm_get_size(md);
old_map = dm_swap_table(md, new_map);
if (IS_ERR(old_map)) {
@@ -1205,7 +1207,7 @@ static int do_resume(struct dm_ioctl *param)
if (old_size && new_size && old_size != new_size)
need_resize_uevent = true;
- if (dm_table_get_mode(new_map) & FMODE_WRITE)
+ if (new_map_mode & FMODE_WRITE)
set_disk_ro(dm_disk(md), 0);
else
set_disk_ro(dm_disk(md), 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0531/1887] pmdomain: rockchip: fix clock leak on domain probe failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (529 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0530/1887] dm: fix reading free memory in do_resume Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0532/1887] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains Greg Kroah-Hartman
` (467 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
[ Upstream commit d8b3847770661b7109146e6479eeadcdab9cecf0 ]
When of_clk_get() failed in the middle of the loop, the references of
the clocks acquired so far were leaked instead of being released by
the error path.
Fixes: d909072d0521 ("soc: rockchip: power-domain: use clk_bulk APIs")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/rockchip/pm_domains.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 5ba582ffaa1a2..32ea21cd39133 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -589,7 +589,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
dev_err(pmu->dev,
"%pOFn: failed to get clk at index %d: %d\n",
node, i, error);
- return error;
+ goto err_put_clocks;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0532/1887] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (530 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0531/1887] pmdomain: rockchip: fix clock leak on domain probe failure Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0533/1887] pmdomain: rockchip: dont ignore clock lookup errors on attach Greg Kroah-Hartman
` (466 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ming Qian, Frank Li, Ulf Hansson,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <ming.qian@oss.nxp.com>
[ Upstream commit 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d ]
On i.MX8MP the VPU blk-ctrl exposes G1, G2 and VC8000E as three separate
genpds, each serialized only by its own genpd lock, so their power_on and
power_off callbacks can run concurrently on SMP.
The sequences are not independent: they share the VPUMIX bus domain, the
VPU_NOC and the ADB400 handshake. On power up the GPC cannot ack-verify
the ADB400 handshake - the ack only completes once blk-ctrl sets the bus
clk-en bit - so it just waits a fixed delay instead of polling hskack. A
sibling transition landing inside another domain's reset window disturbs
that shared clock and handshake timing, the victim's reset does not take
effect, and its block registers read back all zeros: the decoder times
out or the encoder fails its format check.
Serialize the blk-ctrl reset sequence with a per-blk-ctrl mutex; the
driver deliberately avoids a genpd hierarchy, so the genpd core gives no
cross-sibling serialization.
Fixes: a1a5f15f7f6c ("soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl")
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/imx/imx8m-blk-ctrl.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 1b87823d835d3..65315bf908b36 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -13,6 +13,7 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <dt-bindings/power/imx8mm-power.h>
#include <dt-bindings/power/imx8mn-power.h>
@@ -32,6 +33,12 @@ struct imx8m_blk_ctrl {
struct regmap *regmap;
struct imx8m_blk_ctrl_domain *domains;
struct genpd_onecell_data onecell_data;
+ /*
+ * Serializes the blk-ctrl reset/clock sequence across sibling domains;
+ * their transitions interact through the shared VPUMIX bus domain,
+ * VPU_NOC and the not-ack-verified ADB400 handshake (ERR050531).
+ */
+ struct mutex power_lock;
};
struct imx8m_blk_ctrl_domain_data {
@@ -87,6 +94,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
struct imx8m_blk_ctrl *bc = domain->bc;
int ret;
+ guard(mutex)(&bc->power_lock);
+
/* make sure bus domain is awake */
ret = pm_runtime_get_sync(bc->bus_power_dev);
if (ret < 0) {
@@ -146,6 +155,8 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
const struct imx8m_blk_ctrl_domain_data *data = domain->data;
struct imx8m_blk_ctrl *bc = domain->bc;
+ guard(mutex)(&bc->power_lock);
+
/* put devices into reset and disable clocks */
if (data->mipi_phy_rst_mask)
regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
@@ -184,6 +195,10 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
bc->dev = dev;
+ ret = devm_mutex_init(dev, &bc->power_lock);
+ if (ret)
+ return ret;
+
bc_data = of_device_get_match_data(dev);
base = devm_platform_ioremap_resource(pdev, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0533/1887] pmdomain: rockchip: dont ignore clock lookup errors on attach
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (531 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0532/1887] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0534/1887] pmdomain: rockchip: propagate subdomain add errors Greg Kroah-Hartman
` (465 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
[ Upstream commit 4c66c423593e26273ea0d644906ed007630c6f6d ]
rockchip_pd_attach_dev() treated every of_clk_get() error as the end
of the clock list, so a clock that exists but is not available yet
(e.g. -EPROBE_DEFER) was silently skipped and the device ended up
without pm_clk management. Only -ENOENT means there are no more
clocks.
Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain driver")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/rockchip/pm_domains.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 32ea21cd39133..1146fdf477aa8 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -507,7 +507,19 @@ static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
}
i = 0;
- while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+ while (1) {
+ clk = of_clk_get(dev->of_node, i++);
+ if (IS_ERR(clk)) {
+ error = PTR_ERR(clk);
+ if (error == -ENOENT)
+ break;
+
+ dev_err(dev, "failed to get clock %d: %d\n", i - 1,
+ error);
+ pm_clk_destroy(dev);
+ return error;
+ }
+
dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
error = pm_clk_add_clk(dev, clk);
if (error) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0534/1887] pmdomain: rockchip: propagate subdomain add errors
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (532 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0533/1887] pmdomain: rockchip: dont ignore clock lookup errors on attach Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0535/1887] optee: register TEE devices only once fully initialized Greg Kroah-Hartman
` (464 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
[ Upstream commit 4c0d69d677cf5b0065ebbb3ceb8ba66fddbec630 ]
rockchip_pm_add_subdomain() ignored the return value of its recursive
call, so a failure deeper in the hierarchy was silently dropped and
probe still succeeded with an incomplete domain tree.
Fixes: 6be05b5ec161 ("soc: rockchip: power-domain: add support for sub-power domains")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
[ sashal: goto err_out instead of return, so the np reference taken by for_each_child_of_node() is dropped ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/rockchip/pm_domains.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index 1146fdf477aa8..2697977cf24c3 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -767,7 +767,9 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
parent_domain->name, child_domain->name);
}
- rockchip_pm_add_subdomain(pmu, np);
+ error = rockchip_pm_add_subdomain(pmu, np);
+ if (error)
+ goto err_out;
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0535/1887] optee: register TEE devices only once fully initialized
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (533 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0534/1887] pmdomain: rockchip: propagate subdomain add errors Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0536/1887] scsi: ch: Do not keep references to data transfer element devices Greg Kroah-Hartman
` (463 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shao-Fu Chen, Jens Wiklander,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shao-Fu Chen <shf.chen@mediatek.com>
[ Upstream commit c108feca0a096f8db25d1b69130035025e9e936d ]
optee_probe() called tee_device_register() on both the client and the
supplicant device before the rest of struct optee had been initialized.
tee_device_register() calls cdev_device_add(), which does two things at
once: it creates /dev/tee0 and /dev/teepriv0, and it links the device
into the tee class so that class_find_device() can find it. From that
moment on the device is reachable both from user space via tee_open()
and from kernel space via tee_client_open_context(). The only gate in
teedev_open() is tee_device_get(), which merely checks that
teedev->desc is non-NULL, which was already set by tee_device_alloc().
Therefore, there is effectively no gate at all.
A context opened in that window can run against a struct optee where
- optee->call_queue.mutex is not initialized by optee_cq_init()
- optee->supp mutex and completions is not initialized by
optee_supp_init()
- optee->rpmb_dev_mutex is not initialized yet,
- the message argument cache is not initialized by
optee_shm_arg_cache_init()
- optee->ctx is still NULL
Any open session or invoke during this window takes uninitialized
mutexes and dereferences a NULL pointer.
Fix it by moving both tee_device_register() calls down to the point
where all of struct optee is set up.
Fixes: 4fb0a5eb364d ("tee: add OP-TEE driver")
Cc: stable@vger.kernel.org
Signed-off-by: Shao-Fu Chen <shf.chen@mediatek.com>
[JW: adding fixes and cc]
Signed-off-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
[ sashal: Adjusted context to match the older OP-TEE probe initialization sequence. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tee/optee/ffa_abi.c | 16 ++++++++--------
drivers/tee/optee/smc_abi.c | 17 ++++++++---------
2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index 927c3d7947f9c..f0ecd931035e3 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -844,14 +844,6 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
}
optee->supp_teedev = teedev;
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
if (rc)
goto err_unreg_supp_teedev;
@@ -871,6 +863,14 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
if (rc)
goto err_close_ctx;
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_unregister_devices;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_unregister_devices;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_unregister_devices;
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index e6e0428f8e7be..89ab5323f9fe7 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1467,14 +1467,6 @@ static int optee_probe(struct platform_device *pdev)
}
optee->supp_teedev = teedev;
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
mutex_init(&optee->call_queue.mutex);
INIT_LIST_HEAD(&optee->call_queue.waiters);
optee_supp_init(&optee->supp);
@@ -1531,6 +1523,14 @@ static int optee_probe(struct platform_device *pdev)
if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
pr_info("dynamic shared memory is enabled\n");
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_disable_shm_cache;
@@ -1551,7 +1551,6 @@ static int optee_probe(struct platform_device *pdev)
optee_shm_arg_cache_uninit(optee);
optee_supp_uninit(&optee->supp);
mutex_destroy(&optee->call_queue.mutex);
-err_unreg_supp_teedev:
tee_device_unregister(optee->supp_teedev);
err_unreg_teedev:
tee_device_unregister(optee->teedev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0536/1887] scsi: ch: Do not keep references to data transfer element devices
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (534 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0535/1887] optee: register TEE devices only once fully initialized Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0537/1887] drm/vc4: Fix firmware reference leak in vc4_drm_bind() Greg Kroah-Hartman
` (462 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ahmed Abdelhaleem Ahmed,
Laurence Oberman, Martin K. Petersen (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
[ Upstream commit 27c0f718d3b3c99e6d315308e95d987d0382a8a8 ]
ch_readconfig() looks up the scsi_device of every data transfer element
whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in
ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops
it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere
else - it only supplies the vendor, model and revision printed in the same
loop.
Once such a drive is removed, its scsi_device can never be released. It
stays on the host's device list at its address, so a new device there is
refused by anything that walks the list - target_core_pscsi reports
"scsi_device_get() failed for H:C:T:L" - and the low-level driver's module
can no longer be unloaded. Only a reboot recovers.
It shows with any changer that reports its drives' ids; with the mhvtl
virtual library (IBM 3573-TL personality), each create and remove of a
library with four drives leaves four references behind, counted by the
module's use count in lsmod. With ch not bound the count is unchanged, and
with this patch applied it is unchanged too.
Drop the reference as soon as the name has been printed, and remove the now
unused dt[] array. That also removes the array leaked when ch_probe() fails
after ch_readconfig().
The same leak was reported with an RFC patch in 2022, which was not merged.
Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-scsi/20220719075442.6215-1-yanghao_ht@163.com/
Signed-off-by: Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
Link: https://patch.msgid.link/20260929-ch-dt-leak-v2-1-ddda8d635dca@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ sashal: Adjusted allocation removal for kcalloc() instead of kzalloc_objs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/ch.c | 30 +++++++++---------------------
1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 7ab29eaec6f38..fa0317402ba4e 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -110,7 +110,6 @@ typedef struct {
int minor;
char name[8];
struct scsi_device *device;
- struct scsi_device **dt; /* ptrs to data transfer elements */
u_int firsts[CH_TYPES];
u_int counts[CH_TYPES];
u_int unit_attention;
@@ -357,16 +356,10 @@ ch_readconfig(scsi_changer *ch)
vendor_labels[i]);
}
- /* look up the devices of the data transfer elements */
- ch->dt = kcalloc(ch->counts[CHET_DT], sizeof(*ch->dt),
- GFP_KERNEL);
-
- if (!ch->dt) {
- kfree(buffer);
- return -ENOMEM;
- }
-
+ /* report the devices of the data transfer elements */
for (elem = 0; elem < ch->counts[CHET_DT]; elem++) {
+ struct scsi_device *sdev;
+
id = -1;
lun = 0;
if (elem < CH_DT_MAX && -1 != dt_id[elem]) {
@@ -382,10 +375,8 @@ ch_readconfig(scsi_changer *ch)
VPRINTK(KERN_INFO, "dt 0x%x: ",elem+ch->firsts[CHET_DT]);
if (data[6] & 0x80) {
VPRINTK(KERN_CONT, "not this SCSI bus\n");
- ch->dt[elem] = NULL;
} else if (0 == (data[6] & 0x30)) {
VPRINTK(KERN_CONT, "ID/LUN unknown\n");
- ch->dt[elem] = NULL;
} else {
id = ch->device->id;
lun = 0;
@@ -395,18 +386,16 @@ ch_readconfig(scsi_changer *ch)
}
if (-1 != id) {
VPRINTK(KERN_CONT, "ID %i, LUN %i, ",id,lun);
- ch->dt[elem] =
- scsi_device_lookup(ch->device->host,
- ch->device->channel,
- id,lun);
- if (!ch->dt[elem]) {
+ sdev = scsi_device_lookup(ch->device->host,
+ ch->device->channel,
+ id, lun);
+ if (!sdev) {
/* should not happen */
VPRINTK(KERN_CONT, "Huh? device not found!\n");
} else {
VPRINTK(KERN_CONT, "name: %8.8s %16.16s %4.4s\n",
- ch->dt[elem]->vendor,
- ch->dt[elem]->model,
- ch->dt[elem]->rev);
+ sdev->vendor, sdev->model, sdev->rev);
+ scsi_device_put(sdev);
}
}
}
@@ -570,7 +559,6 @@ static void ch_destroy(struct kref *ref)
scsi_changer *ch = container_of(ref, scsi_changer, ref);
ch->device = NULL;
- kfree(ch->dt);
kfree(ch);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0537/1887] drm/vc4: Fix firmware reference leak in vc4_drm_bind()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (535 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0536/1887] scsi: ch: Do not keep references to data transfer element devices Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0538/1887] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks Greg Kroah-Hartman
` (461 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Maíra Canal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
[ Upstream commit b816da5d5df1461446a0a5f3fe2b4948a659a790 ]
The firmware reference obtained via rpi_firmware_get() is leaked when
aperture_remove_all_conflicting_devices() fails, as the error label
returns without putting it. This happens before the firmware is
consumed and put further down in the function.
Put the firmware reference before jumping to err.
Fixes: c406ad5e4a85 ("drm/vc4: Notify the firmware when DRM is in charge")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916154015.2056797-1-vulab@iscas.ac.cn
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
[ sashal: Adapted to drm_aperture_remove_framebuffers() and its direct-return error path. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_drv.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index b6384a5dfdbc1..ec5eca21df44e 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -352,8 +352,11 @@ static int vc4_drm_bind(struct device *dev)
}
ret = drm_aperture_remove_framebuffers(driver);
- if (ret)
+ if (ret) {
+ if (firmware)
+ rpi_firmware_put(firmware);
return ret;
+ }
if (firmware) {
ret = rpi_firmware_property(firmware,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0538/1887] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (536 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0537/1887] drm/vc4: Fix firmware reference leak in vc4_drm_bind() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0539/1887] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN Greg Kroah-Hartman
` (460 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Tom St Denis,
Vitaly Prosyak, Mikhail Gavrilov, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
[ Upstream commit 16c64495859f13f75602f439588883f2a4a4d6a6 ]
Reading or writing a register through the amdgpu_regs2 debugfs file
with GRBM bank selection, which umr does for every banked access (a
single "umr -b x x x -r <reg>" is enough, as is the wave dump with
"-O halt_waves"), makes lockdep report a circular locking dependency,
after which lockdep stays off until reboot:
WARNING: possible circular locking dependency detected
umr/63306 is trying to acquire lock:
ffff8882cf4b8350 (&mm->mmap_lock){++++}-{4:4}, at: __might_fault+0x9b/0x140
but task is already holding lock:
ffff8881aec010d0 (&amdgpu_grbm_lock_key){+.+.}-{4:4}, at: amdgpu_debugfs_regs2_op.isra.0+0x20d/0xd00 [amdgpu]
...
Chain exists of:
&mm->mmap_lock --> &amdgpu_srbm_lock_key --> &amdgpu_grbm_lock_key
...
__might_fault+0xc5/0x140
amdgpu_debugfs_regs2_op.isra.0+0x441/0xd00 [amdgpu]
full_proxy_write+0x10e/0x1d0
vfs_write+0x1d0/0xf50
ksys_write+0x116/0x250
amdgpu_debugfs_regs2_op() and amdgpu_debugfs_process_reg_op() call
get_user()/put_user() for every dword while holding grbm_idx_mutex or
srbm_mutex, and pm.mutex if requested, so a fault there takes mmap_lock
inside those locks. The lock hierarchy in amdgpu_lockdep.c puts
srbm_mutex and grbm_idx_mutex below notifier_lock, which
amdgpu_cs_submit() takes with the BO reservations held, and
dma_resv_lockdep() orders the reservations inside mmap_lock. So
mmap_lock is outside grbm_idx_mutex and srbm_mutex, and these two
debugfs paths nest it the other way round. The copies under the locks
are as old as the bank selection in both files; commit 1d0f5838b126
("drm/amdgpu: Add lockdep annotations for lock ordering validation")
only made them visible to lockdep.
Copy the user buffer in before any of the locks is taken and the result
out after all of them are dropped, as amdgpu_debugfs_wave_read(),
amdgpu_debugfs_gpr_read() and amdgpu_debugfs_gprwave_read() already do.
The buffer is sized by the count passed to read() or write(), so an
access larger than PAGE_SIZE is now rejected with -EINVAL; umr reads and
writes one register at a time. A fault on the user buffer of a write now
fails with -EFAULT before any register is written, instead of after a
partial write.
Fixes: 566281595037 ("drm/amd/amdgpu: Add bank selection for MMIO debugfs (v3)")
Fixes: 37df9560cd3e ("drm/amd/amdgpu: New debugfs interface for MMIO registers (v5)")
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Tom St Denis <tom.stdenis@amd.com>
Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ccf9e35ed6811f2c25ba6368e7dc6481da17159d)
Cc: stable@vger.kernel.org
[ sashal: Omitted the XCC argument from amdgpu_mm_wreg_mmio_rlc() calls to match the three-argument API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 76 ++++++++++++---------
1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 2300752e2fa8c..b80b34b8aa5c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -114,6 +114,20 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
*pos &= (1UL << 22) - 1;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (!read && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -146,28 +160,16 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
mutex_lock(&adev->pm.mutex);
while (size) {
- uint32_t value;
-
- if (read) {
- value = RREG32(*pos >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (read)
+ data[result >> 2] = RREG32(*pos >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, data[result >> 2]);
result += 4;
- buf += 4;
*pos += 4;
size -= 4;
}
-end:
if (use_bank) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -183,6 +185,10 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (read && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}
@@ -232,11 +238,24 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
struct amdgpu_device *adev = rd->adev;
ssize_t result = 0;
int r;
- uint32_t value;
if (size & 0x3 || offset & 0x3)
return -EINVAL;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (write_en && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -276,24 +295,15 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
mutex_lock(&adev->pm.mutex);
while (size) {
- if (!write_en) {
- value = RREG32(offset >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (!write_en)
+ data[result >> 2] = RREG32(offset >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, data[result >> 2]);
offset += 4;
size -= 4;
result += 4;
- buf += 4;
}
-end:
+
if (rd->id.use_grbm) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -313,6 +323,10 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (!write_en && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0539/1887] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (537 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0538/1887] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0540/1887] namespace: unhash a dentry before detaching the mounts on it Greg Kroah-Hartman
` (459 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ca23c8570669ead78867,
Nguyen Ngoc Thang, Thomas Zimmermann, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
[ Upstream commit 755c94d178b7e972bb766199d34e4ba4f63a89eb ]
__drm_fb_helper_initial_config_and_unlock() calls
drm_client_modeset_probe() first, which already fills in each
mode_set->mode/num_connectors for every connected output, and only
afterwards calls drm_fb_helper_single_fb_probe() to create
fb_helper->fb and wire it into those mode_sets via
drm_setup_crtcs_fb().
If drm_fb_helper_single_fb_probe() fails with anything other than
-EAGAIN (e.g. dev->driver->fbdev_probe() itself fails), the function
bails out before drm_setup_crtcs_fb() runs and before setting
fb_helper->deferred_setup. The client is left with mode_sets that
have a mode and connectors but mode_set->fb == NULL, and nothing
marks this fb_helper as needing a retry.
__drm_fb_helper_restore_fbdev_mode_unlocked() only skips committing
when fb_helper->deferred_setup is set, so a later .restore() call
(drm_lastclose() on process exit, in this report) commits the stale
mode_set through drm_client_modeset_commit() ->
drm_client_modeset_commit_atomic() -> __drm_atomic_helper_set_config(),
which hits WARN_ON(!set->fb).
Mark fb_helper->deferred_setup on any drm_fb_helper_single_fb_probe()
failure, not just -EAGAIN, so restore keeps skipping the commit until
a later hotplug event successfully re-probes and re-populates
mode_set->fb. The real error code is still returned to the caller
unchanged.
Reported-by: syzbot+ca23c8570669ead78867@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ca23c8570669ead78867
Fixes: ca91a2758fce ("drm/fb-helper: Support deferred setup")
Cc: stable@vger.kernel.org
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260927075434.72658-1-ngocthang2710.1999@gmail.com
Link: https://patch.msgid.link/20260917154743.1621-1-shechenglong@xfusion.com
[ sashal: Moved the existing preferred_bpp assignment alongside deferred_setup because upstream’s earlier initialization is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_fb_helper.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index a0abfb3f05f04..954ca9215fb88 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1942,11 +1942,11 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
drm_client_modeset_probe(&fb_helper->client, width, height);
ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
if (ret < 0) {
- if (ret == -EAGAIN) {
- fb_helper->preferred_bpp = bpp_sel;
- fb_helper->deferred_setup = true;
+ fb_helper->preferred_bpp = bpp_sel;
+ /* modesets are probed but fb_helper->fb isn't; defer restore too */
+ fb_helper->deferred_setup = true;
+ if (ret == -EAGAIN)
ret = 0;
- }
mutex_unlock(&fb_helper->lock);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0540/1887] namespace: unhash a dentry before detaching the mounts on it
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (538 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0539/1887] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0541/1887] namespace: dont copy an unmounted mount tree Greg Kroah-Hartman
` (458 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 528b383dc35d1e5caf64ddf5d35f983ae543b0d0 ]
unlink(), rmdir() and rename() remove the entry from the filesystem,
call detach_mounts() on the entry with the inode locked and then call
d_delete() once the inode is unlocked.
The thing is that between detach_mounts() and d_delete() the dentry is
still hashed and positive. But after detach_mounts() nothing covers the
dentry anymore. A lookup that finds this dentry in the dcache can
uncover what the mounts hid.
That's a problem when unlinking files or directories that are
mountpoints in other mount namespaces. Everybody who had the underlying
entry covered can race the detach_mount() call until d_delete() has run.
The race window isn't all that small. It encompasses namespace_unlock()
with a full synchronize_rcu_expedited() grace period and the
inode_unlock() of the entry.
In my experiments three walkers that kept trying read an overmounted
file in 11938 of the 16140 unlinks that removed its mountpoint from a
bind mount of the filesystem within a minute.
Fun fact, d_invalidate() has the same ordering problem but gets it
right. It unhashes the dentry first and detaches the mounts afterwards.
Let's do the same in __detach_mounts():
- A lookup that hasn't found the dentry yet misses it in the dcache and
waits for the directory lock that the caller holds until the name is
gone for good.
- A lockless lookup that found it already fails the mount_lock check
while the dentry still counts as a mountpoint and the d_seq check once
it doesn't, and retries.
This fixes the lockless path. We still need to fix the reference count
lookup in a follow-up patch.
So d_drop() the dentry. The dentry stays positive and held but can't be
found anymore. Then proceed with the detach and unlink.
Reproducer:
The reads were counted with the program below, three walkers for 60 s
in a VM with 4 CPUs. The race window is stretched with the debug patch
pasted here. fs.detach_race_walk_us sleeps in lookup_fast() once it
found a mountpoint dentry and before its mounts are crossed.
fs.detach_race_unlink_us sleeps in vfs_unlink() between detach_mounts()
and d_delete().
// SPDX-License-Identifier: GPL-2.0
/*
* unlink_covered: unlink a file that is a mountpoint in a detached copy of
* its mount, against lookups that open it through that copy.
*
* A is a tmpfs with the file f1 (content SECRET_F) and the plain file
* MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
* on A'/f1, held through an O_PATH fd on its root once the tree fd is
* closed. Walkers open f1 through that fd while the driver unlinks A/f1,
* where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
* A read of SECRET_F is a hit: the name was found after its mount was
* gone. The lockless walks use openat2(RESOLVE_CACHED).
*
* usage: unlink_covered [-t seconds] [-w walkers]
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <linux/openat2.h>
#ifndef __NR_open_tree
#define __NR_open_tree 428
#endif
#ifndef __NR_move_mount
#define __NR_move_mount 429
#endif
#ifndef __NR_openat2
#define __NR_openat2 437
#endif
#ifndef OPEN_TREE_CLONE
#define OPEN_TREE_CLONE 1
#endif
#ifndef OPEN_TREE_CLOEXEC
#define OPEN_TREE_CLOEXEC O_CLOEXEC
#endif
#ifndef MOVE_MOUNT_F_EMPTY_PATH
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
#endif
#define WORK "/tmp/uc"
#define ADIR WORK "/A"
static int duration = 60, nwalkers = 3;
static atomic_int stop, writer_waiting;
static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER;
static int cur_fd = -1; /* the root of A', -1 while there is none */
static atomic_long n_unlink, n_walk, n_mark, n_enoent, n_other, n_secret,
n_secret_cached;
static void die(const char *what)
{
fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
exit(2);
}
static void put_file(int dfd, const char *name, const char *content)
{
int fd = openat(dfd, name, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
0644);
if (fd < 0 || write(fd, content, strlen(content)) < 0)
die(name);
close(fd);
}
/* "plain/../" @n times, then f1: a longer walk that checks nothing on its way */
static char *longpath(int n)
{
char *p = malloc(n * 9 + 3), *q = p;
for (int i = 0; i < n; i++, q += 9)
memcpy(q, "plain/../", 9);
strcpy(q, "f1");
return p;
}
static void try_read(int dfd, const char *path, int cached)
{
struct open_how how = { .flags = O_RDONLY | O_CLOEXEC,
.resolve = RESOLVE_CACHED };
char buf[32] = "";
long n;
int fd;
if (cached)
fd = syscall(__NR_openat2, dfd, path, &how, sizeof(how));
else
fd = openat(dfd, path, O_RDONLY | O_CLOEXEC);
atomic_fetch_add(&n_walk, 1);
if (fd < 0) {
if (errno == ENOENT)
atomic_fetch_add(&n_enoent, 1);
else if (!cached || errno != EAGAIN)
atomic_fetch_add(&n_other, 1);
return;
}
n = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (n >= 6 && !strncmp(buf, "SECRET", 6)) {
if (cached)
atomic_fetch_add(&n_secret_cached, 1);
if (!atomic_fetch_add(&n_secret, 1))
printf("HIT: read \"%s\" through %s (%s walk)\n", buf,
path, cached ? "lockless" : "any");
} else {
atomic_fetch_add(&n_mark, 1);
}
}
static void *walker(void *arg)
{
unsigned int r = (long)arg * 2654435761u;
while (!atomic_load(&stop)) {
char *p_long, *p_short;
int dfd;
while (atomic_load(&writer_waiting) && !atomic_load(&stop))
usleep(20);
pthread_rwlock_rdlock(&cur_lock);
dfd = cur_fd;
if (dfd < 0) {
pthread_rwlock_unlock(&cur_lock);
usleep(100);
continue;
}
r = r * 1103515245u + 12345u;
p_long = longpath(1 + (r >> 8) % 400);
p_short = longpath(0);
try_read(dfd, p_long, 0);
try_read(dfd, p_short, 0);
try_read(dfd, p_long, 1);
pthread_rwlock_unlock(&cur_lock);
free(p_long);
free(p_short);
}
return NULL;
}
/* hand the walkers a new A' (or none), close the old one */
static void publish(int fd)
{
int old;
atomic_fetch_add(&writer_waiting, 1);
pthread_rwlock_wrlock(&cur_lock);
old = cur_fd;
cur_fd = fd;
pthread_rwlock_unlock(&cur_lock);
atomic_fetch_sub(&writer_waiting, 1);
if (old >= 0)
close(old);
}
static void *driver(void *arg __attribute__((unused)))
{
int a;
if (mkdir(ADIR, 0755) && errno != EEXIST)
die("mkdir A");
if (mount("A", ADIR, "tmpfs", 0, "size=4M"))
die("mount A");
a = open(ADIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
if (a < 0 || mkdirat(a, "plain", 0755))
die("A/plain");
put_file(a, "MARK_A", "MARK_A");
while (!atomic_load(&stop)) {
int t, m, fd_a;
put_file(a, "f1", "SECRET_F");
t = syscall(__NR_open_tree, a, "",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
if (t < 0)
die("open_tree A");
m = syscall(__NR_open_tree, a, "MARK_A",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
if (m < 0)
die("open_tree MARK_A");
if (syscall(__NR_move_mount, m, "", t, "f1",
MOVE_MOUNT_F_EMPTY_PATH))
die("move_mount");
close(m);
fd_a = openat(t, ".", O_PATH | O_DIRECTORY | O_CLOEXEC);
if (fd_a < 0)
die("open A'");
publish(fd_a);
usleep(200 + rand() % 1000);
close(t); /* A' is unmounted, fd_a holds it */
usleep(200 + rand() % 1000);
if (unlinkat(a, "f1", 0)) /* through A, a plain file there */
die("unlink f1");
atomic_fetch_add(&n_unlink, 1);
usleep(rand() % 300);
publish(-1);
}
close(a);
umount2(ADIR, MNT_DETACH);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t d, *w;
int c, i;
setvbuf(stdout, NULL, _IOLBF, 0);
while ((c = getopt(argc, argv, "t:w:")) != -1) {
switch (c) {
case 't':
duration = atoi(optarg);
break;
case 'w':
nwalkers = atoi(optarg);
break;
default:
fprintf(stderr, "usage: unlink_covered [-t seconds] [-w walkers]\n");
return 2;
}
}
if (unshare(CLONE_NEWNS) ||
mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
die("unshare");
if (mkdir(WORK, 0755) && errno != EEXIST)
die("mkdir");
w = calloc(nwalkers, sizeof(*w));
for (i = 0; i < nwalkers; i++)
if (pthread_create(&w[i], NULL, walker, (void *)(long)i))
die("pthread_create");
if (pthread_create(&d, NULL, driver, NULL))
die("pthread_create");
sleep(duration);
atomic_store(&stop, 1);
pthread_join(d, NULL);
for (i = 0; i < nwalkers; i++)
pthread_join(w[i], NULL);
printf("unlink_covered: %d s, %d walkers: unlinks %ld walks %ld mark %ld enoent %ld other %ld SECRET %ld (lockless %ld)\n",
duration, nwalkers, atomic_load(&n_unlink), atomic_load(&n_walk),
atomic_load(&n_mark), atomic_load(&n_enoent),
atomic_load(&n_other), atomic_load(&n_secret),
atomic_load(&n_secret_cached));
return atomic_load(&n_secret) ? 1 : 0;
}
# diff --git a/fs/namei.c b/fs/namei.c
# --- a/fs/namei.c
# +++ b/fs/namei.c
# @@ -35,6 +35,7 @@
# #include <linux/fcntl.h>
# #include <linux/device_cgroup.h>
# #include <linux/fs_struct.h>
# +#include <linux/delay.h>
# #include <linux/posix_acl.h>
# #include <linux/hash.h>
# #include <linux/bitops.h>
# @@ -1205,9 +1206,26 @@ static int sysctl_protected_symlinks __read_mostly;
# static int sysctl_protected_hardlinks __read_mostly;
# static int sysctl_protected_fifos __read_mostly;
# static int sysctl_protected_regular __read_mostly;
# +/* debug: widen the two windows of the detach_mounts() race */
# +static int sysctl_detach_race_walk_us __read_mostly;
# +static int sysctl_detach_race_unlink_us __read_mostly;
#
# #ifdef CONFIG_SYSCTL
# static const struct ctl_table namei_sysctls[] = {
# + {
# + .procname = "detach_race_walk_us",
# + .data = &sysctl_detach_race_walk_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# + {
# + .procname = "detach_race_unlink_us",
# + .data = &sysctl_detach_race_unlink_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# {
# .procname = "protected_symlinks",
# .data = &sysctl_protected_symlinks,
# @@ -1878,6 +1896,10 @@ static struct dentry *lookup_fast(struct nameidata *nd)
# dentry = __d_lookup(parent, &nd->last);
# if (unlikely(!dentry))
# return NULL;
# + /* debug: between finding a mountpoint and crossing its mounts */
# + if (unlikely(sysctl_detach_race_walk_us) && d_mountpoint(dentry))
# + usleep_range(sysctl_detach_race_walk_us,
# + sysctl_detach_race_walk_us + 10);
# status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
# }
# if (unlikely(status <= 0)) {
# @@ -5693,6 +5715,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
# if (!error) {
# dont_mount(dentry);
# detach_mounts(dentry);
# + /* debug: the mounts are gone, d_delete() is still to come */
# + if (unlikely(sysctl_detach_race_unlink_us))
# + usleep_range(sysctl_detach_race_unlink_us,
# + sysctl_detach_race_unlink_us + 10);
# }
# }
# }
Fixes: 8ed936b5671b ("vfs: Lazily remove mounts on unlinked files and directories.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-1-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: adjusted context to the pointer-based mountpoint handling in __detach_mounts() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/namespace.c b/fs/namespace.c
index f9c3f91277244..1cbab4e3c75fc 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1737,6 +1737,9 @@ static int do_umount(struct mount *mnt, int flags)
* detach_mounts allows lazily unmounting those mounts instead of
* leaking them.
*
+ * The dentry is unhashed before the mounts go so that no lookup finds
+ * what they covered. The caller removes it for good afterwards.
+ *
* The caller may hold dentry->d_inode->i_mutex.
*/
void __detach_mounts(struct dentry *dentry)
@@ -1750,6 +1753,8 @@ void __detach_mounts(struct dentry *dentry)
if (!mp)
goto out_unlock;
+ /* the name goes first, what covered it goes second */
+ d_drop(dentry);
event++;
while (!hlist_empty(&mp->m_list)) {
mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0541/1887] namespace: dont copy an unmounted mount tree
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (539 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0540/1887] namespace: unhash a dentry before detaching the mounts on it Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0542/1887] namespace: check the target before walking it in do_mount_setattr() Greg Kroah-Hartman
` (457 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 8bacbf6be959973b28b691713a872c12eae69eec ]
may_copy_tree() accepts a mount whose root is an nsfs or pidfs file
before it checks whether that mount is mounted. This exception exists
for nsfs and pidfs mounts. They are part of no mount namespace so
neither check_mnt() nor is_mounted() would let them through and
bind-mounting a nsfsfd or a pidfd wouldn't work.
Problem is that exception also admits a bind mount of such a file when
it was lazily unmounted and is only kept alive by a file descriptor:
mount --bind /proc/self/ns/net /tmp/x
exec 3< /tmp/x
umount -l /tmp/x
mount --rbind /proc/self/fd/3 /tmp/y
With MS_REC or AT_RECURSIVE copy_tree() doesn't stop at the unmounted
mount. It copies every mount that stayed attached to it as well. So if
you have a bunch of overmounts over the nsfsfd or the pidfd the whole
unmounted stack is copied. That's a bug.
So refuse to walk an unmounted tree. Copying its root alone stays
possible. So a bind mount of a namespace that is gone can still be
recreated from a file descriptor on the old one. The file descriptor
pins that mount and its root and __has_locked_children() only reads the
direct children which don't leave the parent's list without
namespace_sem. The internal mounts carry MNT_NS_INTERNAL instead of NULL
and are still walked. Copying an unmounted tree recursively fails with
EINVAL.
Fixes: e149ed2b805f ("take the targets of /proc/*/ns/* symlinks to separate fs")
Fixes: ef4144ac2dec ("pidfs: allow bind-mounts")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-4-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: adjusted context for inline mount validation instead of may_copy_tree() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/namespace.c b/fs/namespace.c
index 1cbab4e3c75fc..f2729ffdc5c52 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2435,6 +2435,9 @@ static struct mount *__do_loopback(struct path *old_path, int recurse)
if (!check_mnt(old) && old_path->dentry->d_op != &ns_dentry_operations)
return mnt;
+ if (recurse && !old->mnt_ns)
+ return ERR_PTR(-EINVAL);
+
if (!recurse && has_locked_children(old, old_path->dentry))
return mnt;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0542/1887] namespace: check the target before walking it in do_mount_setattr()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (540 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0541/1887] namespace: dont copy an unmounted mount tree Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:43 ` [PATCH 6.1 0543/1887] fcntl: refuse F_SET_RW_HINT on an immutable inode Greg Kroah-Hartman
` (456 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 08f4288a37ef4b3d19b4a9599ec3048219cac828 ]
When mount_setattr() changes the propagation type to MS_SHARED
do_mount_setattr() takes namespace_sem and calls invent_group_ids()
which walks the whole target tree with next_mnt() and allocates a peer
group id for every mount that doesn't have one.
Whether the caller may touch the target at all is only checked
afterwards under mount_lock. If it may not, cleanup_group_ids() walks
the tree a second time on the way out to free the ids again.
A detached tree that a file descriptor keeps alive, a mount in another
mount namespace or a mount below the root of an anonymous mount
namespace does a bunch of allocation work that is completely useless
because it will fail and revert right after.
Do the right thing and check the target right after taking namespace_sem
instead. A mount leaves its namespace only under namespace_sem so the
mount stays stable. The check under mount_lock stays for the case where
no propagation change is requested and namespace_sem isn't taken.
Callers get the same EINVAL as before.
Fixes: 2a1867219c7b ("fs: add mount_setattr()")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-5-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: replaced anon_ns_root() with explicit checks using existing mount helpers. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/namespace.c b/fs/namespace.c
index f2729ffdc5c52..cf866f5dbd1c5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4224,6 +4224,13 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)
* propagation.
*/
namespace_lock();
+ /* invent_group_ids() walks the tree, only walk a mounted one */
+ if (!is_mounted(&mnt->mnt) ||
+ ((mnt_has_parent(mnt) || !is_anon_ns(mnt->mnt_ns)) &&
+ !check_mnt(mnt))) {
+ namespace_unlock();
+ return -EINVAL;
+ }
if (kattr->propagation == MS_SHARED) {
err = invent_group_ids(mnt, kattr->recurse);
if (err) {
@@ -4236,6 +4243,7 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)
err = -EINVAL;
lock_mount_hash();
+ /* Checked under namespace_sem already if the propagation changes. */
/* Ensure that this isn't anything purely vfs internal. */
if (!is_mounted(&mnt->mnt))
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0543/1887] fcntl: refuse F_SET_RW_HINT on an immutable inode
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (541 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0542/1887] namespace: check the target before walking it in do_mount_setattr() Greg Kroah-Hartman
@ 2026-10-28 16:43 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0544/1887] namespace: handle mount locking for automounts correctly Greg Kroah-Hartman
` (455 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit b0d1022b9bdb1e98aa7fb3244fdd50a58c61766c ]
An immutable inode is never written to so write hints are pointless.
Refuse the hint on an immutable inode the way setattr(), fallocate() and
etxattr() refuse their changes.
Fixes: c75b1d9421f8 ("fs: add fcntl() interface for setting/getting write life time hints")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-3-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: Moved the check from fcntl_set_rw_hint() to the F_SET_RW_HINT case in the combined fcntl_rw_hint() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fcntl.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 1bde178e4aa2e..13ba6b47877b8 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -290,6 +290,9 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd,
return -EFAULT;
return 0;
case F_SET_RW_HINT:
+ /* nothing is ever written to it */
+ if (IS_IMMUTABLE(inode))
+ return -EPERM;
if (copy_from_user(&hint, argp, sizeof(hint)))
return -EFAULT;
if (!rw_hint_valid(hint))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0544/1887] namespace: handle mount locking for automounts correctly
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (542 preceding siblings ...)
2026-10-28 16:43 ` [PATCH 6.1 0543/1887] fcntl: refuse F_SET_RW_HINT on an immutable inode Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0545/1887] tty: add break_wait kernel-doc Greg Kroah-Hartman
` (454 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 33aadc7c72055fca93cb5a3691d836ebf8b31c9b ]
If mounts are propagated across user namespaces, attach_recursive_mnt()
locks every copy of the source mount to protect overmounts from
vanishing and revealing the underlying files or directories.
The user namespace is taken from the caller's mount namespaces since
this is where the mounts end up. Except, that's not always true.
Automounts may legitimately get popped in by tasks located in a
different mount and user namespace during path lookup.
Then check doesn't make sense at that point. The copy in the namespace
of the parent - which may be the host's - is now locked and the host
cannot change the flags of its own mounts anymore.
Here's the reproducer:
- host has debugfs mounted nosuid,nodev,noexec and shared
- tracefs automount below it is not yet active
- hand a child process a directory descriptor on that mount
- child process enters auser and mount namespace
- child process' namespace now holds a locked copy of the host's debugfs
mount that receives propagation from it
- child process stats "tracing/." through the descriptor
- lookup runs on the host's mount so the automount lands below the host's mount
- propagation puts a copy below the child's copy
- both try to clear the flags on the mount they got, with a bind remount:
host, on its own automount: MS_REMOUNT|MS_BIND = EPERM
child, on the copy in its namespace: MS_REMOUNT|MS_BIND = 0
So the lock landed on the host's mount instead of the child's copy.
Congrats. So we need to compare with the owner of the namespace the
mount actually gets mounted on. For all regular cases that is the
caller's mount namespace and so nothing changes.
Detached trees in anonymous mount namespaces by be handed over via
SCM_RIGHTS or inherited in other ways on purpose so the attaching task's
mount namespace is authoritative, not the creator of the detached tree.
Fixes: 132c94e31b8b ("vfs: Carefully propogate mounts across user namespaces")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-6-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: Adjusted attach_recursive_mnt() context for direct dest_mnt and dest_mp arguments instead of the pinned_mountpoint interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index cf866f5dbd1c5..c07e9e857f999 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2219,14 +2219,30 @@ static int attach_recursive_mnt(struct mount *source_mnt,
struct mountpoint *dest_mp,
bool moving)
{
- struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
HLIST_HEAD(tree_list);
struct mnt_namespace *ns = dest_mnt->mnt_ns;
+ struct user_namespace *user_ns = ns->user_ns;
struct mountpoint *smp;
struct mount *child, *p;
struct hlist_node *n;
int err;
+ /*
+ * A caller in an unprivileged mount namespaces may trigger an
+ * automount and propagate locked mounts into privileged mount
+ * namespaces. Take ownership from the target mount namespace.
+ * It's equivalent for everything but the automount case.
+ *
+ * Detached trees in anonymous mount namespaces by be handed
+ * over via SCM_RIGHTS or inherited in other ways on purpose
+ * the attaching task's mount namespace is authoritative, not
+ * the creator of the detached tree.
+ */
+ if (is_anon_ns(ns))
+ user_ns = current->nsproxy->mnt_ns->user_ns;
+ else
+ user_ns = ns->user_ns;
+
/* Preallocate a mountpoint in case the new mounts need
* to be tucked under other mounts.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0545/1887] tty: add break_wait kernel-doc
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (543 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0544/1887] namespace: handle mount locking for automounts correctly Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0546/1887] xfs: xfs_ifree_cluster vs xfs_iflush_shutdown_abort deadlock Greg Kroah-Hartman
` (453 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Randy Dunlap, Johan Hovold,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 5dad87615c9861cfa366ca984b52f581e861df20 ]
Add the missing kernel-doc description for the new break_wait field in
struct tty_struct.
Fixes: 845a2737e0f5 ("tty: abort break signalling on hangup")
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link: https://lore.kernel.org/20d75a7a-2e7a-484f-a267-c21db82dd922@infradead.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260925094222.18303-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/tty.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 37978b784312e..5bfdf02df9c75 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -173,6 +173,7 @@ struct tty_operations;
* @write_wait: concurrent writers are waiting in this queue until they are
* allowed to write
* @read_wait: readers wait for data in this queue
+ * @break_wait: wait queue for timed breaks
* @hangup_work: normally a work to perform a hangup (do_tty_hangup()); while
* freeing the tty, (re)used to release_one_tty()
* @disc_data: pointer to @ldisc's private data (e.g. to &struct n_tty_data)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0546/1887] xfs: xfs_ifree_cluster vs xfs_iflush_shutdown_abort deadlock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (544 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0545/1887] tty: add break_wait kernel-doc Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0547/1887] xfs: catch stale AGF/AGF metadata Greg Kroah-Hartman
` (452 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Christoph Hellwig,
Carlos Maiolino, Carlos Maiolino, Siddh Raman Pant, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@redhat.com>
[ Upstream commit 09234a632be42573d9743ac5ff6773622d233ad0 ]
Lock order of xfs_ifree_cluster() is cluster buffer -> try ILOCK
-> IFLUSHING, except for the last inode in the cluster that is
triggering the free. In that case, the lock order is ILOCK ->
cluster buffer -> IFLUSHING.
xfs_iflush_cluster() uses cluster buffer -> try ILOCK -> IFLUSHING,
so this can safely run concurrently with xfs_ifree_cluster().
xfs_inode_item_precommit() uses ILOCK -> cluster buffer, but this
cannot race with xfs_ifree_cluster() so being in a different order
will not trigger a deadlock.
xfs_reclaim_inode() during a filesystem shutdown uses ILOCK ->
IFLUSHING -> cluster buffer via xfs_iflush_shutdown_abort(), and
this deadlocks against xfs_ifree_cluster() like so:
sysrq: Show Blocked State
task:kworker/10:37 state:D stack:12560 pid:276182 tgid:276182 ppid:2 flags:0x00004000
Workqueue: xfs-inodegc/dm-3 xfs_inodegc_worker
Call Trace:
<TASK>
__schedule+0x650/0xb10
schedule+0x6d/0xf0
schedule_timeout+0x8b/0x180
schedule_timeout_uninterruptible+0x1e/0x30
xfs_ifree+0x326/0x730
xfs_inactive_ifree+0xcb/0x230
xfs_inactive+0x2c8/0x380
xfs_inodegc_worker+0xaa/0x180
process_scheduled_works+0x1d4/0x400
worker_thread+0x234/0x2e0
kthread+0x147/0x170
ret_from_fork+0x3e/0x50
ret_from_fork_asm+0x1a/0x30
</TASK>
task:fsync-tester state:D stack:12160 pid:2255943 tgid:2255943 ppid:3988702 flags:0x00004006
Call Trace:
<TASK>
__schedule+0x650/0xb10
schedule+0x6d/0xf0
schedule_timeout+0x31/0x180
__down_common+0xbe/0x1f0
__down+0x1d/0x30
down+0x48/0x50
xfs_buf_lock+0x3d/0xe0
xfs_iflush_shutdown_abort+0x51/0x1e0
xfs_icwalk_ag+0x386/0x690
xfs_reclaim_inodes_nr+0x114/0x160
xfs_fs_free_cached_objects+0x19/0x20
super_cache_scan+0x17b/0x1a0
do_shrink_slab+0x180/0x350
shrink_slab+0xf8/0x430
drop_slab+0x97/0xf0
drop_caches_sysctl_handler+0x59/0xc0
proc_sys_call_handler+0x189/0x280
proc_sys_write+0x13/0x20
vfs_write+0x33d/0x3f0
ksys_write+0x7c/0xf0
__x64_sys_write+0x1b/0x30
x64_sys_call+0x271d/0x2ee0
do_syscall_64+0x68/0x130
entry_SYSCALL_64_after_hwframe+0x76/0x7e
We can't change the lock order of xfs_ifree_cluster() - XFS_ISTALE
and XFS_IFLUSHING are serialised through to journal IO completion
by the cluster buffer lock being held.
There's quite a few asserts in the code that check that XFS_ISTALE
does not occur out of sync with buffer locking (e.g. in
xfs_iflush_cluster). There's also a dependency on the inode log item
being removed from the buffer before XFS_IFLUSHING is cleared, also
with asserts that trigger on this.
Further, we don't have a requirement for the inode to be locked when
completing or aborting inode flushing because all the inode state
updates are serialised by holding the cluster buffer lock across the
IO to completion.
We can't check for XFS_IRECLAIM in xfs_ifree_mark_inode_stale() and
skip the inode, because there is no guarantee that the inode will be
reclaimed. Hence it *must* be marked XFS_ISTALE regardless of
whether reclaim is preparing to free that inode. Similarly, we can't
check for IFLUSHING before locking the inode because that would
result in dirty inodes not being marked with ISTALE in the event of
racing with XFS_IRECLAIM.
Hence we have to address this issue from the xfs_reclaim_inode()
side. It is clear that we cannot hold the inode locked here when
calling xfs_iflush_shutdown_abort() because it is the inode->buffer
lock order that causes the deadlock against xfs_ifree_cluster().
Hence we need to drop the ILOCK before aborting the inode in the
shutdown case. Once we've aborted the inode, we can grab the ILOCK
again and then immediately reclaim it as it is now guaranteed to be
clean.
Note that dropping the ILOCK in xfs_reclaim_inode() means that it
can now be locked by xfs_ifree_mark_inode_stale() and seen whilst in
this state. This is safe because we have left the XFS_IFLUSHING flag
on the inode and so xfs_ifree_mark_inode_stale() will simply set
XFS_ISTALE and move to the next inode. An ASSERT check in this path
needs to be tweaked to take into account this new shutdown
interaction.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_icache.c | 8 ++++++++
fs/xfs/xfs_inode.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 5f6c2a1f32993..d4eb83e7934d4 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -916,7 +916,15 @@ xfs_reclaim_inode(
*/
if (xlog_is_shutdown(ip->i_mount->m_log)) {
xfs_iunpin_wait(ip);
+ /*
+ * Avoid a ABBA deadlock on the inode cluster buffer vs
+ * concurrent xfs_ifree_cluster() trying to mark the inode
+ * stale. We don't need the inode locked to run the flush abort
+ * code, but the flush abort needs to lock the cluster buffer.
+ */
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iflush_shutdown_abort(ip);
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
goto reclaim;
}
if (xfs_ipincount(ip))
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 3ccbc31767b3c..3139363d892bf 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2225,7 +2225,7 @@ xfs_ifree_mark_inode_stale(
iip = ip->i_itemp;
if (__xfs_iflags_test(ip, XFS_IFLUSHING)) {
ASSERT(!list_empty(&iip->ili_item.li_bio_list));
- ASSERT(iip->ili_last_fields);
+ ASSERT(iip->ili_last_fields || xlog_is_shutdown(mp->m_log));
goto out_iunlock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0547/1887] xfs: catch stale AGF/AGF metadata
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (545 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0546/1887] xfs: xfs_ifree_cluster vs xfs_iflush_shutdown_abort deadlock Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0548/1887] xfs: rearrange code in xfs_buf_item.c Greg Kroah-Hartman
` (451 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Carlos Maiolino,
Carlos Maiolino, Siddh Raman Pant, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@redhat.com>
[ Upstream commit db6a2274162de615ff74b927d38942fe3134d298 ]
There is a race condition that can trigger in dmflakey fstests that
can result in asserts in xfs_ialloc_read_agi() and
xfs_alloc_read_agf() firing. The asserts look like this:
XFS: Assertion failed: pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks), file: fs/xfs/libxfs/xfs_alloc.c, line: 3440
.....
Call Trace:
<TASK>
xfs_alloc_read_agf+0x2ad/0x3a0
xfs_alloc_fix_freelist+0x280/0x720
xfs_alloc_vextent_prepare_ag+0x42/0x120
xfs_alloc_vextent_iterate_ags+0x67/0x260
xfs_alloc_vextent_start_ag+0xe4/0x1c0
xfs_bmapi_allocate+0x6fe/0xc90
xfs_bmapi_convert_delalloc+0x338/0x560
xfs_map_blocks+0x354/0x580
iomap_writepages+0x52b/0xa70
xfs_vm_writepages+0xd7/0x100
do_writepages+0xe1/0x2c0
__writeback_single_inode+0x44/0x340
writeback_sb_inodes+0x2d0/0x570
__writeback_inodes_wb+0x9c/0xf0
wb_writeback+0x139/0x2d0
wb_workfn+0x23e/0x4c0
process_scheduled_works+0x1d4/0x400
worker_thread+0x234/0x2e0
kthread+0x147/0x170
ret_from_fork+0x3e/0x50
ret_from_fork_asm+0x1a/0x30
I've seen the AGI variant from scrub running on the filesysetm
after unmount failed due to systemd interference:
XFS: Assertion failed: pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || xfs_is_shutdown(pag->pag_mount), file: fs/xfs/libxfs/xfs_ialloc.c, line: 2804
.....
Call Trace:
<TASK>
xfs_ialloc_read_agi+0xee/0x150
xchk_perag_drain_and_lock+0x7d/0x240
xchk_ag_init+0x34/0x90
xchk_inode_xref+0x7b/0x220
xchk_inode+0x14d/0x180
xfs_scrub_metadata+0x2e2/0x510
xfs_ioc_scrub_metadata+0x62/0xb0
xfs_file_ioctl+0x446/0xbf0
__se_sys_ioctl+0x6f/0xc0
__x64_sys_ioctl+0x1d/0x30
x64_sys_call+0x1879/0x2ee0
do_syscall_64+0x68/0x130
? exc_page_fault+0x62/0xc0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Essentially, it is the same problem. When _flakey_drop_and_remount()
loads the drop-writes table, it makes all writes silently fail. Writes
are reported to the fs as completed successfully, but they are not
issued to the backing store. The filesystem sees the successful
write completion and marks the metadata buffer clean and removes it
from the AIL.
If this happens at the same time as memory pressure is occuring,
the now-clean AGF and/or AGI buffers can be reclaimed from memory.
Shortly afterwards, but before _flakey_drop_and_remount() runs
unmount, background writeback is kicked and it tries to allocate
blocks for the dirty pages in memory. This then tries to access the
AGF buffer we just turfed out of memory. It's not found, so it gets
read in from disk.
This is all fine, except for the fact that the last writeback of the
AGF did not actually reach disk. The AGF on disk is stale compared
to the in-memory state held by the perag, and so they don't match
and the assert fires.
Then other operations on that inode hang because the task was killed
whilst holding inode locks. e.g:
Workqueue: xfs-conv/dm-12 xfs_end_io
Call Trace:
<TASK>
__schedule+0x650/0xb10
schedule+0x6d/0xf0
schedule_preempt_disabled+0x15/0x30
rwsem_down_write_slowpath+0x31a/0x5f0
down_write+0x43/0x60
xfs_ilock+0x1a8/0x210
xfs_trans_alloc_inode+0x9c/0x240
xfs_iomap_write_unwritten+0xe3/0x300
xfs_end_ioend+0x90/0x130
xfs_end_io+0xce/0x100
process_scheduled_works+0x1d4/0x400
worker_thread+0x234/0x2e0
kthread+0x147/0x170
ret_from_fork+0x3e/0x50
ret_from_fork_asm+0x1a/0x30
</TASK>
and it's all down hill from there.
Memory pressure is one way to trigger this, another is to run "echo
3 > /proc/sys/vm/drop_caches" randomly while tests are running.
Regardless of how it is triggered, this effectively takes down the
system once umount hangs because it's holding a sb->s_umount lock
exclusive and now every sync(1) call gets stuck on it.
Fix this by replacing the asserts with a corruption detection check
and a shutdown.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
6.12:
Fixed conflict due to the following missing commit:
e9c4d8bfb26c ("xfs: factor out a generic xfs_group structure")
6.6:
Fixed conflict due to the following missing commit:
e45ea3645178 ("xfs: split the agf_roots and agf_levels arrays")
Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/libxfs/xfs_alloc.c | 46 +++++++++++++++++++++++++++++---------
fs/xfs/libxfs/xfs_ialloc.c | 32 ++++++++++++++++++++++----
2 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index cd5b197d70464..5bc37f984b006 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -26,6 +26,7 @@
#include "xfs_ag.h"
#include "xfs_ag_resv.h"
#include "xfs_bmap.h"
+#include "xfs_health.h"
struct kmem_cache *xfs_extfree_item_cache;
@@ -3167,18 +3168,43 @@ xfs_alloc_read_agf(
atomic64_add(allocbt_blks,
&pag->pag_mount->m_allocbt_blks);
}
+
#ifdef DEBUG
- else if (!xfs_is_shutdown(pag->pag_mount)) {
- ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
- ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
- ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
- ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
- ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
- ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
- be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
+ /*
+ * It's possible for the AGF to be out of sync if the block device is
+ * silently dropping writes. This can happen in fstests with dmflakey
+ * enabled, which allows the buffer to be cleaned and reclaimed by
+ * memory pressure and then re-read from disk here. We will get a
+ * stale version of the AGF from disk, and nothing good can happen from
+ * here. Hence if we detect this situation, immediately shut down the
+ * filesystem.
+ *
+ * This can also happen if we are already in the middle of a forced
+ * shutdown, so don't bother checking if we are already shut down.
+ */
+ if (!xfs_is_shutdown(pag->pag_mount)) {
+ bool ok = true;
+
+ ok &= pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks);
+ ok &= pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks);
+ ok &= pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks);
+ ok &= pag->pagf_flcount == be32_to_cpu(agf->agf_flcount);
+ ok &= pag->pagf_longest == be32_to_cpu(agf->agf_longest);
+ ok &= pag->pagf_levels[XFS_BTNUM_BNOi] ==
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
+ ok &= pag->pagf_levels[XFS_BTNUM_CNTi] ==
+ be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
+
+ if (XFS_IS_CORRUPT(pag->pag_mount, !ok)) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
+ xfs_trans_brelse(tp, agfbp);
+ xfs_force_shutdown(pag->pag_mount,
+ SHUTDOWN_CORRUPT_ONDISK);
+ return -EFSCORRUPTED;
+ }
}
-#endif
+#endif /* DEBUG */
+
if (agfbpp)
*agfbpp = agfbp;
else
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 4b2894c85ceaa..1d3c07506c594 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -27,6 +27,7 @@
#include "xfs_log.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
+#include "xfs_health.h"
/*
* Lookup a record by ino in the btree given by cur.
@@ -2645,12 +2646,35 @@ xfs_ialloc_read_agi(
pag->pagi_init = 1;
}
+#ifdef DEBUG
/*
- * It's possible for these to be out of sync if
- * we are in the middle of a forced shutdown.
+ * It's possible for the AGF to be out of sync if the block device is
+ * silently dropping writes. This can happen in fstests with dmflakey
+ * enabled, which allows the buffer to be cleaned and reclaimed by
+ * memory pressure and then re-read from disk here. We will get a
+ * stale version of the AGF from disk, and nothing good can happen from
+ * here. Hence if we detect this situation, immediately shut down the
+ * filesystem.
+ *
+ * This can also happen if we are already in the middle of a forced
+ * shutdown, so don't bother checking if we are already shut down.
*/
- ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
- xfs_is_shutdown(pag->pag_mount));
+ if (!xfs_is_shutdown(pag->pag_mount)) {
+ bool ok = true;
+
+ ok &= pag->pagi_freecount == be32_to_cpu(agi->agi_freecount);
+ ok &= pag->pagi_count == be32_to_cpu(agi->agi_count);
+
+ if (XFS_IS_CORRUPT(pag->pag_mount, !ok)) {
+ xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
+ xfs_trans_brelse(tp, agibp);
+ xfs_force_shutdown(pag->pag_mount,
+ SHUTDOWN_CORRUPT_ONDISK);
+ return -EFSCORRUPTED;
+ }
+ }
+#endif /* DEBUG */
+
if (agibpp)
*agibpp = agibp;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0548/1887] xfs: rearrange code in xfs_buf_item.c
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (546 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0547/1887] xfs: catch stale AGF/AGF metadata Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0549/1887] xfs: factor out stale buffer item completion Greg Kroah-Hartman
` (450 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Carlos Maiolino,
Carlos Maiolino, Siddh Raman Pant, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@redhat.com>
[ Upstream commit d2fe5c4c8d25999862d615f616aea7befdd62799 ]
The code to initialise, release and free items is all the way down
the bottom of the file. Upcoming fixes need to these functions
earlier in the file, so move them to the top.
There is one code change in this move - the parameter to
xfs_buf_item_relse() is changed from the xfs_buf to the
xfs_buf_log_item - the thing that the function is releasing.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
6.6:
Fixed conflict due to the following missing commits:
[Continuous range: 10634530f7ba^..d4c75a1b40cd]
d4c75a1b40cd ("xfs: convert remaining kmem_free() to kfree()")
49292576136f ("xfs: convert kmem_free() for kvmalloc users to kvfree()")
afdc115559c5 ("xfs: move kmem_to_page()")
f078d4ea8276 ("xfs: convert kmem_alloc() to kmalloc()")
10634530f7ba ("xfs: convert kmem_zalloc() to kzalloc()")
Removed ASSERT in favour of existing atomic_read-and-return in
xfs_buf_item_relse() due to the following missing commit:
3762113b597f ("xfs: don't lose solo superblock counter update transactions")
Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_buf_item.c | 118 +++++++++++++++++++++---------------------
fs/xfs/xfs_buf_item.h | 1 -
2 files changed, 60 insertions(+), 59 deletions(-)
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 72d6e2dd5ef54..1b323b3c0eb93 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -32,6 +32,63 @@ static inline struct xfs_buf_log_item *BUF_ITEM(struct xfs_log_item *lip)
return container_of(lip, struct xfs_buf_log_item, bli_item);
}
+static void
+xfs_buf_item_get_format(
+ struct xfs_buf_log_item *bip,
+ int count)
+{
+ ASSERT(bip->bli_formats == NULL);
+ bip->bli_format_count = count;
+
+ if (count == 1) {
+ bip->bli_formats = &bip->__bli_format;
+ return;
+ }
+
+ bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format),
+ 0);
+}
+
+static void
+xfs_buf_item_free_format(
+ struct xfs_buf_log_item *bip)
+{
+ if (bip->bli_formats != &bip->__bli_format) {
+ kmem_free(bip->bli_formats);
+ bip->bli_formats = NULL;
+ }
+}
+
+static void
+xfs_buf_item_free(
+ struct xfs_buf_log_item *bip)
+{
+ xfs_buf_item_free_format(bip);
+ kmem_free(bip->bli_item.li_lv_shadow);
+ kmem_cache_free(xfs_buf_item_cache, bip);
+}
+
+/*
+ * xfs_buf_item_relse() is called when the buf log item is no longer needed.
+ */
+static void
+xfs_buf_item_relse(
+ struct xfs_buf_log_item *bip)
+{
+ struct xfs_buf *bp = bip->bli_buf;
+
+ trace_xfs_buf_item_relse(bp, _RET_IP_);
+
+ ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags));
+
+ if (atomic_read(&bip->bli_refcount))
+ return;
+
+ bp->b_log_item = NULL;
+ xfs_buf_rele(bp);
+ xfs_buf_item_free(bip);
+}
+
/* Is this log iovec plausibly large enough to contain the buffer log format? */
bool
xfs_buf_log_check_iovec(
@@ -563,7 +620,7 @@ xfs_buf_item_unpin(
ASSERT(list_empty(&bp->b_li_list));
} else {
xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
- xfs_buf_item_relse(bp);
+ xfs_buf_item_relse(bip);
ASSERT(bp->b_log_item == NULL);
}
xfs_buf_relse(bp);
@@ -673,7 +730,7 @@ xfs_buf_item_put(
*/
if (aborted)
xfs_trans_ail_delete(lip, 0);
- xfs_buf_item_relse(bip->bli_buf);
+ xfs_buf_item_relse(bip);
return true;
}
@@ -824,33 +881,6 @@ static const struct xfs_item_ops xfs_buf_item_ops = {
.iop_push = xfs_buf_item_push,
};
-STATIC void
-xfs_buf_item_get_format(
- struct xfs_buf_log_item *bip,
- int count)
-{
- ASSERT(bip->bli_formats == NULL);
- bip->bli_format_count = count;
-
- if (count == 1) {
- bip->bli_formats = &bip->__bli_format;
- return;
- }
-
- bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format),
- 0);
-}
-
-STATIC void
-xfs_buf_item_free_format(
- struct xfs_buf_log_item *bip)
-{
- if (bip->bli_formats != &bip->__bli_format) {
- kmem_free(bip->bli_formats);
- bip->bli_formats = NULL;
- }
-}
-
/*
* Allocate a new buf log item to go with the given buffer.
* Set the buffer's b_log_item field to point to the new
@@ -1072,34 +1102,6 @@ xfs_buf_item_dirty_format(
return false;
}
-STATIC void
-xfs_buf_item_free(
- struct xfs_buf_log_item *bip)
-{
- xfs_buf_item_free_format(bip);
- kmem_free(bip->bli_item.li_lv_shadow);
- kmem_cache_free(xfs_buf_item_cache, bip);
-}
-
-/*
- * xfs_buf_item_relse() is called when the buf log item is no longer needed.
- */
-void
-xfs_buf_item_relse(
- struct xfs_buf *bp)
-{
- struct xfs_buf_log_item *bip = bp->b_log_item;
-
- trace_xfs_buf_item_relse(bp, _RET_IP_);
- ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags));
-
- if (atomic_read(&bip->bli_refcount))
- return;
- bp->b_log_item = NULL;
- xfs_buf_rele(bp);
- xfs_buf_item_free(bip);
-}
-
void
xfs_buf_item_done(
struct xfs_buf *bp)
@@ -1119,5 +1121,5 @@ xfs_buf_item_done(
xfs_trans_ail_delete(&bp->b_log_item->bli_item,
(bp->b_flags & _XBF_LOGRECOVERY) ? 0 :
SHUTDOWN_CORRUPT_INCORE);
- xfs_buf_item_relse(bp);
+ xfs_buf_item_relse(bp->b_log_item);
}
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 7ddda0aa9dac2..8a8a46e698be4 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -49,7 +49,6 @@ struct xfs_buf_log_item {
int xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
void xfs_buf_item_done(struct xfs_buf *bp);
-void xfs_buf_item_relse(struct xfs_buf *);
bool xfs_buf_item_put(struct xfs_buf_log_item *);
void xfs_buf_item_log(struct xfs_buf_log_item *, uint, uint);
bool xfs_buf_item_dirty_format(struct xfs_buf_log_item *);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0549/1887] xfs: factor out stale buffer item completion
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (547 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0548/1887] xfs: rearrange code in xfs_buf_item.c Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0550/1887] xfs: fix unmount hang with unflushable inodes stuck in the AIL Greg Kroah-Hartman
` (449 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Carlos Maiolino,
Carlos Maiolino, Siddh Raman Pant, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@redhat.com>
[ Upstream commit 816c330b605c3f4813c0dc0ab5af5cce17ff06b3 ]
The stale buffer item completion handling is currently only done
from BLI unpinning. We need to perform this function from where-ever
the last reference to the BLI is dropped, so first we need to
factor this code out into a helper.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_buf_item.c | 60 ++++++++++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 23 deletions(-)
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 1b323b3c0eb93..ade89a233e686 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -541,6 +541,42 @@ xfs_buf_item_pin(
atomic_inc(&bip->bli_buf->b_pin_count);
}
+/*
+ * For a stale BLI, process all the necessary completions that must be
+ * performed when the final BLI reference goes away. The buffer will be
+ * referenced and locked here - we return to the caller with the buffer still
+ * referenced and locked for them to finalise processing of the buffer.
+ */
+static void
+xfs_buf_item_finish_stale(
+ struct xfs_buf_log_item *bip)
+{
+ struct xfs_buf *bp = bip->bli_buf;
+ struct xfs_log_item *lip = &bip->bli_item;
+
+ ASSERT(bip->bli_flags & XFS_BLI_STALE);
+ ASSERT(xfs_buf_islocked(bp));
+ ASSERT(bp->b_flags & XBF_STALE);
+ ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
+ ASSERT(list_empty(&lip->li_trans));
+ ASSERT(!bp->b_transp);
+
+ if (bip->bli_flags & XFS_BLI_STALE_INODE) {
+ xfs_buf_item_done(bp);
+ xfs_buf_inode_iodone(bp);
+ ASSERT(list_empty(&bp->b_li_list));
+ return;
+ }
+
+ /*
+ * We may or may not be on the AIL here, xfs_trans_ail_delete() will do
+ * the right thing regardless of the situation in which we are called.
+ */
+ xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
+ xfs_buf_item_relse(bip);
+ ASSERT(bp->b_log_item == NULL);
+}
+
/*
* This is called to unpin the buffer associated with the buf log item which was
* previously pinned with a call to xfs_buf_item_pin(). We enter this function
@@ -590,13 +626,6 @@ xfs_buf_item_unpin(
}
if (stale) {
- ASSERT(bip->bli_flags & XFS_BLI_STALE);
- ASSERT(xfs_buf_islocked(bp));
- ASSERT(bp->b_flags & XBF_STALE);
- ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
- ASSERT(list_empty(&lip->li_trans));
- ASSERT(!bp->b_transp);
-
trace_xfs_buf_item_unpin_stale(bip);
/*
@@ -607,22 +636,7 @@ xfs_buf_item_unpin(
* processing is complete.
*/
xfs_buf_rele(bp);
-
- /*
- * If we get called here because of an IO error, we may or may
- * not have the item on the AIL. xfs_trans_ail_delete() will
- * take care of that situation. xfs_trans_ail_delete() drops
- * the AIL lock.
- */
- if (bip->bli_flags & XFS_BLI_STALE_INODE) {
- xfs_buf_item_done(bp);
- xfs_buf_inode_iodone(bp);
- ASSERT(list_empty(&bp->b_li_list));
- } else {
- xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
- xfs_buf_item_relse(bip);
- ASSERT(bp->b_log_item == NULL);
- }
+ xfs_buf_item_finish_stale(bip);
xfs_buf_relse(bp);
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0550/1887] xfs: fix unmount hang with unflushable inodes stuck in the AIL
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (548 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0549/1887] xfs: factor out stale buffer item completion Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0551/1887] mm: migrate: fix getting incorrect page mapping during page migration Greg Kroah-Hartman
` (448 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Carlos Maiolino,
Carlos Maiolino, Siddh Raman Pant, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <dchinner@redhat.com>
[ Upstream commit 7b5f775be14ac1532c049022feadcfe44769566d ]
Unmount of a shutdown filesystem can hang with stale inode cluster
buffers in the AIL like so:
[95964.140623] Call Trace:
[95964.144641] __schedule+0x699/0xb70
[95964.154003] schedule+0x64/0xd0
[95964.156851] xfs_ail_push_all_sync+0x9b/0xf0
[95964.164816] xfs_unmount_flush_inodes+0x41/0x70
[95964.168698] xfs_unmountfs+0x7f/0x170
[95964.171846] xfs_fs_put_super+0x3b/0x90
[95964.175216] generic_shutdown_super+0x77/0x160
[95964.178060] kill_block_super+0x1b/0x40
[95964.180553] xfs_kill_sb+0x12/0x30
[95964.182796] deactivate_locked_super+0x38/0x100
[95964.185735] deactivate_super+0x41/0x50
[95964.188245] cleanup_mnt+0x9f/0x160
[95964.190519] __cleanup_mnt+0x12/0x20
[95964.192899] task_work_run+0x89/0xb0
[95964.195221] resume_user_mode_work+0x4f/0x60
[95964.197931] syscall_exit_to_user_mode+0x76/0xb0
[95964.201003] do_syscall_64+0x74/0x130
$ pstree -N mnt |grep umount
|-check-parallel---nsexec---run_test.sh---753---umount
It always seems to be generic/753 that triggers this, and repeating
a quick group test run triggers it every 10-15 iterations. Hence it
generally triggers once up every 30-40 minutes of test time. just
running generic/753 by itself or concurrently with a limited group
of tests doesn't reproduce this issue at all.
Tracing on a hung system shows the AIL repeating every 50ms a log
force followed by an attempt to push pinned, aborted inodes from the
AIL (trimmed for brevity):
xfs_log_force: lsn 0x1c caller xfsaild+0x18e
xfs_log_force: lsn 0x0 caller xlog_cil_flush+0xbd
xfs_log_force: lsn 0x1c caller xfs_log_force+0x77
xfs_ail_pinned: lip 0xffff88826014afa0 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
xfs_ail_pinned: lip 0xffff88814000a708 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
xfs_ail_pinned: lip 0xffff88810b850c80 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
xfs_ail_pinned: lip 0xffff88810b850af0 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
xfs_ail_pinned: lip 0xffff888165cf0a28 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
xfs_ail_pinned: lip 0xffff88810b850bb8 lsn 1/37472 type XFS_LI_INODE flags IN_AIL|ABORTED
....
The inode log items are marked as aborted, which means that either:
a) a transaction commit has occurred, seen an error or shutdown, and
called xfs_trans_free_items() to abort the items. This should happen
before any pinning of log items occurs.
or
b) a dirty transaction has been cancelled. This should also happen
before any pinning of log items occurs.
or
c) AIL insertion at journal IO completion is marked as aborted. In
this case, the log item is pinned by the CIL until journal IO
completes and hence needs to be unpinned. This is then done after
the ->iop_committed() callback is run, so the pin count should be
balanced correctly.
Yet none of these seemed to be occurring. Further tracing indicated
this:
d) Shutdown during CIL pushing resulting in log item completion
being called from checkpoint abort processing. Items are unpinned
and released without serialisation against each other, journal IO
completion or transaction commit completion.
In this case, we may still have a transaction commit in flight that
holds a reference to a xfs_buf_log_item (BLI) after CIL insertion.
e.g. a synchronous transaction will flush the CIL before the
transaction is torn down. The concurrent CIL push then aborts
insertion it and drops the commit/AIL reference to the BLI. This can
leave the transaction commit context with the last reference to the
BLI which is dropped here:
xfs_trans_free_items()
->iop_release
xfs_buf_item_release
xfs_buf_item_put
if (XFS_LI_ABORTED)
xfs_trans_ail_delete
xfs_buf_item_relse()
Unlike the journal completion ->iop_unpin path, this path does not
run stale buffer completion process when it drops the last
reference, hence leaving the stale inodes attached to the buffer
sitting the AIL. There are no other references to those inodes, so
there is no other mechanism to remove them from the AIL. Hence
unmount hangs.
The buffer lock context for stale buffers is passed to the last BLI
reference. This is normally the last BLI unpin on journal IO
completion. The unpin then processes the stale buffer completion and
releases the buffer lock. However, if the final unpin from journal
IO completion (or CIL push abort) does not hold the last reference
to the BLI, there -must- still be a transaction context that
references the BLI, and so that context must perform the stale
buffer completion processing before the buffer is unlocked and the
BLI torn down.
The fix for this is to rework the xfs_buf_item_relse() path to run
stale buffer completion processing if it drops the last reference to
the BLI. We still hold the buffer locked, so the buffer owner and
lock context is the same as if we passed the BLI and buffer to the
->iop_unpin() context to finish stale process on journal commit.
However, we have to be careful here. In a shutdown state, we can be
freeing dirty BLIs from xfs_buf_item_put() via xfs_trans_brelse()
and xfs_trans_bdetach(). The existing code handles this case by
considering shutdown state as "aborted", but in doing so
largely masks the failure to clean up stale BLI state from the
xfs_buf_item_relse() path. i.e regardless of the shutdown state and
whether the item is in the AIL, we must finish the stale buffer
cleanup if we are are dropping the last BLI reference from the
->iop_relse path in transaction commit context.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_buf_item.c | 121 +++++++++++++++++++++++++++++-------------
fs/xfs/xfs_buf_item.h | 2 +-
2 files changed, 86 insertions(+), 37 deletions(-)
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index ade89a233e686..a5f3408e213db 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -709,43 +709,42 @@ xfs_buf_item_push(
* Drop the buffer log item refcount and take appropriate action. This helper
* determines whether the bli must be freed or not, since a decrement to zero
* does not necessarily mean the bli is unused.
- *
- * Return true if the bli is freed, false otherwise.
*/
-bool
+void
xfs_buf_item_put(
struct xfs_buf_log_item *bip)
{
- struct xfs_log_item *lip = &bip->bli_item;
- bool aborted;
- bool dirty;
+
+ ASSERT(xfs_buf_islocked(bip->bli_buf));
/* drop the bli ref and return if it wasn't the last one */
if (!atomic_dec_and_test(&bip->bli_refcount))
- return false;
+ return;
- /*
- * We dropped the last ref and must free the item if clean or aborted.
- * If the bli is dirty and non-aborted, the buffer was clean in the
- * transaction but still awaiting writeback from previous changes. In
- * that case, the bli is freed on buffer writeback completion.
- */
- aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags) ||
- xlog_is_shutdown(lip->li_log);
- dirty = bip->bli_flags & XFS_BLI_DIRTY;
- if (dirty && !aborted)
- return false;
+ /* If the BLI is in the AIL, then it is still dirty and in use */
+ if (test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)) {
+ ASSERT(bip->bli_flags & XFS_BLI_DIRTY);
+ return;
+ }
/*
- * The bli is aborted or clean. An aborted item may be in the AIL
- * regardless of dirty state. For example, consider an aborted
- * transaction that invalidated a dirty bli and cleared the dirty
- * state.
+ * In shutdown conditions, we can be asked to free a dirty BLI that
+ * isn't in the AIL. This can occur due to a checkpoint aborting a BLI
+ * instead of inserting it into the AIL at checkpoint IO completion. If
+ * there's another bli reference (e.g. a btree cursor holds a clean
+ * reference) and it is released via xfs_trans_brelse(), we can get here
+ * with that aborted, dirty BLI. In this case, it is safe to free the
+ * dirty BLI immediately, as it is not in the AIL and there are no
+ * other references to it.
+ *
+ * We should never get here with a stale BLI via that path as
+ * xfs_trans_brelse() specifically holds onto stale buffers rather than
+ * releasing them.
*/
- if (aborted)
- xfs_trans_ail_delete(lip, 0);
+ ASSERT(!(bip->bli_flags & XFS_BLI_DIRTY) ||
+ test_bit(XFS_LI_ABORTED, &bip->bli_item.li_flags));
+ ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
xfs_buf_item_relse(bip);
- return true;
}
/*
@@ -766,6 +765,15 @@ xfs_buf_item_put(
* if necessary but do not unlock the buffer. This is for support of
* xfs_trans_bhold(). Make sure the XFS_BLI_HOLD field is cleared if we don't
* free the item.
+ *
+ * If the XFS_BLI_STALE flag is set, the last reference to the BLI *must*
+ * perform a completion abort of any objects attached to the buffer for IO
+ * tracking purposes. This generally only happens in shutdown situations,
+ * normally xfs_buf_item_unpin() will drop the last BLI reference and perform
+ * completion processing. However, because transaction completion can race with
+ * checkpoint completion during a shutdown, this release context may end up
+ * being the last active reference to the BLI and so needs to perform this
+ * cleanup.
*/
STATIC void
xfs_buf_item_release(
@@ -773,18 +781,19 @@ xfs_buf_item_release(
{
struct xfs_buf_log_item *bip = BUF_ITEM(lip);
struct xfs_buf *bp = bip->bli_buf;
- bool released;
bool hold = bip->bli_flags & XFS_BLI_HOLD;
bool stale = bip->bli_flags & XFS_BLI_STALE;
-#if defined(DEBUG) || defined(XFS_WARN)
- bool ordered = bip->bli_flags & XFS_BLI_ORDERED;
- bool dirty = bip->bli_flags & XFS_BLI_DIRTY;
bool aborted = test_bit(XFS_LI_ABORTED,
&lip->li_flags);
+ bool dirty = bip->bli_flags & XFS_BLI_DIRTY;
+#if defined(DEBUG) || defined(XFS_WARN)
+ bool ordered = bip->bli_flags & XFS_BLI_ORDERED;
#endif
trace_xfs_buf_item_release(bip);
+ ASSERT(xfs_buf_islocked(bp));
+
/*
* The bli dirty state should match whether the blf has logged segments
* except for ordered buffers, where only the bli should be dirty.
@@ -800,16 +809,56 @@ xfs_buf_item_release(
bp->b_transp = NULL;
bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED);
+ /* If there are other references, then we have nothing to do. */
+ if (!atomic_dec_and_test(&bip->bli_refcount))
+ goto out_release;
+
+ /*
+ * Stale buffer completion frees the BLI, unlocks and releases the
+ * buffer. Neither the BLI or buffer are safe to reference after this
+ * call, so there's nothing more we need to do here.
+ *
+ * If we get here with a stale buffer and references to the BLI remain,
+ * we must not unlock the buffer as the last BLI reference owns lock
+ * context, not us.
+ */
+ if (stale) {
+ xfs_buf_item_finish_stale(bip);
+ xfs_buf_relse(bp);
+ ASSERT(!hold);
+ return;
+ }
+
+ /*
+ * Dirty or clean, aborted items are done and need to be removed from
+ * the AIL and released. This frees the BLI, but leaves the buffer
+ * locked and referenced.
+ */
+ if (aborted || xlog_is_shutdown(lip->li_log)) {
+ ASSERT(list_empty(&bip->bli_buf->b_li_list));
+ xfs_buf_item_done(bp);
+ goto out_release;
+ }
+
+ /*
+ * Clean, unreferenced BLIs can be immediately freed, leaving the buffer
+ * locked and referenced.
+ *
+ * Dirty, unreferenced BLIs *must* be in the AIL awaiting writeback.
+ */
+ if (!dirty)
+ xfs_buf_item_relse(bip);
+ else
+ ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
+
+ /* Not safe to reference the BLI from here */
+out_release:
/*
- * Unref the item and unlock the buffer unless held or stale. Stale
- * buffers remain locked until final unpin unless the bli is freed by
- * the unref call. The latter implies shutdown because buffer
- * invalidation dirties the bli and transaction.
+ * If we get here with a stale buffer, we must not unlock the
+ * buffer as the last BLI reference owns lock context, not us.
*/
- released = xfs_buf_item_put(bip);
- if (hold || (stale && !released))
+ if (stale || hold)
return;
- ASSERT(!stale || aborted);
xfs_buf_relse(bp);
}
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 8a8a46e698be4..141c3780a36b9 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -49,7 +49,7 @@ struct xfs_buf_log_item {
int xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
void xfs_buf_item_done(struct xfs_buf *bp);
-bool xfs_buf_item_put(struct xfs_buf_log_item *);
+void xfs_buf_item_put(struct xfs_buf_log_item *bip);
void xfs_buf_item_log(struct xfs_buf_log_item *, uint, uint);
bool xfs_buf_item_dirty_format(struct xfs_buf_log_item *);
void xfs_buf_inode_iodone(struct xfs_buf *);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0551/1887] mm: migrate: fix getting incorrect page mapping during page migration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (549 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0550/1887] xfs: fix unmount hang with unflushable inodes stuck in the AIL Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0552/1887] drm/msm/dpu: Add mutex lock in control vblank irq Greg Kroah-Hartman
` (447 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Wang, Huang, Ying,
Matthew Wilcox, David Hildenbrand, Xu Yu, Zi Yan, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Wang <baolin.wang@linux.alibaba.com>
[ Upstream commit d1adb25df7111de83b64655a80b5a135adbded61 ]
When running stress-ng testing, we found below kernel crash after a few hours:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
pc : dentry_name+0xd8/0x224
lr : pointer+0x22c/0x370
sp : ffff800025f134c0
......
Call trace:
dentry_name+0xd8/0x224
pointer+0x22c/0x370
vsnprintf+0x1ec/0x730
vscnprintf+0x2c/0x60
vprintk_store+0x70/0x234
vprintk_emit+0xe0/0x24c
vprintk_default+0x3c/0x44
vprintk_func+0x84/0x2d0
printk+0x64/0x88
__dump_page+0x52c/0x530
dump_page+0x14/0x20
set_migratetype_isolate+0x110/0x224
start_isolate_page_range+0xc4/0x20c
offline_pages+0x124/0x474
memory_block_offline+0x44/0xf4
memory_subsys_offline+0x3c/0x70
device_offline+0xf0/0x120
......
After analyzing the vmcore, I found this issue is caused by page migration.
The scenario is that, one thread is doing page migration, and we will use the
target page's ->mapping field to save 'anon_vma' pointer between page unmap and
page move, and now the target page is locked and refcount is 1.
Currently, there is another stress-ng thread performing memory hotplug,
attempting to offline the target page that is being migrated. It discovers that
the refcount of this target page is 1, preventing the offline operation, thus
proceeding to dump the page. However, page_mapping() of the target page may
return an incorrect file mapping to crash the system in dump_mapping(), since
the target page->mapping only saves 'anon_vma' pointer without setting
PAGE_MAPPING_ANON flag.
There are seveval ways to fix this issue:
(1) Setting the PAGE_MAPPING_ANON flag for target page's ->mapping when saving
'anon_vma', but this can confuse PageAnon() for PFN walkers, since the target
page has not built mappings yet.
(2) Getting the page lock to call page_mapping() in __dump_page() to avoid crashing
the system, however, there are still some PFN walkers that call page_mapping()
without holding the page lock, such as compaction.
(3) Using target page->private field to save the 'anon_vma' pointer and 2 bits
page state, just as page->mapping records an anonymous page, which can remove
the page_mapping() impact for PFN walkers and also seems a simple way.
So I choose option 3 to fix this issue, and this can also fix other potential
issues for PFN walkers, such as compaction.
Link: https://lkml.kernel.org/r/e60b17a88afc38cb32f84c3e30837ec70b343d2b.1702641709.git.baolin.wang@linux.alibaba.com
Fixes: 64c8902ed441 ("migrate_pages: split unmap_and_move() to _unmap() and _move()")
Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Xu Yu <xuyu@linux.alibaba.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/migrate.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 161ab6e2713d2..72ee6896a2cb2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1010,32 +1010,29 @@ static int move_to_new_folio(struct folio *dst, struct folio *src,
}
/*
- * To record some information during migration, we use some unused
- * fields (mapping and private) of struct folio of the newly allocated
- * destination folio. This is safe because nobody is using them
- * except us.
+ * To record some information during migration, we use unused private
+ * field of struct folio of the newly allocated destination folio.
+ * This is safe because nobody is using it except us.
*/
-union migration_ptr {
- struct anon_vma *anon_vma;
- struct address_space *mapping;
+enum {
+ PAGE_WAS_MAPPED = BIT(0),
};
+
static void __migrate_folio_record(struct folio *dst,
- unsigned long page_was_mapped,
+ int page_was_mapped,
struct anon_vma *anon_vma)
{
- union migration_ptr ptr = { .anon_vma = anon_vma };
- dst->mapping = ptr.mapping;
- dst->private = (void *)page_was_mapped;
+ dst->private = (void *)anon_vma + page_was_mapped;
}
static void __migrate_folio_extract(struct folio *dst,
int *page_was_mappedp,
struct anon_vma **anon_vmap)
{
- union migration_ptr ptr = { .mapping = dst->mapping };
- *anon_vmap = ptr.anon_vma;
- *page_was_mappedp = (unsigned long)dst->private;
- dst->mapping = NULL;
+ unsigned long private = (unsigned long)dst->private;
+
+ *anon_vmap = (struct anon_vma *)(private & ~PAGE_WAS_MAPPED);
+ *page_was_mappedp = private & PAGE_WAS_MAPPED;
dst->private = NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0552/1887] drm/msm/dpu: Add mutex lock in control vblank irq
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (550 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0551/1887] mm: migrate: fix getting incorrect page mapping during page migration Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0553/1887] fs: new helper: simple_rename_timestamp Greg Kroah-Hartman
` (446 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paloma Arellano, Dmitry Baryshkov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paloma Arellano <quic_parellan@quicinc.com>
[ Upstream commit 45284ff733e4caf6c118aae5131eb7e7cf3eea5a ]
Add a mutex lock to control vblank irq to synchronize vblank
enable/disable operations happening from different threads to prevent
race conditions while registering/unregistering the vblank irq callback.
v4: -Removed vblank_ctl_lock from dpu_encoder_virt, so it is only a
parameter of dpu_encoder_phys.
-Switch from atomic refcnt to a simple int counter as mutex has
now been added
v3: Mistakenly did not change wording in last version. It is done now.
v2: Slightly changed wording of commit message
Signed-off-by: Paloma Arellano <quic_parellan@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/571854/
Link: https://lore.kernel.org/r/20231212231101.9240-2-quic_parellan@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 4 ++-
.../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 33 +++++++++++------
.../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 35 ++++++++++++-------
.../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 1 -
4 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index f2af07d87f56f..f1f022e9dcf71 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -177,6 +177,7 @@ enum dpu_intr_idx {
* @hw_wb: Hardware interface to the wb registers
* @dpu_kms: Pointer to the dpu_kms top level
* @cached_mode: DRM mode cached at mode_set time, acted on in enable
+ * @vblank_ctl_lock: Vblank ctl mutex lock to protect vblank_refcount
* @enabled: Whether the encoder has enabled and running a mode
* @split_role: Role to play in a split-panel configuration
* @intf_mode: Interface mode
@@ -207,13 +208,14 @@ struct dpu_encoder_phys {
struct dpu_hw_wb *hw_wb;
struct dpu_kms *dpu_kms;
struct drm_display_mode cached_mode;
+ struct mutex vblank_ctl_lock;
enum dpu_enc_split_role split_role;
enum dpu_intf_mode intf_mode;
enum dpu_intf intf_idx;
enum dpu_wb wb_idx;
spinlock_t *enc_spinlock;
enum dpu_enc_enable_state enable_state;
- atomic_t vblank_refcount;
+ int vblank_refcount;
atomic_t vsync_cnt;
atomic_t underrun_cnt;
atomic_t pending_ctlstart_cnt;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 7581e418418f1..b3cb507c052a6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -246,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
return -EINVAL;
}
- refcount = atomic_read(&phys_enc->vblank_refcount);
+ mutex_lock(&phys_enc->vblank_ctl_lock);
+ refcount = phys_enc->vblank_refcount;
/* Slave encoders don't report vblank */
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
@@ -262,16 +263,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
phys_enc->hw_pp->idx - PINGPONG_0,
enable ? "true" : "false", refcount);
- if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
- ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_RDPTR],
- dpu_encoder_phys_cmd_pp_rd_ptr_irq,
- phys_enc);
- else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
- ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_RDPTR]);
+ if (enable) {
+ if (phys_enc->vblank_refcount == 0)
+ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_RDPTR],
+ dpu_encoder_phys_cmd_pp_rd_ptr_irq,
+ phys_enc);
+ if (!ret)
+ phys_enc->vblank_refcount++;
+ } else if (!enable) {
+ if (phys_enc->vblank_refcount == 1)
+ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_RDPTR]);
+ if (!ret)
+ phys_enc->vblank_refcount--;
+ }
end:
+ mutex_unlock(&phys_enc->vblank_ctl_lock);
if (ret) {
DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
DRMID(phys_enc->parent),
@@ -287,7 +296,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
{
trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
phys_enc->hw_pp->idx - PINGPONG_0,
- enable, atomic_read(&phys_enc->vblank_refcount));
+ enable, phys_enc->vblank_refcount);
if (enable) {
dpu_core_irq_register_callback(phys_enc->dpu_kms,
@@ -777,6 +786,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
phys_enc->hw_mdptop = p->dpu_kms->hw_mdp;
phys_enc->intf_idx = p->intf_idx;
+ mutex_init(&phys_enc->vblank_ctl_lock);
+ phys_enc->vblank_refcount = 0;
+
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
@@ -789,7 +801,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
phys_enc->irq[i] = -EINVAL;
- atomic_set(&phys_enc->vblank_refcount, 0);
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
atomic_set(&cmd_enc->pending_vblank_cnt, 0);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 4b7952c4e639f..3b45a50aa9854 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -375,7 +375,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
int ret = 0;
int refcount;
- refcount = atomic_read(&phys_enc->vblank_refcount);
+ mutex_lock(&phys_enc->vblank_ctl_lock);
+ refcount = phys_enc->vblank_refcount;
/* Slave encoders don't report vblank */
if (!dpu_encoder_phys_vid_is_master(phys_enc))
@@ -388,18 +389,26 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
}
DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
- atomic_read(&phys_enc->vblank_refcount));
+ refcount);
- if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
- ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_VSYNC],
- dpu_encoder_phys_vid_vblank_irq,
- phys_enc);
- else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
- ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
- phys_enc->irq[INTR_IDX_VSYNC]);
+ if (enable) {
+ if (phys_enc->vblank_refcount == 0)
+ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_VSYNC],
+ dpu_encoder_phys_vid_vblank_irq,
+ phys_enc);
+ if (!ret)
+ phys_enc->vblank_refcount++;
+ } else if (!enable) {
+ if (phys_enc->vblank_refcount == 1)
+ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+ phys_enc->irq[INTR_IDX_VSYNC]);
+ if (!ret)
+ phys_enc->vblank_refcount--;
+ }
end:
+ mutex_unlock(&phys_enc->vblank_ctl_lock);
if (ret) {
DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
DRMID(phys_enc->parent),
@@ -607,7 +616,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
phys_enc->hw_intf->idx - INTF_0,
enable,
- atomic_read(&phys_enc->vblank_refcount));
+ phys_enc->vblank_refcount);
if (enable) {
ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
@@ -703,6 +712,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
DPU_DEBUG_VIDENC(phys_enc, "\n");
+ mutex_init(&phys_enc->vblank_ctl_lock);
+ phys_enc->vblank_refcount = 0;
+
dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
@@ -713,7 +725,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
phys_enc->irq[i] = -EINVAL;
- atomic_set(&phys_enc->vblank_refcount, 0);
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
init_waitqueue_head(&phys_enc->pending_kickoff_wq);
phys_enc->enable_state = DPU_ENC_DISABLED;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index fd5f9d04f81e6..462fa58c660df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -735,7 +735,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
phys_enc->irq[i] = -EINVAL;
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
- atomic_set(&phys_enc->vblank_refcount, 0);
wb_enc->wb_done_timeout_cnt = 0;
init_waitqueue_head(&phys_enc->pending_kickoff_wq);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0553/1887] fs: new helper: simple_rename_timestamp
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (551 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0552/1887] drm/msm/dpu: Add mutex lock in control vblank irq Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0554/1887] reiserfs: convert to simple_rename_timestamp Greg Kroah-Hartman
` (445 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jeff Layton, Jan Kara,
Christian Brauner, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 0c4767923ed6964d279309744cdb248890e95ec2 ]
A rename potentially involves updating 4 different inode timestamps. Add
a function that handles the details sanely, and convert the libfs.c
callers to use it.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Message-Id: <20230705185812.579118-3-jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 49db9b1b86a8 ("reiserfs: Avoid touching renamed directory if parent does not change")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/libfs.c | 36 +++++++++++++++++++++++++++---------
include/linux/fs.h | 2 ++
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index 63bc52c20f7e0..60ec2dd903589 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -449,6 +449,31 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
}
EXPORT_SYMBOL(simple_rmdir);
+/**
+ * simple_rename_timestamp - update the various inode timestamps for rename
+ * @old_dir: old parent directory
+ * @old_dentry: dentry that is being renamed
+ * @new_dir: new parent directory
+ * @new_dentry: target for rename
+ *
+ * POSIX mandates that the old and new parent directories have their ctime and
+ * mtime updated, and that inodes of @old_dentry and @new_dentry (if any), have
+ * their ctime updated.
+ */
+void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *newino = d_inode(new_dentry);
+
+ old_dir->i_mtime = inode_set_ctime_current(old_dir);
+ if (new_dir != old_dir)
+ new_dir->i_mtime = inode_set_ctime_current(new_dir);
+ inode_set_ctime_current(d_inode(old_dentry));
+ if (newino)
+ inode_set_ctime_current(newino);
+}
+EXPORT_SYMBOL_GPL(simple_rename_timestamp);
+
int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
@@ -464,11 +489,7 @@ int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
inc_nlink(old_dir);
}
}
- old_dir->i_ctime = old_dir->i_mtime =
- new_dir->i_ctime = new_dir->i_mtime =
- d_inode(old_dentry)->i_ctime =
- d_inode(new_dentry)->i_ctime = current_time(old_dir);
-
+ simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
return 0;
}
EXPORT_SYMBOL_GPL(simple_rename_exchange);
@@ -477,7 +498,6 @@ int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
- struct inode *inode = d_inode(old_dentry);
int they_are_dirs = d_is_dir(old_dentry);
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
@@ -500,9 +520,7 @@ int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
inc_nlink(new_dir);
}
- old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
- new_dir->i_mtime = inode->i_ctime = current_time(old_dir);
-
+ simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
return 0;
}
EXPORT_SYMBOL(simple_rename);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 264381ae06e26..0692c2e0fcf3f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3483,6 +3483,8 @@ extern int simple_open(struct inode *inode, struct file *file);
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
+void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);
extern int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
extern int simple_rename(struct user_namespace *, struct inode *,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0554/1887] reiserfs: convert to simple_rename_timestamp
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (552 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0553/1887] fs: new helper: simple_rename_timestamp Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0555/1887] reiserfs: Avoid touching renamed directory if parent does not change Greg Kroah-Hartman
` (444 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jeff Layton, Jan Kara,
Christian Brauner, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 298d35ef763de3393bd1f60d35ff4203cbb4f26a ]
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Message-Id: <20230705190309.579783-12-jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 49db9b1b86a8 ("reiserfs: Avoid touching renamed directory if parent does not change")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/reiserfs/namei.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index b916859992ec8..fe840620fafae 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1327,7 +1327,6 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
int jbegin_count;
umode_t old_inode_mode;
unsigned long savelink = 1;
- struct timespec64 ctime;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
@@ -1578,14 +1577,11 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
mark_de_hidden(old_de.de_deh + old_de.de_entry_num);
journal_mark_dirty(&th, old_de.de_bh);
- ctime = current_time(old_dir);
- old_dir->i_ctime = old_dir->i_mtime = ctime;
- new_dir->i_ctime = new_dir->i_mtime = ctime;
/*
* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch
* which adds ctime update of renamed object
*/
- old_inode->i_ctime = ctime;
+ simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
if (new_dentry_inode) {
/* adjust link number of the victim */
@@ -1594,7 +1590,6 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
} else {
drop_nlink(new_dentry_inode);
}
- new_dentry_inode->i_ctime = ctime;
savelink = new_dentry_inode->i_nlink;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0555/1887] reiserfs: Avoid touching renamed directory if parent does not change
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (553 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0554/1887] reiserfs: convert to simple_rename_timestamp Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0556/1887] SUNRPC: fix a memleak in gss_import_v2_context Greg Kroah-Hartman
` (443 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jan Kara, Al Viro, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
[ Upstream commit 49db9b1b86a82448dfaf3fcfefcf678dee56c8ed ]
The VFS will not be locking moved directory if its parent does not
change. Change reiserfs rename code to avoid touching renamed directory
if its parent does not change as without locking that can corrupt the
filesystem.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/reiserfs/namei.c | 54 ++++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 25 deletions(-)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index fe840620fafae..0e6bf4f6a80f2 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1325,8 +1325,8 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
struct inode *old_inode, *new_dentry_inode;
struct reiserfs_transaction_handle th;
int jbegin_count;
- umode_t old_inode_mode;
unsigned long savelink = 1;
+ bool update_dir_parent = false;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
@@ -1376,8 +1376,7 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
return -ENOENT;
}
- old_inode_mode = old_inode->i_mode;
- if (S_ISDIR(old_inode_mode)) {
+ if (S_ISDIR(old_inode->i_mode)) {
/*
* make sure that directory being renamed has correct ".."
* and that its new parent directory has not too many links
@@ -1390,24 +1389,28 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
}
}
- /*
- * directory is renamed, its parent directory will be changed,
- * so find ".." entry
- */
- dot_dot_de.de_gen_number_bit_string = NULL;
- retval =
- reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path,
+ if (old_dir != new_dir) {
+ /*
+ * directory is renamed, its parent directory will be
+ * changed, so find ".." entry
+ */
+ dot_dot_de.de_gen_number_bit_string = NULL;
+ retval =
+ reiserfs_find_entry(old_inode, "..", 2,
+ &dot_dot_entry_path,
&dot_dot_de);
- pathrelse(&dot_dot_entry_path);
- if (retval != NAME_FOUND) {
- reiserfs_write_unlock(old_dir->i_sb);
- return -EIO;
- }
+ pathrelse(&dot_dot_entry_path);
+ if (retval != NAME_FOUND) {
+ reiserfs_write_unlock(old_dir->i_sb);
+ return -EIO;
+ }
- /* inode number of .. must equal old_dir->i_ino */
- if (dot_dot_de.de_objectid != old_dir->i_ino) {
- reiserfs_write_unlock(old_dir->i_sb);
- return -EIO;
+ /* inode number of .. must equal old_dir->i_ino */
+ if (dot_dot_de.de_objectid != old_dir->i_ino) {
+ reiserfs_write_unlock(old_dir->i_sb);
+ return -EIO;
+ }
+ update_dir_parent = true;
}
}
@@ -1487,7 +1490,7 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1);
- if (S_ISDIR(old_inode->i_mode)) {
+ if (update_dir_parent) {
if ((retval =
search_by_entry_key(new_dir->i_sb,
&dot_dot_de.de_entry_key,
@@ -1535,14 +1538,14 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
new_de.de_bh);
reiserfs_restore_prepared_buffer(old_inode->i_sb,
old_de.de_bh);
- if (S_ISDIR(old_inode_mode))
+ if (update_dir_parent)
reiserfs_restore_prepared_buffer(old_inode->
i_sb,
dot_dot_de.
de_bh);
continue;
}
- if (S_ISDIR(old_inode_mode)) {
+ if (update_dir_parent) {
if (item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
!entry_points_to_object("..", 2, &dot_dot_de,
old_dir)) {
@@ -1560,7 +1563,7 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
}
}
- RFALSE(S_ISDIR(old_inode_mode) &&
+ RFALSE(update_dir_parent &&
!buffer_journal_prepared(dot_dot_de.de_bh), "");
break;
@@ -1593,11 +1596,12 @@ static int reiserfs_rename(struct user_namespace *mnt_userns,
savelink = new_dentry_inode->i_nlink;
}
- if (S_ISDIR(old_inode_mode)) {
+ if (update_dir_parent) {
/* adjust ".." of renamed directory */
set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir));
journal_mark_dirty(&th, dot_dot_de.de_bh);
-
+ }
+ if (S_ISDIR(old_inode->i_mode)) {
/*
* there (in new_dir) was no directory, so it got new link
* (".." of renamed directory)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0556/1887] SUNRPC: fix a memleak in gss_import_v2_context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (554 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0555/1887] reiserfs: Avoid touching renamed directory if parent does not change Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0557/1887] drm/amd/display: Fix hang/underflow when transitioning to ODM4:1 Greg Kroah-Hartman
` (442 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhipeng Lu, Jeff Layton, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhipeng Lu <alexious@zju.edu.cn>
[ Upstream commit e67b652d8e8591d3b1e569dbcdfcee15993e91fa ]
The ctx->mech_used.data allocated by kmemdup is not freed in neither
gss_import_v2_context nor it only caller gss_krb5_import_sec_context,
which frees ctx on error.
Thus, this patch reform the last call of gss_import_v2_context to the
gss_krb5_import_ctx_v2, preventing the memleak while keepping the return
formation.
Fixes: 47d848077629 ("gss_krb5: handle new context format from gssd")
Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/auth_gss/gss_krb5_mech.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 1c092b05c2bba..8fc6f25468ac6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -471,6 +471,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
u64 seq_send64;
int keylen;
u32 time32;
+ int ret;
p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
if (IS_ERR(p))
@@ -528,14 +529,24 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
switch (ctx->enctype) {
case ENCTYPE_DES3_CBC_RAW:
- return context_derive_keys_des3(ctx, gfp_mask);
+ ret = context_derive_keys_des3(ctx, gfp_mask);
+ break;
case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
- return context_derive_keys_new(ctx, gfp_mask);
+ ret = context_derive_keys_new(ctx, gfp_mask);
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ }
+ if (ret) {
+ p = ERR_PTR(ret);
+ goto out_free;
}
+ return 0;
+
+out_free:
+ kfree(ctx->mech_used.data);
out_err:
return PTR_ERR(p);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0557/1887] drm/amd/display: Fix hang/underflow when transitioning to ODM4:1
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (555 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0556/1887] SUNRPC: fix a memleak in gss_import_v2_context Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0558/1887] smb: client: fix use-after-free in smb2_query_info_compound() Greg Kroah-Hartman
` (441 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Lee, Wayne Lin, Ilya Bakoulin,
Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Bakoulin <ilya.bakoulin@amd.com>
[ Upstream commit e7b2b108cdeab76a7e7324459e50b0c1214c0386 ]
[Why]
Under some circumstances, disabling an OPTC and attempting to reclaim
its OPP(s) for a different OPTC could cause a hang/underflow due to OPPs
not being properly disconnected from the disabled OPTC.
[How]
Ensure that all OPPs are unassigned from an OPTC when it gets disabled.
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c | 7 +++++++
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
index 7dd36e402bac7..56487ba4d00e6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
@@ -139,6 +139,13 @@ static bool optc314_disable_crtc(struct timing_generator *optc)
REG_UPDATE(OTG_CONTROL,
OTG_MASTER_EN, 0);
+ REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
+ OPTC_SEG0_SRC_SEL, 0xf,
+ OPTC_SEG1_SRC_SEL, 0xf,
+ OPTC_SEG2_SRC_SEL, 0xf,
+ OPTC_SEG3_SRC_SEL, 0xf,
+ OPTC_NUM_OF_INPUT_SEGMENT, 0);
+
REG_UPDATE(CONTROL,
VTG0_ENABLE, 0);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
index 37c645a882dd8..4a2fa9bb5393c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
@@ -145,6 +145,13 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
REG_UPDATE(OTG_CONTROL,
OTG_MASTER_EN, 0);
+ REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
+ OPTC_SEG0_SRC_SEL, 0xf,
+ OPTC_SEG1_SRC_SEL, 0xf,
+ OPTC_SEG2_SRC_SEL, 0xf,
+ OPTC_SEG3_SRC_SEL, 0xf,
+ OPTC_NUM_OF_INPUT_SEGMENT, 0);
+
REG_UPDATE(CONTROL,
VTG0_ENABLE, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0558/1887] smb: client: fix use-after-free in smb2_query_info_compound()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (556 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0557/1887] drm/amd/display: Fix hang/underflow when transitioning to ODM4:1 Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0559/1887] riscv: VMAP_STACK overflow detection thread-safe Greg Kroah-Hartman
` (440 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulo Alcantara (SUSE), Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.com>
[ Upstream commit 5c86919455c1edec99ebd3338ad213b59271a71b ]
The following UAF was triggered when running fstests generic/072 with
KASAN enabled against Windows Server 2022 and mount options
'multichannel,max_channels=2,vers=3.1.1,mfsymlinks,noperm'
BUG: KASAN: slab-use-after-free in smb2_query_info_compound+0x423/0x6d0 [cifs]
Read of size 8 at addr ffff888014941048 by task xfs_io/27534
CPU: 0 PID: 27534 Comm: xfs_io Not tainted 6.6.0-rc7 #1
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
Call Trace:
dump_stack_lvl+0x4a/0x80
print_report+0xcf/0x650
? srso_alias_return_thunk+0x5/0x7f
? srso_alias_return_thunk+0x5/0x7f
? __phys_addr+0x46/0x90
kasan_report+0xda/0x110
? smb2_query_info_compound+0x423/0x6d0 [cifs]
? smb2_query_info_compound+0x423/0x6d0 [cifs]
smb2_query_info_compound+0x423/0x6d0 [cifs]
? __pfx_smb2_query_info_compound+0x10/0x10 [cifs]
? srso_alias_return_thunk+0x5/0x7f
? __stack_depot_save+0x39/0x480
? kasan_save_stack+0x33/0x60
? kasan_set_track+0x25/0x30
? ____kasan_slab_free+0x126/0x170
smb2_queryfs+0xc2/0x2c0 [cifs]
? __pfx_smb2_queryfs+0x10/0x10 [cifs]
? __pfx___lock_acquire+0x10/0x10
smb311_queryfs+0x210/0x220 [cifs]
? __pfx_smb311_queryfs+0x10/0x10 [cifs]
? srso_alias_return_thunk+0x5/0x7f
? __lock_acquire+0x480/0x26c0
? lock_release+0x1ed/0x640
? srso_alias_return_thunk+0x5/0x7f
? do_raw_spin_unlock+0x9b/0x100
cifs_statfs+0x18c/0x4b0 [cifs]
statfs_by_dentry+0x9b/0xf0
fd_statfs+0x4e/0xb0
__do_sys_fstatfs+0x7f/0xe0
? __pfx___do_sys_fstatfs+0x10/0x10
? srso_alias_return_thunk+0x5/0x7f
? lockdep_hardirqs_on_prepare+0x136/0x200
? srso_alias_return_thunk+0x5/0x7f
do_syscall_64+0x3f/0x90
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Allocated by task 27534:
kasan_save_stack+0x33/0x60
kasan_set_track+0x25/0x30
__kasan_kmalloc+0x8f/0xa0
open_cached_dir+0x71b/0x1240 [cifs]
smb2_query_info_compound+0x5c3/0x6d0 [cifs]
smb2_queryfs+0xc2/0x2c0 [cifs]
smb311_queryfs+0x210/0x220 [cifs]
cifs_statfs+0x18c/0x4b0 [cifs]
statfs_by_dentry+0x9b/0xf0
fd_statfs+0x4e/0xb0
__do_sys_fstatfs+0x7f/0xe0
do_syscall_64+0x3f/0x90
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Freed by task 27534:
kasan_save_stack+0x33/0x60
kasan_set_track+0x25/0x30
kasan_save_free_info+0x2b/0x50
____kasan_slab_free+0x126/0x170
slab_free_freelist_hook+0xd0/0x1e0
__kmem_cache_free+0x9d/0x1b0
open_cached_dir+0xff5/0x1240 [cifs]
smb2_query_info_compound+0x5c3/0x6d0 [cifs]
smb2_queryfs+0xc2/0x2c0 [cifs]
This is a race between open_cached_dir() and cached_dir_lease_break()
where the cache entry for the open directory handle receives a lease
break while creating it. And before returning from open_cached_dir(),
we put the last reference of the new @cfid because of
!@cfid->has_lease.
Besides the UAF, while running xfstests a lot of missed lease breaks
have been noticed in tests that run several concurrent statfs(2) calls
on those cached fids
CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
CIFS: VFS: \\w22-root1.gandalf.test smb buf 00000000715bfe83 len 108
CIFS: VFS: Dump pending requests:
CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
CIFS: VFS: \\w22-root1.gandalf.test smb buf 000000005aa7316e len 108
...
To fix both, in open_cached_dir() ensure that @cfid->has_lease is set
right before sending out compounded request so that any potential
lease break will be get processed by demultiplex thread while we're
still caching @cfid. And, if open failed for some reason, re-check
@cfid->has_lease to decide whether or not put lease reference.
Cc: stable@vger.kernel.org
Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cached_dir.c | 97 +++++++++++++++++++++++---------------
1 file changed, 60 insertions(+), 37 deletions(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index fca8656929399..bac6ceccaaa9c 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -30,7 +30,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
* fully cached or it may be in the process of
* being deleted due to a lease break.
*/
- if (!cfid->has_lease) {
+ if (!cfid->time || !cfid->has_lease) {
spin_unlock(&cfids->cfid_list_lock);
return NULL;
}
@@ -188,10 +188,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
npath = path_no_prefix(cifs_sb, path);
if (IS_ERR(npath)) {
rc = PTR_ERR(npath);
- kfree(utf16_path);
- return rc;
+ goto out;
}
+ if (!npath[0]) {
+ dentry = dget(cifs_sb->root);
+ } else {
+ dentry = path_to_dentry(cifs_sb, npath);
+ if (IS_ERR(dentry)) {
+ rc = -ENOENT;
+ goto out;
+ }
+ }
+ cfid->dentry = dentry;
+
/*
* We do not hold the lock for the open because in case
* SMB2_open needs to reconnect.
@@ -253,6 +263,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
smb2_set_related(&rqst[1]);
+ /*
+ * Set @cfid->has_lease to true before sending out compounded request so
+ * its lease reference can be put in cached_dir_lease_break() due to a
+ * potential lease break right after the request is sent or while @cfid
+ * is still being cached. Concurrent processes won't be to use it yet
+ * due to @cfid->time being zero.
+ */
+ cfid->has_lease = true;
+
rc = compound_send_recv(xid, ses, server,
flags, 2, rqst,
resp_buftype, rsp_iov);
@@ -267,6 +286,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
cfid->tcon = tcon;
cfid->is_open = true;
+ spin_lock(&cfids->cfid_list_lock);
+
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
oparms.fid->persistent_fid = o_rsp->PersistentFileId;
oparms.fid->volatile_fid = o_rsp->VolatileFileId;
@@ -274,20 +295,30 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
#endif /* CIFS_DEBUG2 */
- if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
+ rc = -EINVAL;
+ if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
+ spin_unlock(&cfids->cfid_list_lock);
goto oshr_free;
+ }
rc = smb2_parse_contexts(server, rsp_iov,
&oparms.fid->epoch,
oparms.fid->lease_key,
&oplock, NULL, NULL);
- if (rc)
+ if (rc) {
+ spin_unlock(&cfids->cfid_list_lock);
goto oshr_free;
- if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
+ }
+ rc = -EINVAL;
+ if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
+ spin_unlock(&cfids->cfid_list_lock);
goto oshr_free;
+ }
qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
- if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
+ if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
+ spin_unlock(&cfids->cfid_list_lock);
goto oshr_free;
+ }
if (!smb2_validate_and_copy_iov(
le16_to_cpu(qi_rsp->OutputBufferOffset),
sizeof(struct smb2_file_all_info),
@@ -295,57 +326,49 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
(char *)&cfid->file_all_info))
cfid->file_all_info_is_valid = true;
- if (!npath[0])
- dentry = dget(cifs_sb->root);
- else {
- dentry = path_to_dentry(cifs_sb, npath);
- if (IS_ERR(dentry)) {
- rc = -ENOENT;
- goto oshr_free;
- }
- }
- cfid->dentry = dentry;
cfid->time = jiffies;
- cfid->has_lease = true;
+ spin_unlock(&cfids->cfid_list_lock);
+ /* At this point the directory handle is fully cached */
+ rc = 0;
oshr_free:
- kfree(utf16_path);
SMB2_open_free(&rqst[0]);
SMB2_query_info_free(&rqst[1]);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
- spin_lock(&cfids->cfid_list_lock);
- if (rc && !cfid->has_lease) {
+ if (rc) {
+ spin_lock(&cfids->cfid_list_lock);
if (cfid->on_list) {
list_del(&cfid->entry);
cfid->on_list = false;
cfids->num_entries--;
}
- rc = -ENOENT;
- }
- spin_unlock(&cfids->cfid_list_lock);
- if (!rc && !cfid->has_lease) {
- /*
- * We are guaranteed to have two references at this point.
- * One for the caller and one for a potential lease.
- * Release the Lease-ref so that the directory will be closed
- * when the caller closes the cached handle.
- */
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ if (cfid->has_lease) {
+ /*
+ * We are guaranteed to have two references at this
+ * point. One for the caller and one for a potential
+ * lease. Release the Lease-ref so that the directory
+ * will be closed when the caller closes the cached
+ * handle.
+ */
+ cfid->has_lease = false;
+ spin_unlock(&cfids->cfid_list_lock);
+ kref_put(&cfid->refcount, smb2_close_cached_fid);
+ goto out;
+ }
+ spin_unlock(&cfids->cfid_list_lock);
}
+out:
if (rc) {
if (cfid->is_open)
SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
cfid->fid.volatile_fid);
free_cached_dir(cfid);
- cfid = NULL;
- }
-
- if (rc == 0) {
+ } else {
*ret_cfid = cfid;
atomic_inc(&tcon->num_remote_opens);
}
-
+ kfree(utf16_path);
return rc;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0559/1887] riscv: VMAP_STACK overflow detection thread-safe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (557 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0558/1887] smb: client: fix use-after-free in smb2_query_info_compound() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0560/1887] f2fs: split initial and dynamic conditions for extent_cache Greg Kroah-Hartman
` (439 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guo Ren, Jisheng Zhang, Deepak Gupta,
Sami Tolvanen, Nathan Chancellor, Palmer Dabbelt, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepak Gupta <debug@rivosinc.com>
[ Upstream commit be97d0db5f44c0674480cb79ac6f5b0529b84c76 ]
commit 31da94c25aea ("riscv: add VMAP_STACK overflow detection") added
support for CONFIG_VMAP_STACK. If overflow is detected, CPU switches to
`shadow_stack` temporarily before switching finally to per-cpu
`overflow_stack`.
If two CPUs/harts are racing and end up in over flowing kernel stack, one
or both will end up corrupting each other state because `shadow_stack` is
not per-cpu. This patch optimizes per-cpu overflow stack switch by
directly picking per-cpu `overflow_stack` and gets rid of `shadow_stack`.
Following are the changes in this patch
- Defines an asm macro to obtain per-cpu symbols in destination
register.
- In entry.S, when overflow is detected, per-cpu overflow stack is
located using per-cpu asm macro. Computing per-cpu symbol requires
a temporary register. x31 is saved away into CSR_SCRATCH
(CSR_SCRATCH is anyways zero since we're in kernel).
Please see Links for additional relevant disccussion and alternative
solution.
Tested by `echo EXHAUST_STACK > /sys/kernel/debug/provoke-crash/DIRECT`
Kernel crash log below
Insufficient stack space to handle exception!/debug/provoke-crash/DIRECT
Task stack: [0xff20000010a98000..0xff20000010a9c000]
Overflow stack: [0xff600001f7d98370..0xff600001f7d99370]
CPU: 1 PID: 205 Comm: bash Not tainted 6.1.0-rc2-00001-g328a1f96f7b9 #34
Hardware name: riscv-virtio,qemu (DT)
epc : __memset+0x60/0xfc
ra : recursive_loop+0x48/0xc6 [lkdtm]
epc : ffffffff808de0e4 ra : ffffffff0163a752 sp : ff20000010a97e80
gp : ffffffff815c0330 tp : ff600000820ea280 t0 : ff20000010a97e88
t1 : 000000000000002e t2 : 3233206874706564 s0 : ff20000010a982b0
s1 : 0000000000000012 a0 : ff20000010a97e88 a1 : 0000000000000000
a2 : 0000000000000400 a3 : ff20000010a98288 a4 : 0000000000000000
a5 : 0000000000000000 a6 : fffffffffffe43f0 a7 : 00007fffffffffff
s2 : ff20000010a97e88 s3 : ffffffff01644680 s4 : ff20000010a9be90
s5 : ff600000842ba6c0 s6 : 00aaaaaac29e42b0 s7 : 00fffffff0aa3684
s8 : 00aaaaaac2978040 s9 : 0000000000000065 s10: 00ffffff8a7cad10
s11: 00ffffff8a76a4e0 t3 : ffffffff815dbaf4 t4 : ffffffff815dbaf4
t5 : ffffffff815dbab8 t6 : ff20000010a9bb48
status: 0000000200000120 badaddr: ff20000010a97e88 cause: 000000000000000f
Kernel panic - not syncing: Kernel stack overflow
CPU: 1 PID: 205 Comm: bash Not tainted 6.1.0-rc2-00001-g328a1f96f7b9 #34
Hardware name: riscv-virtio,qemu (DT)
Call Trace:
[<ffffffff80006754>] dump_backtrace+0x30/0x38
[<ffffffff808de798>] show_stack+0x40/0x4c
[<ffffffff808ea2a8>] dump_stack_lvl+0x44/0x5c
[<ffffffff808ea2d8>] dump_stack+0x18/0x20
[<ffffffff808dec06>] panic+0x126/0x2fe
[<ffffffff800065ea>] walk_stackframe+0x0/0xf0
[<ffffffff0163a752>] recursive_loop+0x48/0xc6 [lkdtm]
SMP: stopping secondary CPUs
---[ end Kernel panic - not syncing: Kernel stack overflow ]---
Cc: Guo Ren <guoren@kernel.org>
Cc: Jisheng Zhang <jszhang@kernel.org>
Link: https://lore.kernel.org/linux-riscv/Y347B0x4VUNOd6V7@xhacker/T/#t
Link: https://lore.kernel.org/lkml/20221124094845.1907443-1-debug@rivosinc.com/
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Co-developed-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Acked-by: Guo Ren <guoren@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/r/20230927224757.1154247-9-samitolvanen@google.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/include/asm/asm-prototypes.h | 1 -
arch/riscv/include/asm/asm.h | 23 ++++++++
arch/riscv/include/asm/thread_info.h | 3 --
arch/riscv/kernel/asm-offsets.c | 1 +
arch/riscv/kernel/entry.S | 70 ++++---------------------
arch/riscv/kernel/traps.c | 30 +----------
6 files changed, 35 insertions(+), 93 deletions(-)
diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
index ef386fcf39394..4a06fa0f64932 100644
--- a/arch/riscv/include/asm/asm-prototypes.h
+++ b/arch/riscv/include/asm/asm-prototypes.h
@@ -25,7 +25,6 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_s);
DECLARE_DO_ERROR_INFO(do_trap_ecall_m);
DECLARE_DO_ERROR_INFO(do_trap_break);
-asmlinkage unsigned long get_overflow_stack(void);
asmlinkage void handle_bad_stack(struct pt_regs *regs);
#endif /* _ASM_RISCV_PROTOTYPES_H */
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 816e753de636d..9890a42c18103 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -69,6 +69,7 @@
#endif
#ifdef __ASSEMBLY__
+#include <asm/asm-offsets.h>
/* Common assembly source macros */
@@ -81,6 +82,28 @@
.endr
.endm
+#ifdef CONFIG_SMP
+#ifdef CONFIG_32BIT
+#define PER_CPU_OFFSET_SHIFT 2
+#else
+#define PER_CPU_OFFSET_SHIFT 3
+#endif
+
+.macro asm_per_cpu dst sym tmp
+ REG_L \tmp, TASK_TI_CPU_NUM(tp)
+ slli \tmp, \tmp, PER_CPU_OFFSET_SHIFT
+ la \dst, __per_cpu_offset
+ add \dst, \dst, \tmp
+ REG_L \tmp, 0(\dst)
+ la \dst, \sym
+ add \dst, \dst, \tmp
+.endm
+#else /* CONFIG_SMP */
+.macro asm_per_cpu dst sym tmp
+ la \dst, \sym
+.endm
+#endif /* CONFIG_SMP */
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_ASM_H */
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index f704c8dd57e04..78933ac04995b 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -42,9 +42,6 @@
#ifndef __ASSEMBLY__
-extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE / sizeof(long)];
-extern unsigned long spin_shadow_stack;
-
#include <asm/processor.h>
#include <asm/csr.h>
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 21f034b3fdbeb..9e6e35da69ce4 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -37,6 +37,7 @@ void asm_offsets(void)
OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp);
+ OFFSET(TASK_TI_CPU_NUM, task_struct, thread_info.cpu);
OFFSET(TASK_THREAD_F0, task_struct, thread.fstate.f[0]);
OFFSET(TASK_THREAD_F1, task_struct, thread.fstate.f[1]);
OFFSET(TASK_THREAD_F2, task_struct, thread.fstate.f[2]);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 99d38fdf8b18f..f6c3841df2f5a 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -10,9 +10,11 @@
#include <asm/asm.h>
#include <asm/csr.h>
#include <asm/unistd.h>
+#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/errata_list.h>
+#include <linux/sizes.h>
#if !IS_ENABLED(CONFIG_PREEMPTION)
.set resume_kernel, restore_all
@@ -397,67 +399,15 @@ handle_syscall_trace_exit:
#ifdef CONFIG_VMAP_STACK
handle_kernel_stack_overflow:
- /*
- * Takes the psuedo-spinlock for the shadow stack, in case multiple
- * harts are concurrently overflowing their kernel stacks. We could
- * store any value here, but since we're overflowing the kernel stack
- * already we only have SP to use as a scratch register. So we just
- * swap in the address of the spinlock, as that's definately non-zero.
- *
- * Pairs with a store_release in handle_bad_stack().
- */
-1: la sp, spin_shadow_stack
- REG_AMOSWAP_AQ sp, sp, (sp)
- bnez sp, 1b
-
- la sp, shadow_stack
- addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE
-
- //save caller register to shadow stack
- addi sp, sp, -(PT_SIZE_ON_STACK)
- REG_S x1, PT_RA(sp)
- REG_S x5, PT_T0(sp)
- REG_S x6, PT_T1(sp)
- REG_S x7, PT_T2(sp)
- REG_S x10, PT_A0(sp)
- REG_S x11, PT_A1(sp)
- REG_S x12, PT_A2(sp)
- REG_S x13, PT_A3(sp)
- REG_S x14, PT_A4(sp)
- REG_S x15, PT_A5(sp)
- REG_S x16, PT_A6(sp)
- REG_S x17, PT_A7(sp)
- REG_S x28, PT_T3(sp)
- REG_S x29, PT_T4(sp)
- REG_S x30, PT_T5(sp)
- REG_S x31, PT_T6(sp)
-
- la ra, restore_caller_reg
- tail get_overflow_stack
-
-restore_caller_reg:
- //save per-cpu overflow stack
- REG_S a0, -8(sp)
- //restore caller register from shadow_stack
- REG_L x1, PT_RA(sp)
- REG_L x5, PT_T0(sp)
- REG_L x6, PT_T1(sp)
- REG_L x7, PT_T2(sp)
- REG_L x10, PT_A0(sp)
- REG_L x11, PT_A1(sp)
- REG_L x12, PT_A2(sp)
- REG_L x13, PT_A3(sp)
- REG_L x14, PT_A4(sp)
- REG_L x15, PT_A5(sp)
- REG_L x16, PT_A6(sp)
- REG_L x17, PT_A7(sp)
- REG_L x28, PT_T3(sp)
- REG_L x29, PT_T4(sp)
- REG_L x30, PT_T5(sp)
- REG_L x31, PT_T6(sp)
+ /* we reach here from kernel context, sscratch must be 0 */
+ csrrw x31, CSR_SCRATCH, x31
+ asm_per_cpu sp, overflow_stack, x31
+ li x31, OVERFLOW_STACK_SIZE
+ add sp, sp, x31
+ /* zero out x31 again and restore x31 */
+ xor x31, x31, x31
+ csrrw x31, CSR_SCRATCH, x31
- //load per-cpu overflow stack
- REG_L sp, -8(sp)
addi sp, sp, -(PT_SIZE_ON_STACK)
//save context to overflow stack
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 7a6c02e17f4f0..ffa37f4f6a107 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -209,42 +209,14 @@ int is_valid_bugaddr(unsigned long pc)
#endif /* CONFIG_GENERIC_BUG */
#ifdef CONFIG_VMAP_STACK
-static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],
+DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],
overflow_stack)__aligned(16);
-/*
- * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used
- * to get per-cpu overflow stack(get_overflow_stack).
- */
-long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16);
-asmlinkage unsigned long get_overflow_stack(void)
-{
- return (unsigned long)this_cpu_ptr(overflow_stack) +
- OVERFLOW_STACK_SIZE;
-}
-
-/*
- * A pseudo spinlock to protect the shadow stack from being used by multiple
- * harts concurrently. This isn't a real spinlock because the lock side must
- * be taken without a valid stack and only a single register, it's only taken
- * while in the process of panicing anyway so the performance and error
- * checking a proper spinlock gives us doesn't matter.
- */
-unsigned long spin_shadow_stack;
asmlinkage void handle_bad_stack(struct pt_regs *regs)
{
unsigned long tsk_stk = (unsigned long)current->stack;
unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack);
- /*
- * We're done with the shadow stack by this point, as we're on the
- * overflow stack. Tell any other concurrent overflowing harts that
- * they can proceed with panicing by releasing the pseudo-spinlock.
- *
- * This pairs with an amoswap.aq in handle_kernel_stack_overflow.
- */
- smp_store_release(&spin_shadow_stack, 0);
-
console_verbose();
pr_emerg("Insufficient stack space to handle exception!\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0560/1887] f2fs: split initial and dynamic conditions for extent_cache
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (558 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0559/1887] riscv: VMAP_STACK overflow detection thread-safe Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0561/1887] cxl/port: Fix delete_endpoint() vs parent unregistration race Greg Kroah-Hartman
` (438 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jaegeuk Kim, Sasha Levin,
syzbot+d342e330a37b48c094b7
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <jaegeuk@kernel.org>
[ Upstream commit f803982190f0265fd36cf84670aa6daefc2b0768 ]
Let's allocate the extent_cache tree without dynamic conditions to avoid a
missing condition causing a panic as below.
# create a file w/ a compressed flag
# disable the compression
# panic while updating extent_cache
F2FS-fs (dm-64): Swapfile: last extent is not aligned to section
F2FS-fs (dm-64): Swapfile (3) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(2097152 * N)
Adding 124996k swap on ./swap-file. Priority:0 extents:2 across:17179494468k
==================================================================
BUG: KASAN: null-ptr-deref in instrument_atomic_read_write out/common/include/linux/instrumented.h:101 [inline]
BUG: KASAN: null-ptr-deref in atomic_try_cmpxchg_acquire out/common/include/asm-generic/atomic-instrumented.h:705 [inline]
BUG: KASAN: null-ptr-deref in queued_write_lock out/common/include/asm-generic/qrwlock.h:92 [inline]
BUG: KASAN: null-ptr-deref in __raw_write_lock out/common/include/linux/rwlock_api_smp.h:211 [inline]
BUG: KASAN: null-ptr-deref in _raw_write_lock+0x5a/0x110 out/common/kernel/locking/spinlock.c:295
Write of size 4 at addr 0000000000000030 by task syz-executor154/3327
CPU: 0 PID: 3327 Comm: syz-executor154 Tainted: G O 5.10.185 #1
Hardware name: emulation qemu-x86/qemu-x86, BIOS 2023.01-21885-gb3cc1cd24d 01/01/2023
Call Trace:
__dump_stack out/common/lib/dump_stack.c:77 [inline]
dump_stack_lvl+0x17e/0x1c4 out/common/lib/dump_stack.c:118
__kasan_report+0x16c/0x260 out/common/mm/kasan/report.c:415
kasan_report+0x51/0x70 out/common/mm/kasan/report.c:428
kasan_check_range+0x2f3/0x340 out/common/mm/kasan/generic.c:186
__kasan_check_write+0x14/0x20 out/common/mm/kasan/shadow.c:37
instrument_atomic_read_write out/common/include/linux/instrumented.h:101 [inline]
atomic_try_cmpxchg_acquire out/common/include/asm-generic/atomic-instrumented.h:705 [inline]
queued_write_lock out/common/include/asm-generic/qrwlock.h:92 [inline]
__raw_write_lock out/common/include/linux/rwlock_api_smp.h:211 [inline]
_raw_write_lock+0x5a/0x110 out/common/kernel/locking/spinlock.c:295
__drop_extent_tree+0xdf/0x2f0 out/common/fs/f2fs/extent_cache.c:1155
f2fs_drop_extent_tree+0x17/0x30 out/common/fs/f2fs/extent_cache.c:1172
f2fs_insert_range out/common/fs/f2fs/file.c:1600 [inline]
f2fs_fallocate+0x19fd/0x1f40 out/common/fs/f2fs/file.c:1764
vfs_fallocate+0x514/0x9b0 out/common/fs/open.c:310
ksys_fallocate out/common/fs/open.c:333 [inline]
__do_sys_fallocate out/common/fs/open.c:341 [inline]
__se_sys_fallocate out/common/fs/open.c:339 [inline]
__x64_sys_fallocate+0xb8/0x100 out/common/fs/open.c:339
do_syscall_64+0x35/0x50 out/common/arch/x86/entry/common.c:46
Cc: stable@vger.kernel.org
Fixes: 72840cccc0a1 ("f2fs: allocate the extent_cache by default")
Reported-and-tested-by: syzbot+d342e330a37b48c094b7@syzkaller.appspotmail.com
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/extent_cache.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index a5c63c7da2994..e66c5d0a04dff 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -58,24 +58,11 @@ static void __set_extent_info(struct extent_info *ei,
}
}
-static bool __may_read_extent_tree(struct inode *inode)
-{
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-
- if (!test_opt(sbi, READ_EXTENT_CACHE))
- return false;
- if (is_inode_flag_set(inode, FI_NO_EXTENT))
- return false;
- if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
- !f2fs_sb_has_readonly(sbi))
- return false;
- return S_ISREG(inode->i_mode);
-}
-
static bool __init_may_extent_tree(struct inode *inode, enum extent_type type)
{
if (type == EX_READ)
- return __may_read_extent_tree(inode);
+ return test_opt(F2FS_I_SB(inode), READ_EXTENT_CACHE) &&
+ S_ISREG(inode->i_mode);
return false;
}
@@ -88,7 +75,17 @@ static bool __may_extent_tree(struct inode *inode, enum extent_type type)
if (list_empty(&F2FS_I_SB(inode)->s_list))
return false;
- return __init_may_extent_tree(inode, type);
+ if (!__init_may_extent_tree(inode, type))
+ return false;
+
+ if (type == EX_READ) {
+ if (is_inode_flag_set(inode, FI_NO_EXTENT))
+ return false;
+ if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
+ !f2fs_sb_has_readonly(F2FS_I_SB(inode)))
+ return false;
+ }
+ return true;
}
static void __try_update_largest_extent(struct extent_tree *et,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0561/1887] cxl/port: Fix delete_endpoint() vs parent unregistration race
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (559 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0560/1887] f2fs: split initial and dynamic conditions for extent_cache Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0562/1887] media: mediatek: vcodec: Only free buffer VA that is not NULL Greg Kroah-Hartman
` (437 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Robert Richter, Dan Williams,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <dan.j.williams@intel.com>
[ Upstream commit 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 ]
The CXL subsystem, at cxl_mem ->probe() time, establishes a lineage of
ports (struct cxl_port objects) between an endpoint and the root of a
CXL topology. Each port including the endpoint port is attached to the
cxl_port driver.
Given that setup, it follows that when either any port in that lineage
goes through a cxl_port ->remove() event, or the memdev goes through a
cxl_mem ->remove() event. The hierarchy below the removed port, or the
entire hierarchy if the memdev is removed needs to come down.
The delete_endpoint() callback is careful to check whether it is being
called to tear down the hierarchy, or if it is only being called to
teardown the memdev because an ancestor port is going through
->remove().
That care needs to take the device_lock() of the endpoint's parent.
Which requires 2 bugs to be fixed:
1/ A reference on the parent is needed to prevent use-after-free
scenarios like this signature:
BUG: spinlock bad magic on CPU#0, kworker/u56:0/11
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20230524-3.fc38 05/24/2023
Workqueue: cxl_port detach_memdev [cxl_core]
RIP: 0010:spin_bug+0x65/0xa0
Call Trace:
do_raw_spin_lock+0x69/0xa0
__mutex_lock+0x695/0xb80
delete_endpoint+0xad/0x150 [cxl_core]
devres_release_all+0xb8/0x110
device_unbind_cleanup+0xe/0x70
device_release_driver_internal+0x1d2/0x210
detach_memdev+0x15/0x20 [cxl_core]
process_one_work+0x1e3/0x4c0
worker_thread+0x1dd/0x3d0
2/ In the case of RCH topologies, the parent device that needs to be
locked is not always @port->dev as returned by cxl_mem_find_port(), use
endpoint->dev.parent instead.
Fixes: 8dd2bc0f8e02 ("cxl/mem: Add the cxl_mem driver")
Cc: <stable@vger.kernel.org>
Reported-by: Robert Richter <rrichter@amd.com>
Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/port.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 20f052d3759e0..15b468b6aec38 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1094,29 +1094,24 @@ static void delete_endpoint(void *data)
{
struct cxl_memdev *cxlmd = data;
struct cxl_port *endpoint = dev_get_drvdata(&cxlmd->dev);
- struct cxl_port *parent_port;
- struct device *parent;
+ struct device *host = endpoint->dev.parent;
- parent_port = cxl_mem_find_port(cxlmd, NULL);
- if (!parent_port)
- goto out;
- parent = &parent_port->dev;
-
- device_lock(parent);
- if (parent->driver && !endpoint->dead) {
- devm_release_action(parent, cxl_unlink_uport, endpoint);
- devm_release_action(parent, unregister_port, endpoint);
+ device_lock(host);
+ if (host->driver && !endpoint->dead) {
+ devm_release_action(host, cxl_unlink_uport, endpoint);
+ devm_release_action(host, unregister_port, endpoint);
}
- device_unlock(parent);
- put_device(parent);
-out:
+ device_unlock(host);
put_device(&endpoint->dev);
+ put_device(host);
}
int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
{
+ struct device *host = endpoint->dev.parent;
struct device *dev = &cxlmd->dev;
+ get_device(host);
get_device(&endpoint->dev);
dev_set_drvdata(dev, endpoint);
return devm_add_action_or_reset(dev, delete_endpoint, cxlmd);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0562/1887] media: mediatek: vcodec: Only free buffer VA that is not NULL
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (560 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0561/1887] cxl/port: Fix delete_endpoint() vs parent unregistration race Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0563/1887] ext4: avoid deadlock in fs reclaim with page writeback Greg Kroah-Hartman
` (436 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fei Shao, AngeloGioacchino Del Regno,
Andrzej Pietrasiewicz, Sebastian Fricke, Mauro Carvalho Chehab,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fei Shao <fshao@chromium.org>
[ Upstream commit eb005c801ec70ff4307727bd3bd6e8280169ef32 ]
In the MediaTek vcodec driver, while mtk_vcodec_mem_free() is mostly
called only when the buffer to free exists, there are some instances
that didn't do the check and triggered warnings in practice.
We believe those checks were forgotten unintentionally. Add the checks
back to fix the warnings.
Signed-off-by: Fei Shao <fshao@chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
index dc35ec7f9c049..e070bd258ce6f 100644
--- a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
@@ -304,11 +304,12 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
* other buffers need to be freed by AP.
*/
for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
- if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
+ if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME && inst->work_bufs[i].va)
mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
}
- mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
+ if (inst->pps_buf.va)
+ mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
mtk_vcodec_debug_leave(inst);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0563/1887] ext4: avoid deadlock in fs reclaim with page writeback
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (561 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0562/1887] media: mediatek: vcodec: Only free buffer VA that is not NULL Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0564/1887] coresight: Fix memory leak in acpi_buffer->pointer Greg Kroah-Hartman
` (435 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6898da502aef574c5f8a,
Jan Kara, Theodore Tso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
[ Upstream commit 00d873c17e29cc32d90ca852b82685f1673acaa5 ]
Ext4 has a filesystem wide lock protecting ext4_writepages() calls to
avoid races with switching of journalled data flag or inode format. This
lock can however cause a deadlock like:
CPU0 CPU1
ext4_writepages()
percpu_down_read(sbi->s_writepages_rwsem);
ext4_change_inode_journal_flag()
percpu_down_write(sbi->s_writepages_rwsem);
- blocks, all readers block from now on
ext4_do_writepages()
ext4_init_io_end()
kmem_cache_zalloc(io_end_cachep, GFP_KERNEL)
fs_reclaim frees dentry...
dentry_unlink_inode()
iput() - last ref =>
iput_final() - inode dirty =>
write_inode_now()...
ext4_writepages() tries to acquire sbi->s_writepages_rwsem
and blocks forever
Make sure we cannot recurse into filesystem reclaim from writeback code
to avoid the deadlock.
Reported-by: syzbot+6898da502aef574c5f8a@syzkaller.appspotmail.com
Link: https://lore.kernel.org/all/0000000000004c66b405fa108e27@google.com
Fixes: c8585c6fcaf2 ("ext4: fix races between changing inode journal mode and ext4_writepages")
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230504124723.20205-1-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/ext4.h | 24 ++++++++++++++++++++++++
fs/ext4/inode.c | 18 ++++++++++--------
fs/ext4/migrate.c | 11 ++++++-----
3 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b1a4fcfdb5483..6d3f888f7e556 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1778,6 +1778,30 @@ static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
return container_of(inode, struct ext4_inode_info, vfs_inode);
}
+static inline int ext4_writepages_down_read(struct super_block *sb)
+{
+ percpu_down_read(&EXT4_SB(sb)->s_writepages_rwsem);
+ return memalloc_nofs_save();
+}
+
+static inline void ext4_writepages_up_read(struct super_block *sb, int ctx)
+{
+ memalloc_nofs_restore(ctx);
+ percpu_up_read(&EXT4_SB(sb)->s_writepages_rwsem);
+}
+
+static inline int ext4_writepages_down_write(struct super_block *sb)
+{
+ percpu_down_write(&EXT4_SB(sb)->s_writepages_rwsem);
+ return memalloc_nofs_save();
+}
+
+static inline void ext4_writepages_up_write(struct super_block *sb, int ctx)
+{
+ memalloc_nofs_restore(ctx);
+ percpu_up_write(&EXT4_SB(sb)->s_writepages_rwsem);
+}
+
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
{
return ino == EXT4_ROOT_INO ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ef801e13ca460..f9e9264a825a3 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2710,11 +2710,12 @@ static int ext4_writepages(struct address_space *mapping,
struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
struct blk_plug plug;
bool give_up_on_write = false;
+ int alloc_ctx;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
- percpu_down_read(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_read(inode->i_sb);
trace_ext4_writepages(inode, wbc);
/*
@@ -2924,7 +2925,7 @@ static int ext4_writepages(struct address_space *mapping,
out_writepages:
trace_ext4_writepages_result(inode, wbc, ret,
nr_to_write - wbc->nr_to_write);
- percpu_up_read(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_read(inode->i_sb, alloc_ctx);
return ret;
}
@@ -2935,17 +2936,18 @@ static int ext4_dax_writepages(struct address_space *mapping,
long nr_to_write = wbc->nr_to_write;
struct inode *inode = mapping->host;
struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
+ int alloc_ctx;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
- percpu_down_read(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_read(inode->i_sb);
trace_ext4_writepages(inode, wbc);
ret = dax_writeback_mapping_range(mapping, sbi->s_daxdev, wbc);
trace_ext4_writepages_result(inode, wbc, ret,
nr_to_write - wbc->nr_to_write);
- percpu_up_read(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_read(inode->i_sb, alloc_ctx);
return ret;
}
@@ -6172,7 +6174,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
journal_t *journal;
handle_t *handle;
int err;
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ int alloc_ctx;
/*
* We have to be very careful here: changing a data block's
@@ -6210,7 +6212,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
}
}
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
jbd2_journal_lock_updates(journal);
/*
@@ -6227,7 +6229,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
err = jbd2_journal_flush(journal, 0);
if (err < 0) {
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return err;
}
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
@@ -6235,7 +6237,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
ext4_set_aops(inode);
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
if (val)
filemap_invalidate_unlock(inode->i_mapping);
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 0be0467ae6dd2..a5e1492bbaaa5 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -408,7 +408,6 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
int ext4_ext_migrate(struct inode *inode)
{
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
handle_t *handle;
int retval = 0, i;
__le32 *i_data;
@@ -418,6 +417,7 @@ int ext4_ext_migrate(struct inode *inode)
unsigned long max_entries;
__u32 goal, tmp_csum_seed;
uid_t owner[2];
+ int alloc_ctx;
/*
* If the filesystem does not support extents, or the inode
@@ -434,7 +434,7 @@ int ext4_ext_migrate(struct inode *inode)
*/
return retval;
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
/*
* Worst case we can touch the allocation bitmaps and a block
@@ -586,7 +586,7 @@ int ext4_ext_migrate(struct inode *inode)
unlock_new_inode(tmp_inode);
iput(tmp_inode);
out_unlock:
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return retval;
}
@@ -605,6 +605,7 @@ int ext4_ind_migrate(struct inode *inode)
ext4_fsblk_t blk;
handle_t *handle;
int ret, ret2 = 0;
+ int alloc_ctx;
if (!ext4_has_feature_extents(inode->i_sb) ||
(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
@@ -621,7 +622,7 @@ int ext4_ind_migrate(struct inode *inode)
if (test_opt(inode->i_sb, DELALLOC))
ext4_alloc_da_blocks(inode);
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
if (IS_ERR(handle)) {
@@ -665,6 +666,6 @@ int ext4_ind_migrate(struct inode *inode)
up_write(&EXT4_I(inode)->i_data_sem);
ext4_journal_stop(handle);
out_unlock:
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0564/1887] coresight: Fix memory leak in acpi_buffer->pointer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (562 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0563/1887] ext4: avoid deadlock in fs reclaim with page writeback Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0565/1887] net/mlx5e: xsk: Fix crash on regular rq reactivation Greg Kroah-Hartman
` (434 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junhao He, James Clark,
Suzuki K Poulose, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junhao He <hejunhao3@huawei.com>
[ Upstream commit 1a9e02673e2550f5612099e64e8761f0c8fc0f50 ]
There are memory leaks reported by kmemleak:
...
unreferenced object 0xffff00213c141000 (size 1024):
comm "systemd-udevd", pid 2123, jiffies 4294909467 (age 6062.160s)
hex dump (first 32 bytes):
04 00 00 00 02 00 00 00 18 10 14 3c 21 00 ff ff ...........<!...
00 00 00 00 00 00 00 00 03 00 00 00 10 00 00 00 ................
backtrace:
[<000000004b7c9001>] __kmem_cache_alloc_node+0x2f8/0x348
[<00000000b0fc7ceb>] __kmalloc+0x58/0x108
[<0000000064ff4695>] acpi_os_allocate+0x2c/0x68
[<000000007d57d116>] acpi_ut_initialize_buffer+0x54/0xe0
[<0000000024583908>] acpi_evaluate_object+0x388/0x438
[<0000000017b2e72b>] acpi_evaluate_object_typed+0xe8/0x240
[<000000005df0eac2>] coresight_get_platform_data+0x1b4/0x988 [coresight]
...
The ACPI buffer memory (buf.pointer) should be freed. But the buffer
is also used after returning from acpi_get_dsd_graph().
Move the temporary variables buf to acpi_coresight_parse_graph(),
and free it before the function return to prevent memory leak.
Fixes: 76ffa5ab5b79 ("coresight: Support for ACPI bindings")
Signed-off-by: Junhao He <hejunhao3@huawei.com>
Reviewed-by: James Clark <james.clark@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20230817085937.55590-2-hejunhao3@huawei.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../hwtracing/coresight/coresight-platform.c | 48 ++++++++++++-------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 3f82ae07a18e5..f19e6758ce599 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -520,19 +520,18 @@ static inline bool acpi_validate_dsd_graph(const union acpi_object *graph)
/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */
static const union acpi_object *
-acpi_get_dsd_graph(struct acpi_device *adev)
+acpi_get_dsd_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
int i;
- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
acpi_status status;
const union acpi_object *dsd;
status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
- &buf, ACPI_TYPE_PACKAGE);
+ buf, ACPI_TYPE_PACKAGE);
if (ACPI_FAILURE(status))
return NULL;
- dsd = buf.pointer;
+ dsd = buf->pointer;
/*
* _DSD property consists tuples { Prop_UUID, Package() }
@@ -583,12 +582,12 @@ acpi_validate_coresight_graph(const union acpi_object *cs_graph)
* returns NULL.
*/
static const union acpi_object *
-acpi_get_coresight_graph(struct acpi_device *adev)
+acpi_get_coresight_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
const union acpi_object *graph_list, *graph;
int i, nr_graphs;
- graph_list = acpi_get_dsd_graph(adev);
+ graph_list = acpi_get_dsd_graph(adev, buf);
if (!graph_list)
return graph_list;
@@ -688,18 +687,22 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
static int acpi_coresight_parse_graph(struct acpi_device *adev,
struct coresight_platform_data *pdata)
{
- int rc, i, nlinks;
+ int rc = 0;
+ int i, nlinks;
const union acpi_object *graph;
struct coresight_connection *conns, *ptr;
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
pdata->nr_inport = pdata->nr_outport = 0;
- graph = acpi_get_coresight_graph(adev);
- if (!graph)
- return -ENOENT;
+ graph = acpi_get_coresight_graph(adev, &buf);
+ if (!graph) {
+ rc = -ENOENT;
+ goto free;
+ }
nlinks = graph->package.elements[2].integer.value;
if (!nlinks)
- return 0;
+ goto free;
/*
* To avoid scanning the table twice (once for finding the number of
@@ -708,16 +711,20 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
* it to the pdata.
*/
conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL);
- if (!conns)
- return -ENOMEM;
+ if (!conns) {
+ rc = -ENOMEM;
+ goto free;
+ }
ptr = conns;
for (i = 0; i < nlinks; i++) {
const union acpi_object *link = &graph->package.elements[3 + i];
int dir;
dir = acpi_coresight_parse_link(adev, link, ptr);
- if (dir < 0)
- return dir;
+ if (dir < 0) {
+ rc = dir;
+ goto free;
+ }
if (dir == ACPI_CORESIGHT_LINK_MASTER) {
if (ptr->outport >= pdata->nr_outport)
@@ -739,7 +746,7 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
rc = coresight_alloc_conns(&adev->dev, pdata);
if (rc)
- return rc;
+ goto free;
/* Copy the connection information to the final location */
for (i = 0; conns + i < ptr; i++) {
@@ -751,7 +758,14 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
}
devm_kfree(&adev->dev, conns);
- return 0;
+free:
+ /*
+ * When ACPI fails to alloc a buffer, it will free the buffer
+ * created via ACPI_ALLOCATE_BUFFER and set to NULL.
+ * ACPI_FREE can handle NULL pointers, so free it directly.
+ */
+ ACPI_FREE(buf.pointer);
+ return rc;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0565/1887] net/mlx5e: xsk: Fix crash on regular rq reactivation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (563 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0564/1887] coresight: Fix memory leak in acpi_buffer->pointer Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0566/1887] f2fs: fix to set flush_merge opt and show noflush_merge Greg Kroah-Hartman
` (433 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kal Cutter Conley, Dragos Tatulea,
Tariq Toukan, Saeed Mahameed, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <dtatulea@nvidia.com>
[ Upstream commit 39646d9bcd1a65d2396328026626859a1dab59d7 ]
When the regular rq is reactivated after the XSK socket is closed
it could be reading stale cqes which eventually corrupts the rq.
This leads to no more traffic being received on the regular rq and a
crash on the next close or deactivation of the rq.
Kal Cuttler Conely reported this issue as a crash on the release
path when the xdpsock sample program is stopped (killed) and restarted
in sequence while traffic is running.
This patch flushes all cqes when during the rq flush. The cqe flushing
is done in the reset state of the rq. mlx5e_rq_to_ready code is moved
into the flush function to allow for this.
Fixes: 082a9edf12fe ("net/mlx5e: xsk: Flush RQ on XSK activation to save memory")
Reported-by: Kal Cutter Conley <kal.conley@dectris.com>
Closes: https://lore.kernel.org/xdp-newbies/CAHApi-nUAs4TeFWUDV915CZJo07XVg2Vp63-no7UDfj6wur9nQ@mail.gmail.com
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index d26c36479ee91..f05fe8074b755 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -989,9 +989,11 @@ static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_s
return err;
}
-static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
+int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state)
{
+ struct mlx5_cqwq *cqwq = &rq->cq.wq;
struct net_device *dev = rq->netdev;
+ struct mlx5_cqe64 *cqe;
int err;
err = mlx5e_modify_rq_state(rq, curr_state, MLX5_RQC_STATE_RST);
@@ -999,6 +1001,14 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
netdev_err(dev, "Failed to move rq 0x%x to reset\n", rq->rqn);
return err;
}
+
+ mlx5e_free_rx_descs(rq);
+
+ while ((cqe = mlx5_cqwq_get_cqe(cqwq)))
+ mlx5_cqwq_pop(cqwq);
+
+ mlx5_cqwq_update_db_record(cqwq);
+
err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
if (err) {
netdev_err(dev, "Failed to move rq 0x%x to ready\n", rq->rqn);
@@ -1008,13 +1018,6 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
return 0;
}
-int mlx5e_flush_rq(struct mlx5e_rq *rq, int curr_state)
-{
- mlx5e_free_rx_descs(rq);
-
- return mlx5e_rq_to_ready(rq, curr_state);
-}
-
static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd)
{
struct mlx5_core_dev *mdev = rq->mdev;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0566/1887] f2fs: fix to set flush_merge opt and show noflush_merge
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (564 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0565/1887] net/mlx5e: xsk: Fix crash on regular rq reactivation Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0567/1887] f2fs: dont reset unchangable mount option in f2fs_remount() Greg Kroah-Hartman
` (432 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chao Yu, Yangtao Li, Jaegeuk Kim,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yangtao Li <frank.li@vivo.com>
[ Upstream commit 967eaad1fed5f6335ea97a47d45214744dc57925 ]
Some minor modifications to flush_merge and related parameters:
1.The FLUSH_MERGE opt is set by default only in non-ro mode.
2.When ro and merge are set at the same time, an error is reported.
3.Display noflush_merge mount opt.
Suggested-by: Chao Yu <chao@kernel.org>
Signed-off-by: Yangtao Li <frank.li@vivo.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: 458c15dfbce6 ("f2fs: don't reset unchangable mount option in f2fs_remount()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/super.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index dc06771fb1e9e..83b376afcd420 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1400,6 +1400,12 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
return -EINVAL;
}
+ if ((f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb)) &&
+ test_opt(sbi, FLUSH_MERGE)) {
+ f2fs_err(sbi, "FLUSH_MERGE not compatible with readonly mode");
+ return -EINVAL;
+ }
+
if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) {
f2fs_err(sbi, "Allow to mount readonly mode only");
return -EROFS;
@@ -1997,8 +2003,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
seq_puts(seq, ",inline_dentry");
else
seq_puts(seq, ",noinline_dentry");
- if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE))
+ if (test_opt(sbi, FLUSH_MERGE))
seq_puts(seq, ",flush_merge");
+ else
+ seq_puts(seq, ",noflush_merge");
if (test_opt(sbi, NOBARRIER))
seq_puts(seq, ",nobarrier");
if (test_opt(sbi, FASTBOOT))
@@ -2125,7 +2133,8 @@ static void default_options(struct f2fs_sb_info *sbi)
set_opt(sbi, MERGE_CHECKPOINT);
F2FS_OPTION(sbi).unusable_cap = 0;
sbi->sb->s_flags |= SB_LAZYTIME;
- set_opt(sbi, FLUSH_MERGE);
+ if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb))
+ set_opt(sbi, FLUSH_MERGE);
if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
set_opt(sbi, DISCARD);
if (f2fs_sb_has_blkzoned(sbi)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0567/1887] f2fs: dont reset unchangable mount option in f2fs_remount()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (565 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0566/1887] f2fs: fix to set flush_merge opt and show noflush_merge Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0568/1887] can: gs_usb: fix time stamp counter initialization Greg Kroah-Hartman
` (431 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d015b6c2fbb5c383bf08, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 458c15dfbce62c35fefd9ca637b20a051309c9f1 ]
syzbot reports a bug as below:
general protection fault, probably for non-canonical address 0xdffffc0000000009: 0000 [#1] PREEMPT SMP KASAN
RIP: 0010:__lock_acquire+0x69/0x2000 kernel/locking/lockdep.c:4942
Call Trace:
lock_acquire+0x1e3/0x520 kernel/locking/lockdep.c:5691
__raw_write_lock include/linux/rwlock_api_smp.h:209 [inline]
_raw_write_lock+0x2e/0x40 kernel/locking/spinlock.c:300
__drop_extent_tree+0x3ac/0x660 fs/f2fs/extent_cache.c:1100
f2fs_drop_extent_tree+0x17/0x30 fs/f2fs/extent_cache.c:1116
f2fs_insert_range+0x2d5/0x3c0 fs/f2fs/file.c:1664
f2fs_fallocate+0x4e4/0x6d0 fs/f2fs/file.c:1838
vfs_fallocate+0x54b/0x6b0 fs/open.c:324
ksys_fallocate fs/open.c:347 [inline]
__do_sys_fallocate fs/open.c:355 [inline]
__se_sys_fallocate fs/open.c:353 [inline]
__x64_sys_fallocate+0xbd/0x100 fs/open.c:353
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
The root cause is race condition as below:
- since it tries to remount rw filesystem, so that do_remount won't
call sb_prepare_remount_readonly to block fallocate, there may be race
condition in between remount and fallocate.
- in f2fs_remount(), default_options() will reset mount option to default
one, and then update it based on result of parse_options(), so there is
a hole which race condition can happen.
Thread A Thread B
- f2fs_fill_super
- parse_options
- clear_opt(READ_EXTENT_CACHE)
- f2fs_remount
- default_options
- set_opt(READ_EXTENT_CACHE)
- f2fs_fallocate
- f2fs_insert_range
- f2fs_drop_extent_tree
- __drop_extent_tree
- __may_extent_tree
- test_opt(READ_EXTENT_CACHE) return true
- write_lock(&et->lock) access NULL pointer
- parse_options
- clear_opt(READ_EXTENT_CACHE)
Cc: <stable@vger.kernel.org>
Reported-by: syzbot+d015b6c2fbb5c383bf08@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/20230522124203.3838360-1-chao@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/super.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 83b376afcd420..a86200f7d9101 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2104,9 +2104,22 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
return 0;
}
-static void default_options(struct f2fs_sb_info *sbi)
+static void default_options(struct f2fs_sb_info *sbi, bool remount)
{
/* init some FS parameters */
+ if (!remount) {
+ set_opt(sbi, READ_EXTENT_CACHE);
+ clear_opt(sbi, DISABLE_CHECKPOINT);
+
+ if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
+ set_opt(sbi, DISCARD);
+
+ if (f2fs_sb_has_blkzoned(sbi))
+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION;
+ else
+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK;
+ }
+
if (f2fs_sb_has_readonly(sbi))
F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE;
else
@@ -2127,23 +2140,16 @@ static void default_options(struct f2fs_sb_info *sbi)
set_opt(sbi, INLINE_XATTR);
set_opt(sbi, INLINE_DATA);
set_opt(sbi, INLINE_DENTRY);
- set_opt(sbi, READ_EXTENT_CACHE);
set_opt(sbi, NOHEAP);
- clear_opt(sbi, DISABLE_CHECKPOINT);
set_opt(sbi, MERGE_CHECKPOINT);
F2FS_OPTION(sbi).unusable_cap = 0;
sbi->sb->s_flags |= SB_LAZYTIME;
if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb))
set_opt(sbi, FLUSH_MERGE);
- if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
- set_opt(sbi, DISCARD);
- if (f2fs_sb_has_blkzoned(sbi)) {
+ if (f2fs_sb_has_blkzoned(sbi))
F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;
- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION;
- } else {
+ else
F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE;
- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK;
- }
#ifdef CONFIG_F2FS_FS_XATTR
set_opt(sbi, XATTR_USER);
@@ -2320,7 +2326,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
clear_sbi_flag(sbi, SBI_NEED_SB_WRITE);
}
- default_options(sbi);
+ default_options(sbi, true);
/* parse mount options */
err = parse_options(sb, data, true);
@@ -4252,7 +4258,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
sizeof(raw_super->uuid));
- default_options(sbi);
+ default_options(sbi, false);
/* parse mount options */
options = kstrdup((const char *)data, GFP_KERNEL);
if (data && !options) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0568/1887] can: gs_usb: fix time stamp counter initialization
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (566 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0567/1887] f2fs: dont reset unchangable mount option in f2fs_remount() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0569/1887] smc: Fix use-after-free in tcp_write_timer_handler() Greg Kroah-Hartman
` (430 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Whittington, Marc Kleine-Budde,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <mkl@pengutronix.de>
[ Upstream commit 5886e4d5ecec3e22844efed90b2dd383ef804b3a ]
If the gs_usb device driver is unloaded (or unbound) before the
interface is shut down, the USB stack first calls the struct
usb_driver::disconnect and then the struct net_device_ops::ndo_stop
callback.
In gs_usb_disconnect() all pending bulk URBs are killed, i.e. no more
RX'ed CAN frames are send from the USB device to the host. Later in
gs_can_close() a reset control message is send to each CAN channel to
remove the controller from the CAN bus. In this race window the USB
device can still receive CAN frames from the bus and internally queue
them to be send to the host.
At least in the current version of the candlelight firmware, the queue
of received CAN frames is not emptied during the reset command. After
loading (or binding) the gs_usb driver, new URBs are submitted during
the struct net_device_ops::ndo_open callback and the candlelight
firmware starts sending its already queued CAN frames to the host.
However, this scenario was not considered when implementing the
hardware timestamp function. The cycle counter/time counter
infrastructure is set up (gs_usb_timestamp_init()) after the USBs are
submitted, resulting in a NULL pointer dereference if
timecounter_cyc2time() (via the call chain:
gs_usb_receive_bulk_callback() -> gs_usb_set_timestamp() ->
gs_usb_skb_set_timestamp()) is called too early.
Move the gs_usb_timestamp_init() function before the URBs are
submitted to fix this problem.
For a comprehensive solution, we need to consider gs_usb devices with
more than 1 channel. The cycle counter/time counter infrastructure is
setup per channel, but the RX URBs are per device. Once gs_can_open()
of _a_ channel has been called, and URBs have been submitted, the
gs_usb_receive_bulk_callback() can be called for _all_ available
channels, even for channels that are not running, yet. As cycle
counter/time counter has not set up, this will again lead to a NULL
pointer dereference.
Convert the cycle counter/time counter from a "per channel" to a "per
device" functionality. Also set it up, before submitting any URBs to
the device.
Further in gs_usb_receive_bulk_callback(), don't process any URBs for
not started CAN channels, only resubmit the URB.
Fixes: 45dfa45f52e6 ("can: gs_usb: add RX and TX hardware timestamp support")
Closes: https://github.com/candle-usb/candleLight_fw/issues/137#issuecomment-1623532076
Cc: stable@vger.kernel.org
Cc: John Whittington <git@jbrengineering.co.uk>
Link: https://lore.kernel.org/all/20230716-gs_usb-fix-time-stamp-counter-v1-2-9017cefcd9d5@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/usb/gs_usb.c | 100 ++++++++++++++++++-----------------
1 file changed, 52 insertions(+), 48 deletions(-)
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index 3ce8cf4ecb2e5..d0fe0e5e9021f 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -297,12 +297,6 @@ struct gs_can {
struct can_bittiming_const bt_const, data_bt_const;
unsigned int channel; /* channel number */
- /* time counter for hardware timestamps */
- struct cyclecounter cc;
- struct timecounter tc;
- spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */
- struct delayed_work timestamp;
-
u32 feature;
unsigned int hf_size_tx;
@@ -318,6 +312,13 @@ struct gs_can {
struct gs_usb {
struct usb_anchor rx_submitted;
struct usb_device *udev;
+
+ /* time counter for hardware timestamps */
+ struct cyclecounter cc;
+ struct timecounter tc;
+ spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */
+ struct delayed_work timestamp;
+
unsigned int hf_size_rx;
u8 active_channels;
u8 channel_cnt;
@@ -387,16 +388,15 @@ static int gs_cmd_reset(struct gs_can *dev)
GFP_KERNEL);
}
-static inline int gs_usb_get_timestamp(const struct gs_can *dev,
+static inline int gs_usb_get_timestamp(const struct gs_usb *parent,
u32 *timestamp_p)
{
__le32 timestamp;
int rc;
- rc = usb_control_msg_recv(interface_to_usbdev(dev->iface), 0,
- GS_USB_BREQ_TIMESTAMP,
+ rc = usb_control_msg_recv(parent->udev, 0, GS_USB_BREQ_TIMESTAMP,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- dev->channel, 0,
+ 0, 0,
×tamp, sizeof(timestamp),
USB_CTRL_GET_TIMEOUT,
GFP_KERNEL);
@@ -410,20 +410,20 @@ static inline int gs_usb_get_timestamp(const struct gs_can *dev,
static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev->tc_lock)
{
- struct gs_can *dev = container_of(cc, struct gs_can, cc);
+ struct gs_usb *parent = container_of(cc, struct gs_usb, cc);
u32 timestamp = 0;
int err;
- lockdep_assert_held(&dev->tc_lock);
+ lockdep_assert_held(&parent->tc_lock);
/* drop lock for synchronous USB transfer */
- spin_unlock_bh(&dev->tc_lock);
- err = gs_usb_get_timestamp(dev, ×tamp);
- spin_lock_bh(&dev->tc_lock);
+ spin_unlock_bh(&parent->tc_lock);
+ err = gs_usb_get_timestamp(parent, ×tamp);
+ spin_lock_bh(&parent->tc_lock);
if (err)
- netdev_err(dev->netdev,
- "Error %d while reading timestamp. HW timestamps may be inaccurate.",
- err);
+ dev_err(&parent->udev->dev,
+ "Error %d while reading timestamp. HW timestamps may be inaccurate.",
+ err);
return timestamp;
}
@@ -431,14 +431,14 @@ static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev
static void gs_usb_timestamp_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
- struct gs_can *dev;
+ struct gs_usb *parent;
- dev = container_of(delayed_work, struct gs_can, timestamp);
- spin_lock_bh(&dev->tc_lock);
- timecounter_read(&dev->tc);
- spin_unlock_bh(&dev->tc_lock);
+ parent = container_of(delayed_work, struct gs_usb, timestamp);
+ spin_lock_bh(&parent->tc_lock);
+ timecounter_read(&parent->tc);
+ spin_unlock_bh(&parent->tc_lock);
- schedule_delayed_work(&dev->timestamp,
+ schedule_delayed_work(&parent->timestamp,
GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ);
}
@@ -446,37 +446,38 @@ static void gs_usb_skb_set_timestamp(struct gs_can *dev,
struct sk_buff *skb, u32 timestamp)
{
struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
+ struct gs_usb *parent = dev->parent;
u64 ns;
- spin_lock_bh(&dev->tc_lock);
- ns = timecounter_cyc2time(&dev->tc, timestamp);
- spin_unlock_bh(&dev->tc_lock);
+ spin_lock_bh(&parent->tc_lock);
+ ns = timecounter_cyc2time(&parent->tc, timestamp);
+ spin_unlock_bh(&parent->tc_lock);
hwtstamps->hwtstamp = ns_to_ktime(ns);
}
-static void gs_usb_timestamp_init(struct gs_can *dev)
+static void gs_usb_timestamp_init(struct gs_usb *parent)
{
- struct cyclecounter *cc = &dev->cc;
+ struct cyclecounter *cc = &parent->cc;
cc->read = gs_usb_timestamp_read;
cc->mask = CYCLECOUNTER_MASK(32);
cc->shift = 32 - bits_per(NSEC_PER_SEC / GS_USB_TIMESTAMP_TIMER_HZ);
cc->mult = clocksource_hz2mult(GS_USB_TIMESTAMP_TIMER_HZ, cc->shift);
- spin_lock_init(&dev->tc_lock);
- spin_lock_bh(&dev->tc_lock);
- timecounter_init(&dev->tc, &dev->cc, ktime_get_real_ns());
- spin_unlock_bh(&dev->tc_lock);
+ spin_lock_init(&parent->tc_lock);
+ spin_lock_bh(&parent->tc_lock);
+ timecounter_init(&parent->tc, &parent->cc, ktime_get_real_ns());
+ spin_unlock_bh(&parent->tc_lock);
- INIT_DELAYED_WORK(&dev->timestamp, gs_usb_timestamp_work);
- schedule_delayed_work(&dev->timestamp,
+ INIT_DELAYED_WORK(&parent->timestamp, gs_usb_timestamp_work);
+ schedule_delayed_work(&parent->timestamp,
GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ);
}
-static void gs_usb_timestamp_stop(struct gs_can *dev)
+static void gs_usb_timestamp_stop(struct gs_usb *parent)
{
- cancel_delayed_work_sync(&dev->timestamp);
+ cancel_delayed_work_sync(&parent->timestamp);
}
static void gs_update_state(struct gs_can *dev, struct can_frame *cf)
@@ -570,6 +571,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
if (!netif_device_present(netdev))
return;
+ if (!netif_running(netdev))
+ goto resubmit_urb;
+
if (hf->echo_id == -1) { /* normal rx */
if (hf->flags & GS_CAN_FLAG_FD) {
skb = alloc_canfd_skb(dev->netdev, &cfd);
@@ -891,6 +895,9 @@ static int gs_can_open(struct net_device *netdev)
}
if (!parent->active_channels) {
+ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+ gs_usb_timestamp_init(parent);
+
for (i = 0; i < GS_MAX_RX_URBS; i++) {
u8 *buf;
@@ -973,10 +980,6 @@ static int gs_can_open(struct net_device *netdev)
}
}
- /* start polling timestamp */
- if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
- gs_usb_timestamp_init(dev);
-
/* finally start device */
dev->can.state = CAN_STATE_ERROR_ACTIVE;
dm.flags = cpu_to_le32(flags);
@@ -987,8 +990,6 @@ static int gs_can_open(struct net_device *netdev)
GFP_KERNEL);
if (rc) {
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
- if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
- gs_usb_timestamp_stop(dev);
dev->can.state = CAN_STATE_STOPPED;
goto out_usb_kill_anchored_urbs;
@@ -1005,9 +1006,13 @@ static int gs_can_open(struct net_device *netdev)
out_usb_free_urb:
usb_free_urb(urb);
out_usb_kill_anchored_urbs:
- if (!parent->active_channels)
+ if (!parent->active_channels) {
usb_kill_anchored_urbs(&parent->rx_submitted);
+ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+ gs_usb_timestamp_stop(parent);
+ }
+
close_candev(netdev);
return rc;
@@ -1021,14 +1026,13 @@ static int gs_can_close(struct net_device *netdev)
netif_stop_queue(netdev);
- /* stop polling timestamp */
- if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
- gs_usb_timestamp_stop(dev);
-
/* Stop polling */
parent->active_channels--;
if (!parent->active_channels) {
usb_kill_anchored_urbs(&parent->rx_submitted);
+
+ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+ gs_usb_timestamp_stop(parent);
}
/* Stop sending URBs */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0569/1887] smc: Fix use-after-free in tcp_write_timer_handler().
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (567 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0568/1887] can: gs_usb: fix time stamp counter initialization Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0570/1887] block/rq_qos: protect rq_qos apis with a new lock Greg Kroah-Hartman
` (429 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+7e1e1bdb852961150198,
Kuniyuki Iwashima, Tony Lu, David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@amazon.com>
[ Upstream commit 9744d2bf19762703704ecba885b7ac282c02eacf ]
With Eric's ref tracker, syzbot finally found a repro for
use-after-free in tcp_write_timer_handler() by kernel TCP
sockets. [0]
If SMC creates a kernel socket in __smc_create(), the kernel
socket is supposed to be freed in smc_clcsock_release() by
calling sock_release() when we close() the parent SMC socket.
However, at the end of smc_clcsock_release(), the kernel
socket's sk_state might not be TCP_CLOSE. This means that
we have not called inet_csk_destroy_sock() in __tcp_close()
and have not stopped the TCP timers.
The kernel socket's TCP timers can be fired later, so we
need to hold a refcnt for net as we do for MPTCP subflows
in mptcp_subflow_create_socket().
[0]:
leaked reference.
sk_alloc (./include/net/net_namespace.h:335 net/core/sock.c:2108)
inet_create (net/ipv4/af_inet.c:319 net/ipv4/af_inet.c:244)
__sock_create (net/socket.c:1546)
smc_create (net/smc/af_smc.c:3269 net/smc/af_smc.c:3284)
__sock_create (net/socket.c:1546)
__sys_socket (net/socket.c:1634 net/socket.c:1618 net/socket.c:1661)
__x64_sys_socket (net/socket.c:1672)
do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
==================================================================
BUG: KASAN: slab-use-after-free in tcp_write_timer_handler (net/ipv4/tcp_timer.c:378 net/ipv4/tcp_timer.c:624 net/ipv4/tcp_timer.c:594)
Read of size 1 at addr ffff888052b65e0d by task syzrepro/18091
CPU: 0 PID: 18091 Comm: syzrepro Tainted: G W 6.3.0-rc4-01174-gb5d54eb5899a #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-1.amzn2022.0.1 04/01/2014
Call Trace:
<IRQ>
dump_stack_lvl (lib/dump_stack.c:107)
print_report (mm/kasan/report.c:320 mm/kasan/report.c:430)
kasan_report (mm/kasan/report.c:538)
tcp_write_timer_handler (net/ipv4/tcp_timer.c:378 net/ipv4/tcp_timer.c:624 net/ipv4/tcp_timer.c:594)
tcp_write_timer (./include/linux/spinlock.h:390 net/ipv4/tcp_timer.c:643)
call_timer_fn (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./include/trace/events/timer.h:127 kernel/time/timer.c:1701)
__run_timers.part.0 (kernel/time/timer.c:1752 kernel/time/timer.c:2022)
run_timer_softirq (kernel/time/timer.c:2037)
__do_softirq (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./include/trace/events/irq.h:142 kernel/softirq.c:572)
__irq_exit_rcu (kernel/softirq.c:445 kernel/softirq.c:650)
irq_exit_rcu (kernel/softirq.c:664)
sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1107 (discriminator 14))
</IRQ>
Fixes: ac7138746e14 ("smc: establish new socket family")
Reported-by: syzbot+7e1e1bdb852961150198@syzkaller.appspotmail.com
Link: https://lore.kernel.org/netdev/000000000000a3f51805f8bcc43a@google.com/
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/af_smc.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 9e142f49a8102..35cf30486916e 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -3315,6 +3315,16 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,
sk_common_release(sk);
goto out;
}
+
+ /* smc_clcsock_release() does not wait smc->clcsock->sk's
+ * destruction; its sk_state might not be TCP_CLOSE after
+ * smc->sk is close()d, and TCP timers can be fired later,
+ * which need net ref.
+ */
+ sk = smc->clcsock->sk;
+ sk->sk_net_refcnt = 1;
+ get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+ sock_inuse_add(net, 1);
} else {
smc->clcsock = clcsock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0570/1887] block/rq_qos: protect rq_qos apis with a new lock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (568 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0569/1887] smc: Fix use-after-free in tcp_write_timer_handler() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0571/1887] f2fs: fix to do sanity check on direct node in truncate_dnode() Greg Kroah-Hartman
` (428 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Kuai, Tejun Heo, Jens Axboe,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <yukuai3@huawei.com>
[ Upstream commit a13bd91be22318768d55470cbc0b0f4488ef9edf ]
commit 50e34d78815e ("block: disable the elevator int del_gendisk")
move rq_qos_exit() from disk_release() to del_gendisk(), this will
introduce some problems:
1) If rq_qos_add() is triggered by enabling iocost/iolatency through
cgroupfs, then it can concurrent with del_gendisk(), it's not safe to
write 'q->rq_qos' concurrently.
2) Activate cgroup policy that is relied on rq_qos will call
rq_qos_add() and blkcg_activate_policy(), and if rq_qos_exit() is
called in the middle, null-ptr-dereference will be triggered in
blkcg_activate_policy().
3) blkg_conf_open_bdev() can call blkdev_get_no_open() first to find the
disk, then if rq_qos_exit() from del_gendisk() is done before
rq_qos_add(), then memory will be leaked.
This patch add a new disk level mutex 'rq_qos_mutex':
1) The lock will protect rq_qos_exit() directly.
2) For wbt that doesn't relied on blk-cgroup, rq_qos_add() can only be
called from disk initialization for now because wbt can't be
destructed until rq_qos_exit(), so it's safe not to protect wbt for
now. Hoever, in case that rq_qos dynamically destruction is supported
in the furture, this patch also protect rq_qos_add() from wbt_init()
directly, this is enough because blk-sysfs already synchronize
writers with disk removal.
3) For iocost and iolatency, in order to synchronize disk removal and
cgroup configuration, the lock is held after blkdev_get_no_open()
from blkg_conf_open_bdev(), and is released in blkg_conf_exit().
In order to fix the above memory leak, disk_live() is checked after
holding the new lock.
Fixes: 50e34d78815e ("block: disable the elevator int del_gendisk")
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Acked-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/r/20230414084008.2085155-1-yukuai1@huaweicloud.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-cgroup.c | 12 ++++++++++++
block/blk-core.c | 1 +
block/blk-iocost.c | 4 ++++
block/blk-rq-qos.c | 2 ++
block/blk-rq-qos.h | 18 ++++--------------
block/blk-wbt.c | 2 ++
include/linux/blkdev.h | 1 +
7 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 7d7c99d93bdb8..3a33ec0af8419 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -656,6 +656,13 @@ struct block_device *blkcg_conf_open_bdev(char **inputp)
return ERR_PTR(-ENODEV);
}
+ mutex_lock(&bdev->bd_queue->rq_qos_mutex);
+ if (!disk_live(bdev->bd_disk)) {
+ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
+ blkdev_put_no_open(bdev);
+ return ERR_PTR(-ENODEV);
+ }
+
*inputp = input;
return bdev;
}
@@ -779,6 +786,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
fail_exit_queue:
blk_queue_exit(q);
fail:
+ mutex_unlock(&q->rq_qos_mutex);
blkdev_put_no_open(bdev);
/*
* If queue was bypassing, we should retry. Do so after a
@@ -803,9 +811,11 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
*/
void blkg_conf_finish(struct blkg_conf_ctx *ctx)
__releases(&ctx->bdev->bd_queue->queue_lock) __releases(rcu)
+ __releases(&ctx->bdev->bd_queue->rq_qos_mutex)
{
spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
rcu_read_unlock();
+ mutex_unlock(&ctx->bdev->bd_queue->rq_qos_mutex);
blkdev_put_no_open(ctx->bdev);
}
EXPORT_SYMBOL_GPL(blkg_conf_finish);
@@ -1297,7 +1307,9 @@ int blkcg_init_disk(struct gendisk *disk)
if (ret)
goto err_ioprio_exit;
+ mutex_lock(&q->rq_qos_mutex);
ret = blk_iolatency_init(disk);
+ mutex_unlock(&q->rq_qos_mutex);
if (ret)
goto err_throtl_exit;
diff --git a/block/blk-core.c b/block/blk-core.c
index 1fcd80a1c54fd..641bc0fa8a4ad 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -412,6 +412,7 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu)
mutex_init(&q->debugfs_mutex);
mutex_init(&q->sysfs_lock);
mutex_init(&q->sysfs_dir_lock);
+ mutex_init(&q->rq_qos_mutex);
spin_lock_init(&q->queue_lock);
init_waitqueue_head(&q->mq_freeze_wq);
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 93482cc420c97..3989d8c796b0f 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -3309,11 +3309,13 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
ioc_refresh_params(ioc, true);
spin_unlock_irq(&ioc->lock);
+ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
blkdev_put_no_open(bdev);
return nbytes;
einval:
ret = -EINVAL;
err:
+ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
blkdev_put_no_open(bdev);
return ret;
}
@@ -3434,12 +3436,14 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
ioc_refresh_params(ioc, true);
spin_unlock_irq(&ioc->lock);
+ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
blkdev_put_no_open(bdev);
return nbytes;
einval:
ret = -EINVAL;
err:
+ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
blkdev_put_no_open(bdev);
return ret;
}
diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
index a319311d1ced1..aa45f073d51b0 100644
--- a/block/blk-rq-qos.c
+++ b/block/blk-rq-qos.c
@@ -288,9 +288,11 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
void rq_qos_exit(struct request_queue *q)
{
+ mutex_lock(&q->rq_qos_mutex);
while (q->rq_qos) {
struct rq_qos *rqos = q->rq_qos;
q->rq_qos = rqos->next;
rqos->ops->exit(rqos);
}
+ mutex_unlock(&q->rq_qos_mutex);
}
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index 1ef1f7d4bc3cb..98be0e02a86c1 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -87,21 +87,18 @@ static inline void rq_wait_init(struct rq_wait *rq_wait)
static inline int rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
{
+ lockdep_assert_held(&q->rq_qos_mutex);
+
/*
* No IO can be in-flight when adding rqos, so freeze queue, which
* is fine since we only support rq_qos for blk-mq queue.
- *
- * Reuse ->queue_lock for protecting against other concurrent
- * rq_qos adding/deleting
*/
blk_mq_freeze_queue(q);
- spin_lock_irq(&q->queue_lock);
if (rq_qos_id(q, rqos->id))
goto ebusy;
rqos->next = q->rq_qos;
q->rq_qos = rqos;
- spin_unlock_irq(&q->queue_lock);
blk_mq_unfreeze_queue(q);
@@ -113,7 +110,6 @@ static inline int rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
return 0;
ebusy:
- spin_unlock_irq(&q->queue_lock);
blk_mq_unfreeze_queue(q);
return -EBUSY;
@@ -123,21 +119,15 @@ static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos)
{
struct rq_qos **cur;
- /*
- * See comment in rq_qos_add() about freezing queue & using
- * ->queue_lock.
- */
- blk_mq_freeze_queue(q);
+ lockdep_assert_held(&q->rq_qos_mutex);
- spin_lock_irq(&q->queue_lock);
+ blk_mq_freeze_queue(q);
for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) {
if (*cur == rqos) {
*cur = rqos->next;
break;
}
}
- spin_unlock_irq(&q->queue_lock);
-
blk_mq_unfreeze_queue(q);
mutex_lock(&q->debugfs_mutex);
diff --git a/block/blk-wbt.c b/block/blk-wbt.c
index c293e08b301ff..46534c877c12f 100644
--- a/block/blk-wbt.c
+++ b/block/blk-wbt.c
@@ -850,7 +850,9 @@ int wbt_init(struct request_queue *q)
/*
* Assign rwb and add the stats callback.
*/
+ mutex_lock(&q->rq_qos_mutex);
ret = rq_qos_add(q, &rwb->rqos);
+ mutex_unlock(&q->rq_qos_mutex);
if (ret)
goto err_free;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index de013fc37ef83..c5d07c7609d4b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -397,6 +397,7 @@ struct request_queue {
struct blk_queue_stats *stats;
struct rq_qos *rq_qos;
+ struct mutex rq_qos_mutex;
const struct blk_mq_ops *mq_ops;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0571/1887] f2fs: fix to do sanity check on direct node in truncate_dnode()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (569 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0570/1887] block/rq_qos: protect rq_qos apis with a new lock Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0572/1887] interconnect: Fix locking for runpm vs reclaim Greg Kroah-Hartman
` (427 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin,
syzbot+12cb4425b22169b52036
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit a6ec83786ab9f13f25fb18166dee908845713a95 ]
syzbot reports below bug:
BUG: KASAN: slab-use-after-free in f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
Read of size 4 at addr ffff88802a25c000 by task syz-executor148/5000
CPU: 1 PID: 5000 Comm: syz-executor148 Not tainted 6.4.0-rc7-syzkaller-00041-ge660abd551f1 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xd9/0x150 lib/dump_stack.c:106
print_address_description.constprop.0+0x2c/0x3c0 mm/kasan/report.c:351
print_report mm/kasan/report.c:462 [inline]
kasan_report+0x11c/0x130 mm/kasan/report.c:572
f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
truncate_dnode+0x229/0x2e0 fs/f2fs/node.c:944
f2fs_truncate_inode_blocks+0x64b/0xde0 fs/f2fs/node.c:1154
f2fs_do_truncate_blocks+0x4ac/0xf30 fs/f2fs/file.c:721
f2fs_truncate_blocks+0x7b/0x300 fs/f2fs/file.c:749
f2fs_truncate.part.0+0x4a5/0x630 fs/f2fs/file.c:799
f2fs_truncate include/linux/fs.h:825 [inline]
f2fs_setattr+0x1738/0x2090 fs/f2fs/file.c:1006
notify_change+0xb2c/0x1180 fs/attr.c:483
do_truncate+0x143/0x200 fs/open.c:66
handle_truncate fs/namei.c:3295 [inline]
do_open fs/namei.c:3640 [inline]
path_openat+0x2083/0x2750 fs/namei.c:3791
do_filp_open+0x1ba/0x410 fs/namei.c:3818
do_sys_openat2+0x16d/0x4c0 fs/open.c:1356
do_sys_open fs/open.c:1372 [inline]
__do_sys_creat fs/open.c:1448 [inline]
__se_sys_creat fs/open.c:1442 [inline]
__x64_sys_creat+0xcd/0x120 fs/open.c:1442
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
The root cause is, inodeA references inodeB via inodeB's ino, once inodeA
is truncated, it calls truncate_dnode() to truncate data blocks in inodeB's
node page, it traverse mapping data from node->i.i_addr[0] to
node->i.i_addr[ADDRS_PER_BLOCK() - 1], result in out-of-boundary access.
This patch fixes to add sanity check on dnode page in truncate_dnode(),
so that, it can help to avoid triggering such issue, and once it encounters
such issue, it will record newly introduced ERROR_INVALID_NODE_REFERENCE
error into superblock, later fsck can detect such issue and try repairing.
Also, it removes f2fs_truncate_data_blocks() for cleanup due to the
function has only one caller, and uses f2fs_truncate_data_blocks_range()
instead.
Reported-and-tested-by: syzbot+12cb4425b22169b52036@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000f3038a05fef867f8@google.com
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/f2fs.h | 1 -
fs/f2fs/file.c | 5 -----
fs/f2fs/node.c | 14 ++++++++++++--
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 3b1d99d03ab1b..971d45979ce40 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3466,7 +3466,6 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr)
* file.c
*/
int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
-void f2fs_truncate_data_blocks(struct dnode_of_data *dn);
int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock);
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
int f2fs_truncate(struct inode *inode);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 36c3103035c3d..6755d23a90512 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -666,11 +666,6 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
dn->ofs_in_node, nr_free);
}
-void f2fs_truncate_data_blocks(struct dnode_of_data *dn)
-{
- f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode));
-}
-
static int truncate_partial_data_page(struct inode *inode, u64 from,
bool cache_only)
{
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 8d2e5d3910c59..9d4ec1a061bfb 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -946,6 +946,7 @@ static int truncate_node(struct dnode_of_data *dn)
static int truncate_dnode(struct dnode_of_data *dn)
{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct page *page;
int err;
@@ -953,16 +954,25 @@ static int truncate_dnode(struct dnode_of_data *dn)
return 1;
/* get direct node */
- page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid);
+ page = f2fs_get_node_page(sbi, dn->nid);
if (PTR_ERR(page) == -ENOENT)
return 1;
else if (IS_ERR(page))
return PTR_ERR(page);
+ if (IS_INODE(page) || ino_of_node(page) != dn->inode->i_ino) {
+ f2fs_err(sbi, "incorrect node reference, ino: %lu, nid: %u, ino_of_node: %u",
+ dn->inode->i_ino, dn->nid, ino_of_node(page));
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_handle_error(sbi, ERROR_INVALID_NODE_REFERENCE);
+ f2fs_put_page(page, 1);
+ return -EFSCORRUPTED;
+ }
+
/* Make dnode_of_data for parameter */
dn->node_page = page;
dn->ofs_in_node = 0;
- f2fs_truncate_data_blocks(dn);
+ f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode));
err = truncate_node(dn);
if (err) {
f2fs_put_page(page, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0572/1887] interconnect: Fix locking for runpm vs reclaim
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (570 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0571/1887] f2fs: fix to do sanity check on direct node in truncate_dnode() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0573/1887] blk-cgroup: dropping parent refcount after pd_free_fn() is done Greg Kroah-Hartman
` (426 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rob Clark, Georgi Djakov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <robdclark@chromium.org>
[ Upstream commit af42269c3523492d71ebbe11fefae2653e9cdc78 ]
For cases where icc_bw_set() can be called in callbaths that could
deadlock against shrinker/reclaim, such as runpm resume, we need to
decouple the icc locking. Introduce a new icc_bw_lock for cases where
we need to serialize bw aggregation and update to decouple that from
paths that require memory allocation such as node/link creation/
destruction.
Fixes this lockdep splat:
======================================================
WARNING: possible circular locking dependency detected
6.2.0-rc8-debug+ #554 Not tainted
------------------------------------------------------
ring0/132 is trying to acquire lock:
ffffff80871916d0 (&gmu->lock){+.+.}-{3:3}, at: a6xx_pm_resume+0xf0/0x234
but task is already holding lock:
ffffffdb5aee57e8 (dma_fence_map){++++}-{0:0}, at: msm_job_run+0x68/0x150
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #4 (dma_fence_map){++++}-{0:0}:
__dma_fence_might_wait+0x74/0xc0
dma_resv_lockdep+0x1f4/0x2f4
do_one_initcall+0x104/0x2bc
kernel_init_freeable+0x344/0x34c
kernel_init+0x30/0x134
ret_from_fork+0x10/0x20
-> #3 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}:
fs_reclaim_acquire+0x80/0xa8
slab_pre_alloc_hook.constprop.0+0x40/0x25c
__kmem_cache_alloc_node+0x60/0x1cc
__kmalloc+0xd8/0x100
topology_parse_cpu_capacity+0x8c/0x178
get_cpu_for_node+0x88/0xc4
parse_cluster+0x1b0/0x28c
parse_cluster+0x8c/0x28c
init_cpu_topology+0x168/0x188
smp_prepare_cpus+0x24/0xf8
kernel_init_freeable+0x18c/0x34c
kernel_init+0x30/0x134
ret_from_fork+0x10/0x20
-> #2 (fs_reclaim){+.+.}-{0:0}:
__fs_reclaim_acquire+0x3c/0x48
fs_reclaim_acquire+0x54/0xa8
slab_pre_alloc_hook.constprop.0+0x40/0x25c
__kmem_cache_alloc_node+0x60/0x1cc
__kmalloc+0xd8/0x100
kzalloc.constprop.0+0x14/0x20
icc_node_create_nolock+0x4c/0xc4
icc_node_create+0x38/0x58
qcom_icc_rpmh_probe+0x1b8/0x248
platform_probe+0x70/0xc4
really_probe+0x158/0x290
__driver_probe_device+0xc8/0xe0
driver_probe_device+0x44/0x100
__driver_attach+0xf8/0x108
bus_for_each_dev+0x78/0xc4
driver_attach+0x2c/0x38
bus_add_driver+0xd0/0x1d8
driver_register+0xbc/0xf8
__platform_driver_register+0x30/0x3c
qnoc_driver_init+0x24/0x30
do_one_initcall+0x104/0x2bc
kernel_init_freeable+0x344/0x34c
kernel_init+0x30/0x134
ret_from_fork+0x10/0x20
-> #1 (icc_lock){+.+.}-{3:3}:
__mutex_lock+0xcc/0x3c8
mutex_lock_nested+0x30/0x44
icc_set_bw+0x88/0x2b4
_set_opp_bw+0x8c/0xd8
_set_opp+0x19c/0x300
dev_pm_opp_set_opp+0x84/0x94
a6xx_gmu_resume+0x18c/0x804
a6xx_pm_resume+0xf8/0x234
adreno_runtime_resume+0x2c/0x38
pm_generic_runtime_resume+0x30/0x44
__rpm_callback+0x15c/0x174
rpm_callback+0x78/0x7c
rpm_resume+0x318/0x524
__pm_runtime_resume+0x78/0xbc
adreno_load_gpu+0xc4/0x17c
msm_open+0x50/0x120
drm_file_alloc+0x17c/0x228
drm_open_helper+0x74/0x118
drm_open+0xa0/0x144
drm_stub_open+0xd4/0xe4
chrdev_open+0x1b8/0x1e4
do_dentry_open+0x2f8/0x38c
vfs_open+0x34/0x40
path_openat+0x64c/0x7b4
do_filp_open+0x54/0xc4
do_sys_openat2+0x9c/0x100
do_sys_open+0x50/0x7c
__arm64_sys_openat+0x28/0x34
invoke_syscall+0x8c/0x128
el0_svc_common.constprop.0+0xa0/0x11c
do_el0_svc+0xac/0xbc
el0_svc+0x48/0xa0
el0t_64_sync_handler+0xac/0x13c
el0t_64_sync+0x190/0x194
-> #0 (&gmu->lock){+.+.}-{3:3}:
__lock_acquire+0xe00/0x1060
lock_acquire+0x1e0/0x2f8
__mutex_lock+0xcc/0x3c8
mutex_lock_nested+0x30/0x44
a6xx_pm_resume+0xf0/0x234
adreno_runtime_resume+0x2c/0x38
pm_generic_runtime_resume+0x30/0x44
__rpm_callback+0x15c/0x174
rpm_callback+0x78/0x7c
rpm_resume+0x318/0x524
__pm_runtime_resume+0x78/0xbc
pm_runtime_get_sync.isra.0+0x14/0x20
msm_gpu_submit+0x58/0x178
msm_job_run+0x78/0x150
drm_sched_main+0x290/0x370
kthread+0xf0/0x100
ret_from_fork+0x10/0x20
other info that might help us debug this:
Chain exists of:
&gmu->lock --> mmu_notifier_invalidate_range_start --> dma_fence_map
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(dma_fence_map);
lock(mmu_notifier_invalidate_range_start);
lock(dma_fence_map);
lock(&gmu->lock);
*** DEADLOCK ***
2 locks held by ring0/132:
#0: ffffff8087191170 (&gpu->lock){+.+.}-{3:3}, at: msm_job_run+0x64/0x150
#1: ffffffdb5aee57e8 (dma_fence_map){++++}-{0:0}, at: msm_job_run+0x68/0x150
stack backtrace:
CPU: 7 PID: 132 Comm: ring0 Not tainted 6.2.0-rc8-debug+ #554
Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
Call trace:
dump_backtrace.part.0+0xb4/0xf8
show_stack+0x20/0x38
dump_stack_lvl+0x9c/0xd0
dump_stack+0x18/0x34
print_circular_bug+0x1b4/0x1f0
check_noncircular+0x78/0xac
__lock_acquire+0xe00/0x1060
lock_acquire+0x1e0/0x2f8
__mutex_lock+0xcc/0x3c8
mutex_lock_nested+0x30/0x44
a6xx_pm_resume+0xf0/0x234
adreno_runtime_resume+0x2c/0x38
pm_generic_runtime_resume+0x30/0x44
__rpm_callback+0x15c/0x174
rpm_callback+0x78/0x7c
rpm_resume+0x318/0x524
__pm_runtime_resume+0x78/0xbc
pm_runtime_get_sync.isra.0+0x14/0x20
msm_gpu_submit+0x58/0x178
msm_job_run+0x78/0x150
drm_sched_main+0x290/0x370
kthread+0xf0/0x100
ret_from_fork+0x10/0x20
Signed-off-by: Rob Clark <robdclark@chromium.org>
Link: https://lore.kernel.org/r/20230807171148.210181-7-robdclark@gmail.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/interconnect/core.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 09143aae680ef..40e2f110c5339 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -29,6 +29,7 @@ static LIST_HEAD(icc_providers);
static int providers_count;
static bool synced_state;
static DEFINE_MUTEX(icc_lock);
+static DEFINE_MUTEX(icc_bw_lock);
static struct dentry *icc_debugfs_dir;
static void icc_summary_show_one(struct seq_file *s, struct icc_node *n)
@@ -635,7 +636,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw)
if (WARN_ON(IS_ERR(path) || !path->num_nodes))
return -EINVAL;
- mutex_lock(&icc_lock);
+ mutex_lock(&icc_bw_lock);
old_avg = path->reqs[0].avg_bw;
old_peak = path->reqs[0].peak_bw;
@@ -667,7 +668,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw)
apply_constraints(path);
}
- mutex_unlock(&icc_lock);
+ mutex_unlock(&icc_bw_lock);
trace_icc_set_bw_end(path, ret);
@@ -971,6 +972,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
return;
mutex_lock(&icc_lock);
+ mutex_lock(&icc_bw_lock);
node->provider = provider;
list_add_tail(&node->node_list, &provider->nodes);
@@ -996,6 +998,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
node->avg_bw = 0;
node->peak_bw = 0;
+ mutex_unlock(&icc_bw_lock);
mutex_unlock(&icc_lock);
}
EXPORT_SYMBOL_GPL(icc_node_add);
@@ -1135,6 +1138,7 @@ void icc_sync_state(struct device *dev)
return;
mutex_lock(&icc_lock);
+ mutex_lock(&icc_bw_lock);
synced_state = true;
list_for_each_entry(p, &icc_providers, provider_list) {
dev_dbg(p->dev, "interconnect provider is in synced state\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0573/1887] blk-cgroup: dropping parent refcount after pd_free_fn() is done
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (571 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0572/1887] interconnect: Fix locking for runpm vs reclaim Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0574/1887] nexthop: Factor out hash threshold fdb nexthop selection Greg Kroah-Hartman
` (425 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Kuai, Tejun Heo,
Christoph Hellwig, Jens Axboe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <yukuai3@huawei.com>
[ Upstream commit c7241babf0855d8a6180cd1743ff0ec34de40b4e ]
Some cgroup policies will access parent pd through child pd even
after pd_offline_fn() is done. If pd_free_fn() for parent is called
before child, then UAF can be triggered. Hence it's better to guarantee
the order of pd_free_fn().
Currently refcount of parent blkg is dropped in __blkg_release(), which
is before pd_free_fn() is called in blkg_free_work_fn() while
blkg_free_work_fn() is called asynchronously.
This patch make sure pd_free_fn() called from removing cgroup is ordered
by delaying dropping parent refcount after calling pd_free_fn() for
child.
BTW, pd_free_fn() will also be called from blkcg_deactivate_policy()
from deleting device, and following patches will guarantee the order.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20230119110350.2287325-2-yukuai1@huaweicloud.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-cgroup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 3a33ec0af8419..34b89029ba434 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -94,6 +94,8 @@ static void blkg_free_workfn(struct work_struct *work)
if (blkg->pd[i])
blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
+ if (blkg->parent)
+ blkg_put(blkg->parent);
if (blkg->q)
blk_put_queue(blkg->q);
free_percpu(blkg->iostat_cpu);
@@ -128,8 +130,6 @@ static void __blkg_release(struct rcu_head *rcu)
/* release the blkcg and parent blkg refs this blkg has been holding */
css_put(&blkg->blkcg->css);
- if (blkg->parent)
- blkg_put(blkg->parent);
blkg_free(blkg);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0574/1887] nexthop: Factor out hash threshold fdb nexthop selection
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (572 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0573/1887] blk-cgroup: dropping parent refcount after pd_free_fn() is done Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0575/1887] nexthop: Factor out neighbor validity check Greg Kroah-Hartman
` (424 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Benjamin Poirier,
David Ahern, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Poirier <bpoirier@nvidia.com>
[ Upstream commit eedd47a6ec9f683f0b8d931aacca81985be55eec ]
The loop in nexthop_select_path_hthr() includes code to check for neighbor
validity. Since this does not apply to fdb nexthops, simplify the loop by
moving the fdb nexthop selection to its own function.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Benjamin Poirier <bpoirier@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20230719-nh_select-v2-1-04383e89f868@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b72a6a7ab957 ("net: nexthop: Increase weight to u16")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/nexthop.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index cd93dd74608ac..e3d9660bf0e5c 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1153,11 +1153,31 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
return !!(state & NUD_VALID);
}
+static struct nexthop *nexthop_select_path_fdb(struct nh_group *nhg, int hash)
+{
+ int i;
+
+ for (i = 0; i < nhg->num_nh; i++) {
+ struct nh_grp_entry *nhge = &nhg->nh_entries[i];
+
+ if (hash > atomic_read(&nhge->hthr.upper_bound))
+ continue;
+
+ return nhge->nh;
+ }
+
+ WARN_ON_ONCE(1);
+ return NULL;
+}
+
static struct nexthop *nexthop_select_path_hthr(struct nh_group *nhg, int hash)
{
struct nexthop *rc = NULL;
int i;
+ if (nhg->fdb_nh)
+ return nexthop_select_path_fdb(nhg, hash);
+
for (i = 0; i < nhg->num_nh; ++i) {
struct nh_grp_entry *nhge = &nhg->nh_entries[i];
struct nh_info *nhi;
@@ -1166,8 +1186,6 @@ static struct nexthop *nexthop_select_path_hthr(struct nh_group *nhg, int hash)
continue;
nhi = rcu_dereference(nhge->nh->nh_info);
- if (nhi->fdb_nh)
- return nhge->nh;
/* nexthops always check if it is good and does
* not rely on a sysctl for this behavior
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0575/1887] nexthop: Factor out neighbor validity check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (573 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0574/1887] nexthop: Factor out hash threshold fdb nexthop selection Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0576/1887] nexthop: Do not return invalid nexthop object during multipath selection Greg Kroah-Hartman
` (423 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Benjamin Poirier,
David Ahern, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Poirier <bpoirier@nvidia.com>
[ Upstream commit 4bb5239b43348f4a1cd73f44be3dc57ac653ae9c ]
For legacy nexthops, there is fib_good_nh() to check the neighbor validity.
In order to make the nexthop object code more similar to the legacy nexthop
code, factor out the nexthop object neighbor validity check into its own
function.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Benjamin Poirier <bpoirier@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20230719-nh_select-v2-2-04383e89f868@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b72a6a7ab957 ("net: nexthop: Increase weight to u16")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/nexthop.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index e3d9660bf0e5c..005465e61ae3d 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1153,6 +1153,20 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
return !!(state & NUD_VALID);
}
+static bool nexthop_is_good_nh(const struct nexthop *nh)
+{
+ struct nh_info *nhi = rcu_dereference(nh->nh_info);
+
+ switch (nhi->family) {
+ case AF_INET:
+ return ipv4_good_nh(&nhi->fib_nh);
+ case AF_INET6:
+ return ipv6_good_nh(&nhi->fib6_nh);
+ }
+
+ return false;
+}
+
static struct nexthop *nexthop_select_path_fdb(struct nh_group *nhg, int hash)
{
int i;
@@ -1180,26 +1194,15 @@ static struct nexthop *nexthop_select_path_hthr(struct nh_group *nhg, int hash)
for (i = 0; i < nhg->num_nh; ++i) {
struct nh_grp_entry *nhge = &nhg->nh_entries[i];
- struct nh_info *nhi;
if (hash > atomic_read(&nhge->hthr.upper_bound))
continue;
- nhi = rcu_dereference(nhge->nh->nh_info);
-
/* nexthops always check if it is good and does
* not rely on a sysctl for this behavior
*/
- switch (nhi->family) {
- case AF_INET:
- if (ipv4_good_nh(&nhi->fib_nh))
- return nhge->nh;
- break;
- case AF_INET6:
- if (ipv6_good_nh(&nhi->fib6_nh))
- return nhge->nh;
- break;
- }
+ if (nexthop_is_good_nh(nhge->nh))
+ return nhge->nh;
if (!rc)
rc = nhge->nh;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0576/1887] nexthop: Do not return invalid nexthop object during multipath selection
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (574 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0575/1887] nexthop: Factor out neighbor validity check Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0577/1887] net: nexthop: Have all NH notifiers carry NH ID Greg Kroah-Hartman
` (422 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Benjamin Poirier,
David Ahern, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Poirier <bpoirier@nvidia.com>
[ Upstream commit 75f5f04c7bd2163044f80d5f7bea6b79edc288fa ]
With legacy nexthops, when net.ipv4.fib_multipath_use_neigh is set,
fib_select_multipath() will never set res->nhc to a nexthop that is not
good (as per fib_good_nh()). OTOH, with nexthop objects,
nexthop_select_path_hthr() may return a nexthop that failed the
nexthop_is_good_nh() test even if there was one that passed. Refactor
nexthop_select_path_hthr() to follow a selection logic more similar to
fib_select_multipath().
The issue can be demonstrated with the following sequence of commands. The
first block shows that things work as expected with legacy nexthops. The
last sequence of `ip rou get` in the second block shows the problem case -
some routes still use the .2 nexthop.
sysctl net.ipv4.fib_multipath_use_neigh=1
ip link add dummy1 up type dummy
ip rou add 198.51.100.0/24 nexthop via 192.0.2.1 dev dummy1 onlink nexthop via 192.0.2.2 dev dummy1 onlink
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip neigh add 192.0.2.1 dev dummy1 nud failed
echo ".1 failed:" # results should not use .1
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip neigh del 192.0.2.1 dev dummy1
ip neigh add 192.0.2.2 dev dummy1 nud failed
echo ".2 failed:" # results should not use .2
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip link del dummy1
ip link add dummy1 up type dummy
ip nexthop add id 1 via 192.0.2.1 dev dummy1 onlink
ip nexthop add id 2 via 192.0.2.2 dev dummy1 onlink
ip nexthop add id 1001 group 1/2
ip rou add 198.51.100.0/24 nhid 1001
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip neigh add 192.0.2.1 dev dummy1 nud failed
echo ".1 failed:" # results should not use .1
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip neigh del 192.0.2.1 dev dummy1
ip neigh add 192.0.2.2 dev dummy1 nud failed
echo ".2 failed:" # results should not use .2
for i in {10..19}; do ip -o rou get 198.51.100.$i; done
ip link del dummy1
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Benjamin Poirier <bpoirier@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20230719-nh_select-v2-3-04383e89f868@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b72a6a7ab957 ("net: nexthop: Increase weight to u16")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/nexthop.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 005465e61ae3d..5dc50bbdd2d07 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1195,20 +1195,22 @@ static struct nexthop *nexthop_select_path_hthr(struct nh_group *nhg, int hash)
for (i = 0; i < nhg->num_nh; ++i) {
struct nh_grp_entry *nhge = &nhg->nh_entries[i];
- if (hash > atomic_read(&nhge->hthr.upper_bound))
- continue;
-
/* nexthops always check if it is good and does
* not rely on a sysctl for this behavior
*/
- if (nexthop_is_good_nh(nhge->nh))
- return nhge->nh;
+ if (!nexthop_is_good_nh(nhge->nh))
+ continue;
if (!rc)
rc = nhge->nh;
+
+ if (hash > atomic_read(&nhge->hthr.upper_bound))
+ continue;
+
+ return nhge->nh;
}
- return rc;
+ return rc ? : nhg->nh_entries[0].nh;
}
static struct nexthop *nexthop_select_path_res(struct nh_group *nhg, int hash)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0577/1887] net: nexthop: Have all NH notifiers carry NH ID
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (575 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0576/1887] nexthop: Do not return invalid nexthop object during multipath selection Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0578/1887] net: nexthop: Increase weight to u16 Greg Kroah-Hartman
` (421 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Petr Machata, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <petrm@nvidia.com>
[ Upstream commit e99eb57e9b14d830a571c5255248d4d7eb08b27e ]
When sending the notifications to collect NH statistics for resilient
groups, the driver will need to know the nexthop IDs in individual buckets
to look up the right counter. To that end, move the nexthop ID from struct
nh_notifier_grp_entry_info to nh_notifier_single_info.
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/8f964cd50b1a56d3606ce7ab4c50354ae019c43b.1709901020.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b72a6a7ab957 ("net: nexthop: Increase weight to u16")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/nexthop.h | 2 +-
net/ipv4/nexthop.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/nexthop.h b/include/net/nexthop.h
index 2b12725de9c09..f7d4239347351 100644
--- a/include/net/nexthop.h
+++ b/include/net/nexthop.h
@@ -173,6 +173,7 @@ struct nh_notifier_single_info {
__be32 ipv4;
struct in6_addr ipv6;
};
+ u32 id;
u8 is_reject:1,
is_fdb:1,
has_encap:1;
@@ -180,7 +181,6 @@ struct nh_notifier_single_info {
struct nh_notifier_grp_entry_info {
u8 weight;
- u32 id;
struct nh_notifier_single_info nh;
};
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 5dc50bbdd2d07..0bf7b83bec1b9 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -92,6 +92,7 @@ __nh_notifier_single_info_init(struct nh_notifier_single_info *nh_info,
else if (nh_info->gw_family == AF_INET6)
nh_info->ipv6 = nhi->fib_nhc.nhc_gw.ipv6;
+ nh_info->id = nhi->nh_parent->id;
nh_info->is_reject = nhi->reject_nh;
nh_info->is_fdb = nhi->fdb_nh;
nh_info->has_encap = !!nhi->fib_nhc.nhc_lwtstate;
@@ -137,7 +138,6 @@ static int nh_notifier_mpath_info_init(struct nh_notifier_info *info,
struct nh_info *nhi;
nhi = rtnl_dereference(nhge->nh->nh_info);
- info->nh_grp->nh_entries[i].id = nhge->nh->id;
info->nh_grp->nh_entries[i].weight = nhge->weight;
__nh_notifier_single_info_init(&info->nh_grp->nh_entries[i].nh,
nhi);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0578/1887] net: nexthop: Increase weight to u16
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (576 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0577/1887] net: nexthop: Have all NH notifiers carry NH ID Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0579/1887] drm/amd/display: Add NULL test for timing generator in dcn21_set_pipe() Greg Kroah-Hartman
` (420 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Petr Machata, Ido Schimmel,
David Ahern, Przemek Kitszel, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <petrm@nvidia.com>
[ Upstream commit b72a6a7ab9573e06d5c2fcb92eaa28614a735bfd ]
In CLOS networks, as link failures occur at various points in the network,
ECMP weights of the involved nodes are adjusted to compensate. With high
fan-out of the involved nodes, and overall high number of nodes,
a (non-)ECMP weight ratio that we would like to configure does not fit into
8 bits. Instead of, say, 255:254, we might like to configure something like
1000:999. For these deployments, the 8-bit weight may not be enough.
To that end, in this patch increase the next hop weight from u8 to u16.
Increasing the width of an integral type can be tricky, because while the
code still compiles, the types may not check out anymore, and numerical
errors come up. To prevent this, the conversion was done in two steps.
First the type was changed from u8 to a single-member structure, which
invalidated all uses of the field. This allowed going through them one by
one and audit for type correctness. Then the structure was replaced with a
vanilla u16 again. This should ensure that no place was missed.
The UAPI for configuring nexthop group members is that an attribute
NHA_GROUP carries an array of struct nexthop_grp entries:
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u16 resvd2;
};
The field resvd1 is currently validated and required to be zero. We can
lift this requirement and carry high-order bits of the weight in the
reserved field:
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 weight_high;
__u16 resvd2;
};
Keeping the fields split this way was chosen in case an existing userspace
makes assumptions about the width of the weight field, and to sidestep any
endianness issues.
The weight field is currently encoded as the weight value minus one,
because weight of 0 is invalid. This same trick is impossible for the new
weight_high field, because zero must mean actual zero. With this in place:
- Old userspace is guaranteed to carry weight_high of 0, therefore
configuring 8-bit weights as appropriate. When dumping nexthops with
16-bit weight, it would only show the lower 8 bits. But configuring such
nexthops implies existence of userspace aware of the extension in the
first place.
- New userspace talking to an old kernel will work as long as it only
attempts to configure 8-bit weights, where the high-order bits are zero.
Old kernel will bounce attempts at configuring >8-bit weights.
Renaming reserved fields as they are allocated for some purpose is commonly
done in Linux. Whoever touches a reserved field is doing so at their own
risk. nexthop_grp::resvd1 in particular is currently used by at least
strace, however they carry an own copy of UAPI headers, and the conversion
should be trivial. A helper is provided for decoding the weight out of the
two fields. Forcing a conversion seems preferable to bending backwards and
introducing anonymous unions or whatever.
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Link: https://patch.msgid.link/483e2fcf4beb0d9135d62e7d27b46fa2685479d4.1723036486.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/nexthop.h | 4 ++--
include/uapi/linux/nexthop.h | 7 ++++++-
net/ipv4/nexthop.c | 37 ++++++++++++++++++++++--------------
3 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/include/net/nexthop.h b/include/net/nexthop.h
index f7d4239347351..f37e96f93f20b 100644
--- a/include/net/nexthop.h
+++ b/include/net/nexthop.h
@@ -97,7 +97,7 @@ struct nh_res_table {
struct nh_grp_entry {
struct nexthop *nh;
- u8 weight;
+ u16 weight;
union {
struct {
@@ -180,7 +180,7 @@ struct nh_notifier_single_info {
};
struct nh_notifier_grp_entry_info {
- u8 weight;
+ u16 weight;
struct nh_notifier_single_info nh;
};
diff --git a/include/uapi/linux/nexthop.h b/include/uapi/linux/nexthop.h
index d8ffa8c9ca784..6b0de563beec1 100644
--- a/include/uapi/linux/nexthop.h
+++ b/include/uapi/linux/nexthop.h
@@ -16,10 +16,15 @@ struct nhmsg {
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
- __u8 resvd1;
+ __u8 weight_high; /* high order bits of weight */
__u16 resvd2;
};
+static inline __u16 nexthop_grp_weight(const struct nexthop_grp *entry)
+{
+ return ((entry->weight_high << 8) | entry->weight) + 1;
+}
+
enum {
NEXTHOP_GRP_TYPE_MPATH, /* hash-threshold nexthop group
* default type if not specified
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 0bf7b83bec1b9..b48fbc0f42899 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -660,6 +660,7 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg)
size_t len = nhg->num_nh * sizeof(*p);
struct nlattr *nla;
u16 group_type = 0;
+ u16 weight;
int i;
if (nhg->hash_threshold)
@@ -676,9 +677,12 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg)
p = nla_data(nla);
for (i = 0; i < nhg->num_nh; ++i) {
+ weight = nhg->nh_entries[i].weight - 1;
+
*p++ = (struct nexthop_grp) {
.id = nhg->nh_entries[i].nh->id,
- .weight = nhg->nh_entries[i].weight - 1,
+ .weight = weight,
+ .weight_high = weight >> 8,
};
}
@@ -1062,11 +1066,14 @@ static int nh_check_attr_group(struct net *net,
nhg = nla_data(tb[NHA_GROUP]);
for (i = 0; i < len; ++i) {
- if (nhg[i].resvd1 || nhg[i].resvd2) {
- NL_SET_ERR_MSG(extack, "Reserved fields in nexthop_grp must be 0");
+ if (nhg[i].resvd2) {
+ NL_SET_ERR_MSG(extack, "Reserved field in nexthop_grp must be 0");
return -EINVAL;
}
- if (nhg[i].weight > 254) {
+ if (nexthop_grp_weight(&nhg[i]) == 0) {
+ /* 0xffff got passed in, representing weight of 0x10000,
+ * which is too heavy.
+ */
NL_SET_ERR_MSG(extack, "Invalid value for weight");
return -EINVAL;
}
@@ -1655,9 +1662,9 @@ static void nh_res_table_cancel_upkeep(struct nh_res_table *res_table)
static void nh_res_group_rebalance(struct nh_group *nhg,
struct nh_res_table *res_table)
{
- int prev_upper_bound = 0;
- int total = 0;
- int w = 0;
+ u16 prev_upper_bound = 0;
+ u32 total = 0;
+ u32 w = 0;
int i;
INIT_LIST_HEAD(&res_table->uw_nh_entries);
@@ -1667,11 +1674,12 @@ static void nh_res_group_rebalance(struct nh_group *nhg,
for (i = 0; i < nhg->num_nh; ++i) {
struct nh_grp_entry *nhge = &nhg->nh_entries[i];
- int upper_bound;
+ u16 upper_bound;
+ u64 btw;
w += nhge->weight;
- upper_bound = DIV_ROUND_CLOSEST(res_table->num_nh_buckets * w,
- total);
+ btw = ((u64)res_table->num_nh_buckets) * w;
+ upper_bound = DIV_ROUND_CLOSEST_ULL(btw, total);
nhge->res.wants_buckets = upper_bound - prev_upper_bound;
prev_upper_bound = upper_bound;
@@ -1737,8 +1745,8 @@ static void replace_nexthop_grp_res(struct nh_group *oldg,
static void nh_hthr_group_rebalance(struct nh_group *nhg)
{
- int total = 0;
- int w = 0;
+ u32 total = 0;
+ u32 w = 0;
int i;
for (i = 0; i < nhg->num_nh; ++i)
@@ -1746,7 +1754,7 @@ static void nh_hthr_group_rebalance(struct nh_group *nhg)
for (i = 0; i < nhg->num_nh; ++i) {
struct nh_grp_entry *nhge = &nhg->nh_entries[i];
- int upper_bound;
+ u32 upper_bound;
w += nhge->weight;
upper_bound = DIV_ROUND_CLOSEST_ULL((u64)w << 31, total) - 1;
@@ -2492,7 +2500,8 @@ static struct nexthop *nexthop_create_group(struct net *net,
nhg->has_v4 = true;
nhg->nh_entries[i].nh = nhe;
- nhg->nh_entries[i].weight = entry[i].weight + 1;
+ nhg->nh_entries[i].weight = nexthop_grp_weight(&entry[i]);
+
list_add(&nhg->nh_entries[i].nh_list, &nhe->grp_list);
nhg->nh_entries[i].nh_parent = nh;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0579/1887] drm/amd/display: Add NULL test for timing generator in dcn21_set_pipe()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (577 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0578/1887] net: nexthop: Increase weight to u16 Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0580/1887] drm/amd/display: Fix panel_cntl could be null in dcn21_set_backlight_level() Greg Kroah-Hartman
` (419 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yongqiang Sun, Anthony Koo,
Rodrigo Siqueira, Aurabindo Pillai, Srinivasan Shanmugam,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit 66951d98d9bf45ba25acf37fe0747253fafdf298 ]
In "u32 otg_inst = pipe_ctx->stream_res.tg->inst;"
pipe_ctx->stream_res.tg could be NULL, it is relying on the caller to
ensure the tg is not NULL.
Fixes: 474ac4a875ca ("drm/amd/display: Implement some asic specific abm call backs.")
Cc: Yongqiang Sun <yongqiang.sun@amd.com>
Cc: Anthony Koo <Anthony.Koo@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
index 69cc192a7e719..13340ea84e7d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
@@ -182,17 +182,22 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
{
struct abm *abm = pipe_ctx->stream_res.abm;
- uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
+ struct timing_generator *tg = pipe_ctx->stream_res.tg;
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
+ uint32_t otg_inst;
+
+ if (!abm || !tg || !panel_cntl)
+ return;
+
+ otg_inst = tg->inst;
if (dmcu) {
dce110_set_pipe(pipe_ctx);
return;
}
- if (abm && panel_cntl)
- dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+ dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
}
bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0580/1887] drm/amd/display: Fix panel_cntl could be null in dcn21_set_backlight_level()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (578 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0579/1887] drm/amd/display: Add NULL test for timing generator in dcn21_set_pipe() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0581/1887] net/sched: flower: Fix chain template offload Greg Kroah-Hartman
` (418 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yongqiang Sun, Anthony Koo,
Rodrigo Siqueira, Aurabindo Pillai, Srinivasan Shanmugam,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit e96fddb32931d007db12b1fce9b5e8e4c080401b ]
'panel_cntl' structure used to control the display panel could be null,
dereferencing it could lead to a null pointer access.
Fixes the below:
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn21/dcn21_hwseq.c:269 dcn21_set_backlight_level() error: we previously assumed 'panel_cntl' could be null (see line 250)
Fixes: 474ac4a875ca ("drm/amd/display: Implement some asic specific abm call backs.")
Cc: Yongqiang Sun <yongqiang.sun@amd.com>
Cc: Anthony Koo <Anthony.Koo@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
index 13340ea84e7d0..5910cde0408d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
@@ -207,16 +207,21 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
union dmub_rb_cmd cmd;
struct dc_context *dc = pipe_ctx->stream->ctx;
struct abm *abm = pipe_ctx->stream_res.abm;
- uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
+ struct timing_generator *tg = pipe_ctx->stream_res.tg;
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
+ uint32_t otg_inst;
+
+ if (!abm || !tg || !panel_cntl)
+ return false;
+
+ otg_inst = tg->inst;
if (dc->dc->res_pool->dmcu) {
dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp);
return true;
}
- if (abm && panel_cntl)
- dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
+ dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst);
memset(&cmd, 0, sizeof(cmd));
cmd.abm_set_backlight.header.type = DMUB_CMD__ABM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0581/1887] net/sched: flower: Fix chain template offload
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (579 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0580/1887] drm/amd/display: Fix panel_cntl could be null in dcn21_set_backlight_level() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0582/1887] arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD Greg Kroah-Hartman
` (417 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, David S. Miller,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 32f2a0afa95fae0d1ceec2ff06e0e816939964b8 ]
When a qdisc is deleted from a net device the stack instructs the
underlying driver to remove its flow offload callback from the
associated filter block using the 'FLOW_BLOCK_UNBIND' command. The stack
then continues to replay the removal of the filters in the block for
this driver by iterating over the chains in the block and invoking the
'reoffload' operation of the classifier being used. In turn, the
classifier in its 'reoffload' operation prepares and emits a
'FLOW_CLS_DESTROY' command for each filter.
However, the stack does not do the same for chain templates and the
underlying driver never receives a 'FLOW_CLS_TMPLT_DESTROY' command when
a qdisc is deleted. This results in a memory leak [1] which can be
reproduced using [2].
Fix by introducing a 'tmplt_reoffload' operation and have the stack
invoke it with the appropriate arguments as part of the replay.
Implement the operation in the sole classifier that supports chain
templates (flower) by emitting the 'FLOW_CLS_TMPLT_{CREATE,DESTROY}'
command based on whether a flow offload callback is being bound to a
filter block or being unbound from one.
As far as I can tell, the issue happens since cited commit which
reordered tcf_block_offload_unbind() before tcf_block_flush_all_chains()
in __tcf_block_put(). The order cannot be reversed as the filter block
is expected to be freed after flushing all the chains.
[1]
unreferenced object 0xffff888107e28800 (size 2048):
comm "tc", pid 1079, jiffies 4294958525 (age 3074.287s)
hex dump (first 32 bytes):
b1 a6 7c 11 81 88 ff ff e0 5b b3 10 81 88 ff ff ..|......[......
01 00 00 00 00 00 00 00 e0 aa b0 84 ff ff ff ff ................
backtrace:
[<ffffffff81c06a68>] __kmem_cache_alloc_node+0x1e8/0x320
[<ffffffff81ab374e>] __kmalloc+0x4e/0x90
[<ffffffff832aec6d>] mlxsw_sp_acl_ruleset_get+0x34d/0x7a0
[<ffffffff832bc195>] mlxsw_sp_flower_tmplt_create+0x145/0x180
[<ffffffff832b2e1a>] mlxsw_sp_flow_block_cb+0x1ea/0x280
[<ffffffff83a10613>] tc_setup_cb_call+0x183/0x340
[<ffffffff83a9f85a>] fl_tmplt_create+0x3da/0x4c0
[<ffffffff83a22435>] tc_ctl_chain+0xa15/0x1170
[<ffffffff838a863c>] rtnetlink_rcv_msg+0x3cc/0xed0
[<ffffffff83ac87f0>] netlink_rcv_skb+0x170/0x440
[<ffffffff83ac6270>] netlink_unicast+0x540/0x820
[<ffffffff83ac6e28>] netlink_sendmsg+0x8d8/0xda0
[<ffffffff83793def>] ____sys_sendmsg+0x30f/0xa80
[<ffffffff8379d29a>] ___sys_sendmsg+0x13a/0x1e0
[<ffffffff8379d50c>] __sys_sendmsg+0x11c/0x1f0
[<ffffffff843b9ce0>] do_syscall_64+0x40/0xe0
unreferenced object 0xffff88816d2c0400 (size 1024):
comm "tc", pid 1079, jiffies 4294958525 (age 3074.287s)
hex dump (first 32 bytes):
40 00 00 00 00 00 00 00 57 f6 38 be 00 00 00 00 @.......W.8.....
10 04 2c 6d 81 88 ff ff 10 04 2c 6d 81 88 ff ff ..,m......,m....
backtrace:
[<ffffffff81c06a68>] __kmem_cache_alloc_node+0x1e8/0x320
[<ffffffff81ab36c1>] __kmalloc_node+0x51/0x90
[<ffffffff81a8ed96>] kvmalloc_node+0xa6/0x1f0
[<ffffffff82827d03>] bucket_table_alloc.isra.0+0x83/0x460
[<ffffffff82828d2b>] rhashtable_init+0x43b/0x7c0
[<ffffffff832aed48>] mlxsw_sp_acl_ruleset_get+0x428/0x7a0
[<ffffffff832bc195>] mlxsw_sp_flower_tmplt_create+0x145/0x180
[<ffffffff832b2e1a>] mlxsw_sp_flow_block_cb+0x1ea/0x280
[<ffffffff83a10613>] tc_setup_cb_call+0x183/0x340
[<ffffffff83a9f85a>] fl_tmplt_create+0x3da/0x4c0
[<ffffffff83a22435>] tc_ctl_chain+0xa15/0x1170
[<ffffffff838a863c>] rtnetlink_rcv_msg+0x3cc/0xed0
[<ffffffff83ac87f0>] netlink_rcv_skb+0x170/0x440
[<ffffffff83ac6270>] netlink_unicast+0x540/0x820
[<ffffffff83ac6e28>] netlink_sendmsg+0x8d8/0xda0
[<ffffffff83793def>] ____sys_sendmsg+0x30f/0xa80
[2]
# tc qdisc add dev swp1 clsact
# tc chain add dev swp1 ingress proto ip chain 1 flower dst_ip 0.0.0.0/32
# tc qdisc del dev swp1 clsact
# devlink dev reload pci/0000:06:00.0
Fixes: bbf73830cd48 ("net: sched: traverse chains in block with tcf_get_next_chain()")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sch_generic.h | 4 ++++
net/sched/cls_api.c | 9 ++++++++-
net/sched/cls_flower.c | 23 +++++++++++++++++++++++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 7ec1f5aa6adaf..b694d27f41714 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -378,6 +378,10 @@ struct tcf_proto_ops {
struct nlattr **tca,
struct netlink_ext_ack *extack);
void (*tmplt_destroy)(void *tmplt_priv);
+ void (*tmplt_reoffload)(struct tcf_chain *chain,
+ bool add,
+ flow_setup_cb_t *cb,
+ void *cb_priv);
/* rtnetlink specific */
int (*dump)(struct net*, struct tcf_proto*, void *,
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index dbaf6e72aa2da..9ee545b0364ad 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1431,6 +1431,9 @@ tcf_block_playback_offloads(struct tcf_block *block, flow_setup_cb_t *cb,
chain_prev = chain,
chain = __tcf_get_next_chain(block, chain),
tcf_chain_put(chain_prev)) {
+ if (chain->tmplt_ops && add)
+ chain->tmplt_ops->tmplt_reoffload(chain, true, cb,
+ cb_priv);
for (tp = __tcf_get_next_proto(chain, NULL); tp;
tp_prev = tp,
tp = __tcf_get_next_proto(chain, tp),
@@ -1446,6 +1449,9 @@ tcf_block_playback_offloads(struct tcf_block *block, flow_setup_cb_t *cb,
goto err_playback_remove;
}
}
+ if (chain->tmplt_ops && !add)
+ chain->tmplt_ops->tmplt_reoffload(chain, false, cb,
+ cb_priv);
}
return 0;
@@ -2861,7 +2867,8 @@ static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net,
ops = tcf_proto_lookup_ops(name, true, extack);
if (IS_ERR(ops))
return PTR_ERR(ops);
- if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) {
+ if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump ||
+ !ops->tmplt_reoffload) {
NL_SET_ERR_MSG(extack, "Chain templates are not supported with specified classifier");
module_put(ops->owner);
return -EOPNOTSUPP;
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index a40a9e84c75f4..42234a0101e78 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -2596,6 +2596,28 @@ static void fl_tmplt_destroy(void *tmplt_priv)
kfree(tmplt);
}
+static void fl_tmplt_reoffload(struct tcf_chain *chain, bool add,
+ flow_setup_cb_t *cb, void *cb_priv)
+{
+ struct fl_flow_tmplt *tmplt = chain->tmplt_priv;
+ struct flow_cls_offload cls_flower = {};
+
+ cls_flower.rule = flow_rule_alloc(0);
+ if (!cls_flower.rule)
+ return;
+
+ cls_flower.common.chain_index = chain->index;
+ cls_flower.command = add ? FLOW_CLS_TMPLT_CREATE :
+ FLOW_CLS_TMPLT_DESTROY;
+ cls_flower.cookie = (unsigned long) tmplt;
+ cls_flower.rule->match.dissector = &tmplt->dissector;
+ cls_flower.rule->match.mask = &tmplt->mask;
+ cls_flower.rule->match.key = &tmplt->dummy_key;
+
+ cb(TC_SETUP_CLSFLOWER, &cls_flower, cb_priv);
+ kfree(cls_flower.rule);
+}
+
static int fl_dump_key_val(struct sk_buff *skb,
void *val, int val_type,
void *mask, int mask_type, int len)
@@ -3452,6 +3474,7 @@ static struct tcf_proto_ops cls_fl_ops __read_mostly = {
.bind_class = fl_bind_class,
.tmplt_create = fl_tmplt_create,
.tmplt_destroy = fl_tmplt_destroy,
+ .tmplt_reoffload = fl_tmplt_reoffload,
.tmplt_dump = fl_tmplt_dump,
.owner = THIS_MODULE,
.flags = TCF_PROTO_OPS_DOIT_UNLOCKED,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0582/1887] arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (580 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0581/1887] net/sched: flower: Fix chain template offload Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0583/1887] rxrpc: Fix delayed ACKs to not set the reference serial number Greg Kroah-Hartman
` (416 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Rutland, Catalin Marinas,
James Morse, Rob Herring, Will Deacon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <mark.rutland@arm.com>
[ Upstream commit 832dd634bd1b4e3bbe9f10b9c9ba5db6f6f2b97f ]
Currently the ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD workaround isn't
quite right, as it is supposed to be applied after the last explicit
memory access, but is immediately followed by an LDR.
The ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD workaround is used to
handle Cortex-A520 erratum 2966298 and Cortex-A510 erratum 3117295,
which are described in:
* https://developer.arm.com/documentation/SDEN2444153/0600/?lang=en
* https://developer.arm.com/documentation/SDEN1873361/1600/?lang=en
In both cases the workaround is described as:
| If pagetable isolation is disabled, the context switch logic in the
| kernel can be updated to execute the following sequence on affected
| cores before exiting to EL0, and after all explicit memory accesses:
|
| 1. A non-shareable TLBI to any context and/or address, including
| unused contexts or addresses, such as a `TLBI VALE1 Xzr`.
|
| 2. A DSB NSH to guarantee completion of the TLBI.
The important part being that the TLBI+DSB must be placed "after all
explicit memory accesses".
Unfortunately, as-implemented, the TLBI+DSB is immediately followed by
an LDR, as we have:
| alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
| tlbi vale1, xzr
| dsb nsh
| alternative_else_nop_endif
| alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
| ldr lr, [sp, #S_LR]
| add sp, sp, #PT_REGS_SIZE // restore sp
| eret
| alternative_else_nop_endif
|
| [ ... KPTI exception return path ... ]
This patch fixes this by reworking the logic to place the TLBI+DSB
immediately before the ERET, after all explicit memory accesses.
The ERET is currently in a separate alternative block, and alternatives
cannot be nested. To account for this, the alternative block for
ARM64_UNMAP_KERNEL_AT_EL0 is replaced with a single alternative branch
to skip the KPTI logic, with the new shape of the logic being:
| alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0
| [ ... KPTI exception return path ... ]
| .L_skip_tramp_exit_\@:
|
| ldr lr, [sp, #S_LR]
| add sp, sp, #PT_REGS_SIZE // restore sp
|
| alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
| tlbi vale1, xzr
| dsb nsh
| alternative_else_nop_endif
| eret
The new structure means that the workaround is only applied when KPTI is
not in use; this is fine as noted in the documented implications of the
erratum:
| Pagetable isolation between EL0 and higher level ELs prevents the
| issue from occurring.
... and as per the workaround description quoted above, the workaround
is only necessary "If pagetable isolation is disabled".
Fixes: 471470bc7052 ("arm64: errata: Add Cortex-A520 speculative unprivileged load workaround")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20240116110221.420467-2-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/entry.S | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 4b4a9aa76e1a3..6df98546605d4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -419,16 +419,9 @@ alternative_else_nop_endif
ldp x28, x29, [sp, #16 * 14]
.if \el == 0
-alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
- tlbi vale1, xzr
- dsb nsh
-alternative_else_nop_endif
-alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
- ldr lr, [sp, #S_LR]
- add sp, sp, #PT_REGS_SIZE // restore sp
- eret
-alternative_else_nop_endif
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+ alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0
+
bne 4f
msr far_el1, x29
tramp_alias x30, tramp_exit_native, x29
@@ -436,7 +429,18 @@ alternative_else_nop_endif
4:
tramp_alias x30, tramp_exit_compat, x29
br x30
+
+.L_skip_tramp_exit_\@:
#endif
+ ldr lr, [sp, #S_LR]
+ add sp, sp, #PT_REGS_SIZE // restore sp
+
+ /* This must be after the last explicit memory access */
+alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+ tlbi vale1, xzr
+ dsb nsh
+alternative_else_nop_endif
+ eret
.else
ldr lr, [sp, #S_LR]
add sp, sp, #PT_REGS_SIZE // restore sp
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0583/1887] rxrpc: Fix delayed ACKs to not set the reference serial number
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (581 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0582/1887] arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0584/1887] net: stmmac: protect updates of 64-bit statistics counters Greg Kroah-Hartman
` (415 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Marc Dionne,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-afs, netdev, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit e7870cf13d20f56bfc19f9c3e89707c69cf104ef ]
Fix the construction of delayed ACKs to not set the reference serial number
as they can't be used as an RTT reference.
Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: linux-afs@lists.infradead.org
cc: netdev@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rxrpc/output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 08c117bc083ec..3d9032fae9d91 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -87,7 +87,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
return 0;
/* Barrier against rxrpc_input_data(). */
- serial = call->ackr_serial;
+ serial = reason == RXRPC_ACK_DELAY ? 0 : call->ackr_serial;
hard_ack = READ_ONCE(call->rx_hard_ack);
top = smp_load_acquire(&call->rx_top);
*_hard_ack = hard_ack;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0584/1887] net: stmmac: protect updates of 64-bit statistics counters
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (582 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0583/1887] rxrpc: Fix delayed ACKs to not set the reference serial number Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0585/1887] net/sched: act_mirred: use the backlog for mirred ingress Greg Kroah-Hartman
` (414 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Petr Tesarik, Jisheng Zhang,
David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Tesarik <petr@tesarici.cz>
[ Upstream commit 38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8 ]
As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
u64_stats_sync must ensure mutual exclusion, or one seqcount update could
be lost on 32-bit platforms, thus blocking readers forever. Such lockups
have been observed in real world after stmmac_xmit() on one CPU raced with
stmmac_napi_poll_tx() on another CPU.
To fix the issue without introducing a new lock, split the statics into
three parts:
1. fields updated only under the tx queue lock,
2. fields updated only during NAPI poll,
3. fields updated only from interrupt context,
Updates to fields in the first two groups are already serialized through
other locks. It is sufficient to split the existing struct u64_stats_sync
so that each group has its own.
Note that tx_set_ic_bit is updated from both contexts. Split this counter
so that each context gets its own, and calculate their sum to get the total
value in stmmac_get_ethtool_stats().
For the third group, multiple interrupts may be processed by different CPUs
at the same time, but interrupts on the same CPU will not nest. Move fields
from this group to a newly created per-cpu struct stmmac_pcpu_stats.
Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn@torres.zugschlus.de/t/
Cc: stable@vger.kernel.org
Signed-off-by: Petr Tesarik <petr@tesarici.cz>
Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 56 +++++---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 15 +-
.../net/ethernet/stmicro/stmmac/dwmac4_lib.c | 15 +-
.../net/ethernet/stmicro/stmmac/dwmac_lib.c | 15 +-
.../ethernet/stmicro/stmmac/dwxgmac2_dma.c | 15 +-
.../ethernet/stmicro/stmmac/stmmac_ethtool.c | 129 +++++++++++------
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 133 +++++++++---------
7 files changed, 221 insertions(+), 157 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 671ada52bf664..df4ece1966548 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -58,28 +58,51 @@
#undef FRAME_FILTER_DEBUG
/* #define FRAME_FILTER_DEBUG */
+struct stmmac_q_tx_stats {
+ u64_stats_t tx_bytes;
+ u64_stats_t tx_set_ic_bit;
+ u64_stats_t tx_tso_frames;
+ u64_stats_t tx_tso_nfrags;
+};
+
+struct stmmac_napi_tx_stats {
+ u64_stats_t tx_packets;
+ u64_stats_t tx_pkt_n;
+ u64_stats_t poll;
+ u64_stats_t tx_clean;
+ u64_stats_t tx_set_ic_bit;
+};
+
struct stmmac_txq_stats {
- u64 tx_bytes;
- u64 tx_packets;
- u64 tx_pkt_n;
- u64 tx_normal_irq_n;
- u64 napi_poll;
- u64 tx_clean;
- u64 tx_set_ic_bit;
- u64 tx_tso_frames;
- u64 tx_tso_nfrags;
- struct u64_stats_sync syncp;
+ /* Updates protected by tx queue lock. */
+ struct u64_stats_sync q_syncp;
+ struct stmmac_q_tx_stats q;
+
+ /* Updates protected by NAPI poll logic. */
+ struct u64_stats_sync napi_syncp;
+ struct stmmac_napi_tx_stats napi;
} ____cacheline_aligned_in_smp;
+struct stmmac_napi_rx_stats {
+ u64_stats_t rx_bytes;
+ u64_stats_t rx_packets;
+ u64_stats_t rx_pkt_n;
+ u64_stats_t poll;
+};
+
struct stmmac_rxq_stats {
- u64 rx_bytes;
- u64 rx_packets;
- u64 rx_pkt_n;
- u64 rx_normal_irq_n;
- u64 napi_poll;
- struct u64_stats_sync syncp;
+ /* Updates protected by NAPI poll logic. */
+ struct u64_stats_sync napi_syncp;
+ struct stmmac_napi_rx_stats napi;
} ____cacheline_aligned_in_smp;
+/* Updates on each CPU protected by not allowing nested irqs. */
+struct stmmac_pcpu_stats {
+ struct u64_stats_sync syncp;
+ u64_stats_t rx_normal_irq_n[MTL_MAX_TX_QUEUES];
+ u64_stats_t tx_normal_irq_n[MTL_MAX_RX_QUEUES];
+};
+
/* Extra statistic and debug information exposed by ethtool */
struct stmmac_extra_stats {
/* Transmit errors */
@@ -204,6 +227,7 @@ struct stmmac_extra_stats {
/* per queue statistics */
struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
+ struct stmmac_pcpu_stats __percpu *pcpu_stats;
unsigned long rx_dropped;
unsigned long rx_errors;
unsigned long tx_dropped;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index ddf6fa00cedd5..b09ea85641418 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -440,8 +440,7 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
struct stmmac_extra_stats *x, u32 chan,
u32 dir)
{
- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
int ret = 0;
u32 v;
@@ -454,9 +453,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
if (v & EMAC_TX_INT) {
ret |= handle_tx;
- u64_stats_update_begin(&txq_stats->syncp);
- txq_stats->tx_normal_irq_n++;
- u64_stats_update_end(&txq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
}
if (v & EMAC_TX_DMA_STOP_INT)
@@ -478,9 +477,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
if (v & EMAC_RX_INT) {
ret |= handle_rx;
- u64_stats_update_begin(&rxq_stats->syncp);
- rxq_stats->rx_normal_irq_n++;
- u64_stats_update_end(&rxq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
}
if (v & EMAC_RX_BUF_UA_INT)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index 9470d3fd2dede..0d185e54eb7e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -171,8 +171,7 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
int ret = 0;
if (dir == DMA_DIR_RX)
@@ -201,15 +200,15 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
}
/* TX/RX NORMAL interrupts */
if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
- u64_stats_update_begin(&rxq_stats->syncp);
- rxq_stats->rx_normal_irq_n++;
- u64_stats_update_end(&rxq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_rx;
}
if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
- u64_stats_update_begin(&txq_stats->syncp);
- txq_stats->tx_normal_irq_n++;
- u64_stats_update_end(&txq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_tx;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 7907d62d34375..85e18f9a22f92 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -162,8 +162,7 @@ static void show_rx_process_state(unsigned int status)
int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_extra_stats *x, u32 chan, u32 dir)
{
- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
int ret = 0;
/* read the status register (CSR5) */
u32 intr_status = readl(ioaddr + DMA_STATUS);
@@ -215,16 +214,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 value = readl(ioaddr + DMA_INTR_ENA);
/* to schedule NAPI on real RIE event. */
if (likely(value & DMA_INTR_ENA_RIE)) {
- u64_stats_update_begin(&rxq_stats->syncp);
- rxq_stats->rx_normal_irq_n++;
- u64_stats_update_end(&rxq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_rx;
}
}
if (likely(intr_status & DMA_STATUS_TI)) {
- u64_stats_update_begin(&txq_stats->syncp);
- txq_stats->tx_normal_irq_n++;
- u64_stats_update_end(&txq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_tx;
}
if (unlikely(intr_status & DMA_STATUS_ERI))
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 1e5ffc0d81c3a..8d11c6472d8da 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -333,8 +333,7 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
struct stmmac_extra_stats *x, u32 chan,
u32 dir)
{
- struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
- struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+ struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
int ret = 0;
@@ -363,15 +362,15 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
/* TX/RX NORMAL interrupts */
if (likely(intr_status & XGMAC_NIS)) {
if (likely(intr_status & XGMAC_RI)) {
- u64_stats_update_begin(&rxq_stats->syncp);
- rxq_stats->rx_normal_irq_n++;
- u64_stats_update_end(&rxq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_rx;
}
if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
- u64_stats_update_begin(&txq_stats->syncp);
- txq_stats->tx_normal_irq_n++;
- u64_stats_update_end(&txq_stats->syncp);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+ u64_stats_update_end(&stats->syncp);
ret |= handle_tx;
}
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 2e67e9abe1b7c..4d40e0c8c1b36 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -546,44 +546,79 @@ stmmac_set_pauseparam(struct net_device *netdev,
}
}
+static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q)
+{
+ u64 total;
+ int cpu;
+
+ total = 0;
+ for_each_possible_cpu(cpu) {
+ struct stmmac_pcpu_stats *pcpu;
+ unsigned int start;
+ u64 irq_n;
+
+ pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
+ do {
+ start = u64_stats_fetch_begin(&pcpu->syncp);
+ irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]);
+ } while (u64_stats_fetch_retry(&pcpu->syncp, start));
+ total += irq_n;
+ }
+ return total;
+}
+
+static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q)
+{
+ u64 total;
+ int cpu;
+
+ total = 0;
+ for_each_possible_cpu(cpu) {
+ struct stmmac_pcpu_stats *pcpu;
+ unsigned int start;
+ u64 irq_n;
+
+ pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
+ do {
+ start = u64_stats_fetch_begin(&pcpu->syncp);
+ irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]);
+ } while (u64_stats_fetch_retry(&pcpu->syncp, start));
+ total += irq_n;
+ }
+ return total;
+}
+
static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
{
u32 tx_cnt = priv->plat->tx_queues_to_use;
u32 rx_cnt = priv->plat->rx_queues_to_use;
unsigned int start;
- int q, stat;
- char *p;
+ int q;
for (q = 0; q < tx_cnt; q++) {
struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
- struct stmmac_txq_stats snapshot;
+ u64 pkt_n;
do {
- start = u64_stats_fetch_begin(&txq_stats->syncp);
- snapshot = *txq_stats;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+ pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n);
+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
- p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
- for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
- *data++ = (*(u64 *)p);
- p += sizeof(u64);
- }
+ *data++ = pkt_n;
+ *data++ = stmmac_get_tx_normal_irq_n(priv, q);
}
for (q = 0; q < rx_cnt; q++) {
struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
- struct stmmac_rxq_stats snapshot;
+ u64 pkt_n;
do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
- snapshot = *rxq_stats;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+ pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n);
+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
- p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
- for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
- *data++ = (*(u64 *)p);
- p += sizeof(u64);
- }
+ *data++ = pkt_n;
+ *data++ = stmmac_get_rx_normal_irq_n(priv, q);
}
}
@@ -642,39 +677,49 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
pos = j;
for (i = 0; i < rx_queues_count; i++) {
struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i];
- struct stmmac_rxq_stats snapshot;
+ struct stmmac_napi_rx_stats snapshot;
+ u64 n_irq;
j = pos;
do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
- snapshot = *rxq_stats;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
-
- data[j++] += snapshot.rx_pkt_n;
- data[j++] += snapshot.rx_normal_irq_n;
- normal_irq_n += snapshot.rx_normal_irq_n;
- napi_poll += snapshot.napi_poll;
+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+ snapshot = rxq_stats->napi;
+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
+
+ data[j++] += u64_stats_read(&snapshot.rx_pkt_n);
+ n_irq = stmmac_get_rx_normal_irq_n(priv, i);
+ data[j++] += n_irq;
+ normal_irq_n += n_irq;
+ napi_poll += u64_stats_read(&snapshot.poll);
}
pos = j;
for (i = 0; i < tx_queues_count; i++) {
struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i];
- struct stmmac_txq_stats snapshot;
+ struct stmmac_napi_tx_stats napi_snapshot;
+ struct stmmac_q_tx_stats q_snapshot;
+ u64 n_irq;
j = pos;
do {
- start = u64_stats_fetch_begin(&txq_stats->syncp);
- snapshot = *txq_stats;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
-
- data[j++] += snapshot.tx_pkt_n;
- data[j++] += snapshot.tx_normal_irq_n;
- normal_irq_n += snapshot.tx_normal_irq_n;
- data[j++] += snapshot.tx_clean;
- data[j++] += snapshot.tx_set_ic_bit;
- data[j++] += snapshot.tx_tso_frames;
- data[j++] += snapshot.tx_tso_nfrags;
- napi_poll += snapshot.napi_poll;
+ start = u64_stats_fetch_begin(&txq_stats->q_syncp);
+ q_snapshot = txq_stats->q;
+ } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
+ do {
+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+ napi_snapshot = txq_stats->napi;
+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
+
+ data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n);
+ n_irq = stmmac_get_tx_normal_irq_n(priv, i);
+ data[j++] += n_irq;
+ normal_irq_n += n_irq;
+ data[j++] += u64_stats_read(&napi_snapshot.tx_clean);
+ data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) +
+ u64_stats_read(&napi_snapshot.tx_set_ic_bit);
+ data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames);
+ data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags);
+ napi_poll += u64_stats_read(&napi_snapshot.poll);
}
normal_irq_n += priv->xstats.rx_early_irq;
data[j++] = normal_irq_n;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5ca6157208864..f72367ecdb879 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2433,7 +2433,6 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
struct xdp_desc xdp_desc;
bool work_done = true;
u32 tx_set_ic_bit = 0;
- unsigned long flags;
/* Avoids TX time-out as we are sharing with slow path */
txq_trans_cond_update(nq);
@@ -2506,9 +2505,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
entry = tx_q->cur_tx;
}
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->tx_set_ic_bit += tx_set_ic_bit;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_update_begin(&txq_stats->napi_syncp);
+ u64_stats_add(&txq_stats->napi.tx_set_ic_bit, tx_set_ic_bit);
+ u64_stats_update_end(&txq_stats->napi_syncp);
if (tx_desc) {
stmmac_flush_tx_descriptors(priv, queue);
@@ -2552,7 +2551,6 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
unsigned int bytes_compl = 0, pkts_compl = 0;
unsigned int entry, xmits = 0, count = 0;
u32 tx_packets = 0, tx_errors = 0;
- unsigned long flags;
__netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
@@ -2708,11 +2706,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
if (tx_q->dirty_tx != tx_q->cur_tx)
stmmac_tx_timer_arm(priv, queue);
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->tx_packets += tx_packets;
- txq_stats->tx_pkt_n += tx_packets;
- txq_stats->tx_clean++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_update_begin(&txq_stats->napi_syncp);
+ u64_stats_add(&txq_stats->napi.tx_packets, tx_packets);
+ u64_stats_add(&txq_stats->napi.tx_pkt_n, tx_packets);
+ u64_stats_inc(&txq_stats->napi.tx_clean);
+ u64_stats_update_end(&txq_stats->napi_syncp);
priv->xstats.tx_errors += tx_errors;
@@ -4101,7 +4099,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
bool has_vlan, set_ic;
dma_addr_t tso_des, des;
u8 proto_hdr_len, hdr;
- unsigned long flags;
u32 pay_len, mss;
int i;
@@ -4278,13 +4275,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
}
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->tx_bytes += skb->len;
- txq_stats->tx_tso_frames++;
- txq_stats->tx_tso_nfrags += nfrags;
+ u64_stats_update_begin(&txq_stats->q_syncp);
+ u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
+ u64_stats_inc(&txq_stats->q.tx_tso_frames);
+ u64_stats_add(&txq_stats->q.tx_tso_nfrags, nfrags);
if (set_ic)
- txq_stats->tx_set_ic_bit++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+ u64_stats_update_end(&txq_stats->q_syncp);
if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type);
@@ -4361,7 +4358,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
struct stmmac_tx_queue *tx_q;
bool has_vlan, set_ic;
int entry, first_tx;
- unsigned long flags;
dma_addr_t des;
tx_q = &priv->dma_conf.tx_queue[queue];
@@ -4517,11 +4513,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
}
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->tx_bytes += skb->len;
+ u64_stats_update_begin(&txq_stats->q_syncp);
+ u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
if (set_ic)
- txq_stats->tx_set_ic_bit++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+ u64_stats_update_end(&txq_stats->q_syncp);
if (priv->sarc_type)
stmmac_set_desc_sarc(priv, first, priv->sarc_type);
@@ -4785,12 +4781,11 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
set_ic = false;
if (set_ic) {
- unsigned long flags;
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, tx_desc);
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->tx_set_ic_bit++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_update_begin(&txq_stats->q_syncp);
+ u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+ u64_stats_update_end(&txq_stats->q_syncp);
}
stmmac_enable_dma_transmission(priv, priv->ioaddr);
@@ -4950,7 +4945,6 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
unsigned int len = xdp->data_end - xdp->data;
enum pkt_hash_types hash_type;
int coe = priv->hw->rx_csum;
- unsigned long flags;
struct sk_buff *skb;
u32 hash;
@@ -4975,10 +4969,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
skb_record_rx_queue(skb, queue);
napi_gro_receive(&ch->rxtx_napi, skb);
- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
- rxq_stats->rx_pkt_n++;
- rxq_stats->rx_bytes += len;
- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+ u64_stats_update_begin(&rxq_stats->napi_syncp);
+ u64_stats_inc(&rxq_stats->napi.rx_pkt_n);
+ u64_stats_add(&rxq_stats->napi.rx_bytes, len);
+ u64_stats_update_end(&rxq_stats->napi_syncp);
}
static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
@@ -5050,7 +5044,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
unsigned int desc_size;
struct bpf_prog *prog;
bool failure = false;
- unsigned long flags;
int xdp_status = 0;
int status = 0;
@@ -5204,9 +5197,9 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_finalize_xdp_rx(priv, xdp_status);
- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
- rxq_stats->rx_pkt_n += count;
- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+ u64_stats_update_begin(&rxq_stats->napi_syncp);
+ u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
+ u64_stats_update_end(&rxq_stats->napi_syncp);
priv->xstats.rx_dropped += rx_dropped;
priv->xstats.rx_errors += rx_errors;
@@ -5244,7 +5237,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
unsigned int desc_size;
struct sk_buff *skb = NULL;
struct stmmac_xdp_buff ctx;
- unsigned long flags;
int xdp_status = 0;
int bufsz;
@@ -5494,11 +5486,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_rx_refill(priv, queue);
- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
- rxq_stats->rx_packets += rx_packets;
- rxq_stats->rx_bytes += rx_bytes;
- rxq_stats->rx_pkt_n += count;
- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+ u64_stats_update_begin(&rxq_stats->napi_syncp);
+ u64_stats_add(&rxq_stats->napi.rx_packets, rx_packets);
+ u64_stats_add(&rxq_stats->napi.rx_bytes, rx_bytes);
+ u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
+ u64_stats_update_end(&rxq_stats->napi_syncp);
priv->xstats.rx_dropped += rx_dropped;
priv->xstats.rx_errors += rx_errors;
@@ -5513,13 +5505,12 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget)
struct stmmac_priv *priv = ch->priv_data;
struct stmmac_rxq_stats *rxq_stats;
u32 chan = ch->index;
- unsigned long flags;
int work_done;
rxq_stats = &priv->xstats.rxq_stats[chan];
- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
- rxq_stats->napi_poll++;
- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+ u64_stats_update_begin(&rxq_stats->napi_syncp);
+ u64_stats_inc(&rxq_stats->napi.poll);
+ u64_stats_update_end(&rxq_stats->napi_syncp);
work_done = stmmac_rx(priv, budget, chan);
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -5540,13 +5531,12 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget)
struct stmmac_priv *priv = ch->priv_data;
struct stmmac_txq_stats *txq_stats;
u32 chan = ch->index;
- unsigned long flags;
int work_done;
txq_stats = &priv->xstats.txq_stats[chan];
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->napi_poll++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_update_begin(&txq_stats->napi_syncp);
+ u64_stats_inc(&txq_stats->napi.poll);
+ u64_stats_update_end(&txq_stats->napi_syncp);
work_done = stmmac_tx_clean(priv, budget, chan);
work_done = min(work_done, budget);
@@ -5571,17 +5561,16 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget)
struct stmmac_rxq_stats *rxq_stats;
struct stmmac_txq_stats *txq_stats;
u32 chan = ch->index;
- unsigned long flags;
rxq_stats = &priv->xstats.rxq_stats[chan];
- flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
- rxq_stats->napi_poll++;
- u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+ u64_stats_update_begin(&rxq_stats->napi_syncp);
+ u64_stats_inc(&rxq_stats->napi.poll);
+ u64_stats_update_end(&rxq_stats->napi_syncp);
txq_stats = &priv->xstats.txq_stats[chan];
- flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
- txq_stats->napi_poll++;
- u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+ u64_stats_update_begin(&txq_stats->napi_syncp);
+ u64_stats_inc(&txq_stats->napi.poll);
+ u64_stats_update_end(&txq_stats->napi_syncp);
tx_done = stmmac_tx_clean(priv, budget, chan);
tx_done = min(tx_done, budget);
@@ -6843,10 +6832,13 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
u64 tx_bytes;
do {
- start = u64_stats_fetch_begin(&txq_stats->syncp);
- tx_packets = txq_stats->tx_packets;
- tx_bytes = txq_stats->tx_bytes;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ start = u64_stats_fetch_begin(&txq_stats->q_syncp);
+ tx_bytes = u64_stats_read(&txq_stats->q.tx_bytes);
+ } while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
+ do {
+ start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+ tx_packets = u64_stats_read(&txq_stats->napi.tx_packets);
+ } while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
stats->tx_packets += tx_packets;
stats->tx_bytes += tx_bytes;
@@ -6858,10 +6850,10 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
u64 rx_bytes;
do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
- rx_packets = rxq_stats->rx_packets;
- rx_bytes = rxq_stats->rx_bytes;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+ start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+ rx_packets = u64_stats_read(&rxq_stats->napi.rx_packets);
+ rx_bytes = u64_stats_read(&rxq_stats->napi.rx_bytes);
+ } while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
@@ -7225,9 +7217,16 @@ int stmmac_dvr_probe(struct device *device,
priv->dev = ndev;
for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
- u64_stats_init(&priv->xstats.rxq_stats[i].syncp);
- for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
- u64_stats_init(&priv->xstats.txq_stats[i].syncp);
+ u64_stats_init(&priv->xstats.rxq_stats[i].napi_syncp);
+ for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
+ u64_stats_init(&priv->xstats.txq_stats[i].q_syncp);
+ u64_stats_init(&priv->xstats.txq_stats[i].napi_syncp);
+ }
+
+ priv->xstats.pcpu_stats =
+ devm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats);
+ if (!priv->xstats.pcpu_stats)
+ return -ENOMEM;
stmmac_set_ethtool_ops(ndev);
priv->pause = pause;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0585/1887] net/sched: act_mirred: use the backlog for mirred ingress
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (583 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0584/1887] net: stmmac: protect updates of 64-bit statistics counters Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0586/1887] ASoC: qcom: Fix uninitialized pointer dmactl Greg Kroah-Hartman
` (413 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marcelo Ricardo Leitner,
Davide Caratti, Jakub Kicinski, Jamal Hadi Salim, David S. Miller,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 52f671db18823089a02f07efc04efdb2272ddc17 ]
The test Davide added in commit ca22da2fbd69 ("act_mirred: use the backlog
for nested calls to mirred ingress") hangs our testing VMs every 10 or so
runs, with the familiar tcp_v4_rcv -> tcp_v4_rcv deadlock reported by
lockdep.
The problem as previously described by Davide (see Link) is that
if we reverse flow of traffic with the redirect (egress -> ingress)
we may reach the same socket which generated the packet. And we may
still be holding its socket lock. The common solution to such deadlocks
is to put the packet in the Rx backlog, rather than run the Rx path
inline. Do that for all egress -> ingress reversals, not just once
we started to nest mirred calls.
In the past there was a concern that the backlog indirection will
lead to loss of error reporting / less accurate stats. But the current
workaround does not seem to address the issue.
Fixes: 53592b364001 ("net/sched: act_mirred: Implement ingress actions")
Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Suggested-by: Davide Caratti <dcaratti@redhat.com>
Link: https://lore.kernel.org/netdev/33dc43f587ec1388ba456b4915c75f02a8aae226.1663945716.git.dcaratti@redhat.com/
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_mirred.c | 14 +++++---------
.../testing/selftests/net/forwarding/tc_actions.sh | 3 ---
2 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index bbc34987bd09b..896bffd50aa8b 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -205,18 +205,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
return err;
}
-static bool is_mirred_nested(void)
-{
- return unlikely(__this_cpu_read(mirred_nest_level) > 1);
-}
-
-static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb)
+static int
+tcf_mirred_forward(bool at_ingress, bool want_ingress, struct sk_buff *skb)
{
int err;
if (!want_ingress)
err = tcf_dev_queue_xmit(skb, dev_queue_xmit);
- else if (is_mirred_nested())
+ else if (!at_ingress)
err = netif_rx(skb);
else
err = netif_receive_skb(skb);
@@ -312,7 +308,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
/* let's the caller reinsert the packet, if possible */
if (use_reinsert) {
- err = tcf_mirred_forward(want_ingress, skb);
+ err = tcf_mirred_forward(at_ingress, want_ingress, skb);
if (err)
tcf_action_inc_overlimit_qstats(&m->common);
__this_cpu_dec(mirred_nest_level);
@@ -320,7 +316,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
}
}
- err = tcf_mirred_forward(want_ingress, skb2);
+ err = tcf_mirred_forward(at_ingress, want_ingress, skb2);
if (err)
tcf_action_inc_overlimit_qstats(&m->common);
__this_cpu_dec(mirred_nest_level);
diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
index b0f5e55d2d0b2..5896296365022 100755
--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
+++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
@@ -235,9 +235,6 @@ mirred_egress_to_ingress_tcp_test()
check_err $? "didn't mirred redirect ICMP"
tc_check_packets "dev $h1 ingress" 102 10
check_err $? "didn't drop mirred ICMP"
- local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits)
- test ${overlimits} = 10
- check_err $? "wrong overlimits, expected 10 got ${overlimits}"
tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower
tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0586/1887] ASoC: qcom: Fix uninitialized pointer dmactl
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (584 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0585/1887] net/sched: act_mirred: use the backlog for mirred ingress Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0587/1887] spi: lpspi: Avoid potential use-after-free in probe() Greg Kroah-Hartman
` (412 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Colin Ian King, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <colin.i.king@gmail.com>
[ Upstream commit 1382d8b55129875b2e07c4d2a7ebc790183769ee ]
In the case where __lpass_get_dmactl_handle is called and the driver
id dai_id is invalid the pointer dmactl is not being assigned a value,
and dmactl contains a garbage value since it has not been initialized
and so the null check may not work. Fix this to initialize dmactl to
NULL. One could argue that modern compilers will set this to zero, but
it is useful to keep this initialized as per the same way in functions
__lpass_platform_codec_intf_init and lpass_cdc_dma_daiops_hw_params.
Cleans up clang scan build warning:
sound/soc/qcom/lpass-cdc-dma.c:275:7: warning: Branch condition
evaluates to a garbage value [core.uninitialized.Branch]
Fixes: b81af585ea54 ("ASoC: qcom: Add lpass CPU driver for codec dma control")
Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Link: https://msgid.link/r/20240221134804.3475989-1-colin.i.king@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/qcom/lpass-cdc-dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/qcom/lpass-cdc-dma.c b/sound/soc/qcom/lpass-cdc-dma.c
index 31b9f1c22beea..97c240e8bec38 100644
--- a/sound/soc/qcom/lpass-cdc-dma.c
+++ b/sound/soc/qcom/lpass-cdc-dma.c
@@ -258,7 +258,7 @@ static int lpass_cdc_dma_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *soc_runtime = asoc_substream_to_rtd(substream);
- struct lpaif_dmactl *dmactl;
+ struct lpaif_dmactl *dmactl = NULL;
int ret = 0, id;
switch (cmd) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0587/1887] spi: lpspi: Avoid potential use-after-free in probe()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (585 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0586/1887] ASoC: qcom: Fix uninitialized pointer dmactl Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0588/1887] f2fs: introduce f2fs_is_readonly() for readability Greg Kroah-Hartman
` (411 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Sverdlin, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
[ Upstream commit 2ae0ab0143fcc06190713ed81a6486ed0ad3c861 ]
fsl_lpspi_probe() is allocating/disposing memory manually with
spi_alloc_host()/spi_alloc_target(), but uses
devm_spi_register_controller(). In case of error after the latter call the
memory will be explicitly freed in the probe function by
spi_controller_put() call, but used afterwards by "devm" management outside
probe() (spi_unregister_controller() <- devm_spi_unregister() below).
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000070
...
Call trace:
kernfs_find_ns
kernfs_find_and_get_ns
sysfs_remove_group
sysfs_remove_groups
device_remove_attrs
device_del
spi_unregister_controller
devm_spi_unregister
release_nodes
devres_release_all
really_probe
driver_probe_device
__device_attach_driver
bus_for_each_drv
__device_attach
device_initial_probe
bus_probe_device
deferred_probe_work_func
process_one_work
worker_thread
kthread
ret_from_fork
Fixes: 5314987de5e5 ("spi: imx: add lpspi bus driver")
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Link: https://msgid.link/r/20240312112050.2503643-1-alexander.sverdlin@siemens.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-fsl-lpspi.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 0daba232f4744..df49b52df7c2a 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -827,11 +827,11 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
is_slave = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
if (is_slave)
- controller = spi_alloc_slave(&pdev->dev,
- sizeof(struct fsl_lpspi_data));
+ controller = devm_spi_alloc_target(&pdev->dev,
+ sizeof(struct fsl_lpspi_data));
else
- controller = spi_alloc_master(&pdev->dev,
- sizeof(struct fsl_lpspi_data));
+ controller = devm_spi_alloc_host(&pdev->dev,
+ sizeof(struct fsl_lpspi_data));
if (!controller)
return -ENOMEM;
@@ -931,7 +931,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
pm_runtime_put_sync(fsl_lpspi->dev);
pm_runtime_disable(fsl_lpspi->dev);
out_controller_put:
- spi_controller_put(controller);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0588/1887] f2fs: introduce f2fs_is_readonly() for readability
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (586 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0587/1887] spi: lpspi: Avoid potential use-after-free in probe() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0589/1887] f2fs: introduce f2fs_invalidate_internal_cache() for cleanup Greg Kroah-Hartman
` (410 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yangtao Li, Chao Yu, Jaegeuk Kim,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yangtao Li <frank.li@vivo.com>
[ Upstream commit ed8ac22b6b75804743f1dae6563d75f85cfd1483 ]
Introduce f2fs_is_readonly() and use it to simplify code.
Signed-off-by: Yangtao Li <frank.li@vivo.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: 9f0c4a46be1f ("f2fs: fix to truncate meta inode pages forcely")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/f2fs.h | 5 +++++
fs/f2fs/super.c | 5 ++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 971d45979ce40..f72c28700ab7e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4596,6 +4596,11 @@ static inline void f2fs_handle_page_eio(struct f2fs_sb_info *sbi, pgoff_t ofs,
}
}
+static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
+{
+ return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
+}
+
#define EFSBADCRC EBADMSG /* Bad CRC detected */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index a86200f7d9101..375daa37b3795 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1400,8 +1400,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
return -EINVAL;
}
- if ((f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb)) &&
- test_opt(sbi, FLUSH_MERGE)) {
+ if (f2fs_is_readonly(sbi) && test_opt(sbi, FLUSH_MERGE)) {
f2fs_err(sbi, "FLUSH_MERGE not compatible with readonly mode");
return -EINVAL;
}
@@ -2144,7 +2143,7 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount)
set_opt(sbi, MERGE_CHECKPOINT);
F2FS_OPTION(sbi).unusable_cap = 0;
sbi->sb->s_flags |= SB_LAZYTIME;
- if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb))
+ if (!f2fs_is_readonly(sbi))
set_opt(sbi, FLUSH_MERGE);
if (f2fs_sb_has_blkzoned(sbi))
F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0589/1887] f2fs: introduce f2fs_invalidate_internal_cache() for cleanup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (587 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0588/1887] f2fs: introduce f2fs_is_readonly() for readability Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0590/1887] f2fs: fix to truncate meta inode pages forcely Greg Kroah-Hartman
` (409 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 4e4f1eb9949b10cb7d76370fd27d41f20ef2b32b ]
Just cleanup, no logic changes.
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: 9f0c4a46be1f ("f2fs: fix to truncate meta inode pages forcely")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/data.c | 8 +++-----
fs/f2fs/f2fs.h | 7 +++++++
fs/f2fs/gc.c | 5 ++---
fs/f2fs/segment.c | 14 ++++----------
4 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 94c46b1b04c5c..082e09be4e8a9 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1458,11 +1458,9 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
old_blkaddr = dn->data_blkaddr;
f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
&sum, seg_type, NULL);
- if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) {
- invalidate_mapping_pages(META_MAPPING(sbi),
- old_blkaddr, old_blkaddr);
- f2fs_invalidate_compress_page(sbi, old_blkaddr);
- }
+ if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
+ f2fs_invalidate_internal_cache(sbi, old_blkaddr);
+
f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
return 0;
}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f72c28700ab7e..b077ba9bd0f2b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4601,6 +4601,13 @@ static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
}
+static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
+ block_t blkaddr)
+{
+ invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr);
+ f2fs_invalidate_compress_page(sbi, blkaddr);
+}
+
#define EFSBADCRC EBADMSG /* Bad CRC detected */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 0254e3116e552..abb8f3c37b782 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1377,9 +1377,8 @@ static int move_data_block(struct inode *inode, block_t bidx,
memcpy(page_address(fio.encrypted_page),
page_address(mpage), PAGE_SIZE);
f2fs_put_page(mpage, 1);
- invalidate_mapping_pages(META_MAPPING(fio.sbi),
- fio.old_blkaddr, fio.old_blkaddr);
- f2fs_invalidate_compress_page(fio.sbi, fio.old_blkaddr);
+
+ f2fs_invalidate_internal_cache(fio.sbi, fio.old_blkaddr);
set_page_dirty(fio.encrypted_page);
if (clear_page_dirty_for_io(fio.encrypted_page))
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index db126347ca057..6a8fbb0409ae6 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2298,8 +2298,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
if (addr == NEW_ADDR || addr == COMPRESS_ADDR)
return;
- invalidate_mapping_pages(META_MAPPING(sbi), addr, addr);
- f2fs_invalidate_compress_page(sbi, addr);
+ f2fs_invalidate_internal_cache(sbi, addr);
/* add it into sit main buffer */
down_write(&sit_i->sentry_lock);
@@ -3369,11 +3368,8 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
reallocate:
f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
&fio->new_blkaddr, sum, type, fio);
- if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) {
- invalidate_mapping_pages(META_MAPPING(fio->sbi),
- fio->old_blkaddr, fio->old_blkaddr);
- f2fs_invalidate_compress_page(fio->sbi, fio->old_blkaddr);
- }
+ if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO)
+ f2fs_invalidate_internal_cache(fio->sbi, fio->old_blkaddr);
/* writeout dirty page into bdev */
f2fs_submit_page_write(fio);
@@ -3568,9 +3564,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
update_sit_entry(sbi, new_blkaddr, 1);
}
if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) {
- invalidate_mapping_pages(META_MAPPING(sbi),
- old_blkaddr, old_blkaddr);
- f2fs_invalidate_compress_page(sbi, old_blkaddr);
+ f2fs_invalidate_internal_cache(sbi, old_blkaddr);
if (!from_gc)
update_segment_mtime(sbi, old_blkaddr, 0);
update_sit_entry(sbi, old_blkaddr, -1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0590/1887] f2fs: fix to truncate meta inode pages forcely
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (588 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0589/1887] f2fs: introduce f2fs_invalidate_internal_cache() for cleanup Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0591/1887] drm/bridge: adv7511: fix crash on irq during probe Greg Kroah-Hartman
` (408 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 9f0c4a46be1fe9b97dbe66d49204c1371e3ece65 ]
Below race case can cause data corruption:
Thread A GC thread
- gc_data_segment
- ra_data_block
- locked meta_inode page
- f2fs_inplace_write_data
- invalidate_mapping_pages
: fail to invalidate meta_inode page
due to lock failure or dirty|writeback
status
- f2fs_submit_page_bio
: write last dirty data to old blkaddr
- move_data_block
- load old data from meta_inode page
- f2fs_submit_page_write
: write old data to new blkaddr
Because invalidate_mapping_pages() will skip invalidating page which
has unclear status including locked, dirty, writeback and so on, so
we need to use truncate_inode_pages_range() instead of
invalidate_mapping_pages() to make sure meta_inode page will be dropped.
Fixes: 6aa58d8ad20a ("f2fs: readahead encrypted block during GC")
Fixes: e3b49ea36802 ("f2fs: invalidate META_MAPPING before IPU/DIO write")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/checkpoint.c | 5 +++--
fs/f2fs/f2fs.h | 28 +++++++++++++++++++++++++++-
fs/f2fs/segment.c | 5 ++---
include/linux/f2fs_fs.h | 1 +
4 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 49000b1a7a653..84fc60d843bc2 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1609,8 +1609,9 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
*/
if (f2fs_sb_has_encrypt(sbi) || f2fs_sb_has_verity(sbi) ||
f2fs_sb_has_compression(sbi))
- invalidate_mapping_pages(META_MAPPING(sbi),
- MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1);
+ f2fs_bug_on(sbi,
+ invalidate_inode_pages2_range(META_MAPPING(sbi),
+ MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1));
f2fs_release_ino_entry(sbi, false);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b077ba9bd0f2b..f18e380967678 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4601,10 +4601,36 @@ static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
}
+static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi,
+ block_t blkaddr, unsigned int cnt)
+{
+ bool need_submit = false;
+ int i = 0;
+
+ do {
+ struct page *page;
+
+ page = find_get_page(META_MAPPING(sbi), blkaddr + i);
+ if (page) {
+ if (PageWriteback(page))
+ need_submit = true;
+ f2fs_put_page(page, 0);
+ }
+ } while (++i < cnt && !need_submit);
+
+ if (need_submit)
+ f2fs_submit_merged_write_cond(sbi, sbi->meta_inode,
+ NULL, 0, DATA);
+
+ truncate_inode_pages_range(META_MAPPING(sbi),
+ F2FS_BLK_TO_BYTES((loff_t)blkaddr),
+ F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1)));
+}
+
static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
block_t blkaddr)
{
- invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr);
+ f2fs_truncate_meta_inode_pages(sbi, blkaddr, 1);
f2fs_invalidate_compress_page(sbi, blkaddr);
}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6a8fbb0409ae6..4b13e04c6e608 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3462,8 +3462,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
}
if (fio->post_read)
- invalidate_mapping_pages(META_MAPPING(sbi),
- fio->new_blkaddr, fio->new_blkaddr);
+ f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1);
stat_inc_inplace_blocks(fio->sbi);
@@ -3653,7 +3652,7 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
for (i = 0; i < len; i++)
f2fs_wait_on_block_writeback(inode, blkaddr + i);
- invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr + len - 1);
+ f2fs_truncate_meta_inode_pages(sbi, blkaddr, len);
}
static int read_compacted_summaries(struct f2fs_sb_info *sbi)
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 1373c037255d9..bf834b801b55b 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -27,6 +27,7 @@
#define F2FS_BYTES_TO_BLK(bytes) ((bytes) >> F2FS_BLKSIZE_BITS)
#define F2FS_BLK_TO_BYTES(blk) ((blk) << F2FS_BLKSIZE_BITS)
+#define F2FS_BLK_END_BYTES(blk) (F2FS_BLK_TO_BYTES(blk + 1) - 1)
/* 0, 1(node nid), 2(meta nid) are reserved node id */
#define F2FS_RESERVED_NODE_NUM 3
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0591/1887] drm/bridge: adv7511: fix crash on irq during probe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (589 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0590/1887] f2fs: fix to truncate meta inode pages forcely Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0592/1887] Bluetooth: af_bluetooth: Fix deadlock Greg Kroah-Hartman
` (407 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mads Bligaard Nielsen,
Alvin Šipraga, Robert Foss, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mads Bligaard Nielsen <bli@bang-olufsen.dk>
[ Upstream commit aeedaee5ef5468caf59e2bb1265c2116e0c9a924 ]
Moved IRQ registration down to end of adv7511_probe().
If an IRQ already is pending during adv7511_probe
(before adv7511_cec_init) then cec_received_msg_ts
could crash using uninitialized data:
Unable to handle kernel read from unreadable memory at virtual address 00000000000003d5
Internal error: Oops: 96000004 [#1] PREEMPT_RT SMP
Call trace:
cec_received_msg_ts+0x48/0x990 [cec]
adv7511_cec_irq_process+0x1cc/0x308 [adv7511]
adv7511_irq_process+0xd8/0x120 [adv7511]
adv7511_irq_handler+0x1c/0x30 [adv7511]
irq_thread_fn+0x30/0xa0
irq_thread+0x14c/0x238
kthread+0x190/0x1a8
Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support")
Signed-off-by: Mads Bligaard Nielsen <bli@bang-olufsen.dk>
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Reviewed-by: Robert Foss <rfoss@kernel.org>
Signed-off-by: Robert Foss <rfoss@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240219-adv7511-cec-irq-crash-fix-v2-1-245e53c4b96f@bang-olufsen.dk
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 3e6fe86049599..ac8bc356bcac0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1292,17 +1292,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
- if (i2c->irq) {
- init_waitqueue_head(&adv7511->wq);
-
- ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
- adv7511_irq_handler,
- IRQF_ONESHOT, dev_name(dev),
- adv7511);
- if (ret)
- goto err_unregister_cec;
- }
-
adv7511_power_off(adv7511);
i2c_set_clientdata(i2c, adv7511);
@@ -1326,6 +1315,17 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511_audio_init(dev, adv7511);
+ if (i2c->irq) {
+ init_waitqueue_head(&adv7511->wq);
+
+ ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
+ adv7511_irq_handler,
+ IRQF_ONESHOT, dev_name(dev),
+ adv7511);
+ if (ret)
+ goto err_unregister_audio;
+ }
+
if (adv7511->type == ADV7533 || adv7511->type == ADV7535) {
ret = adv7533_attach_dsi(adv7511);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0592/1887] Bluetooth: af_bluetooth: Fix deadlock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (590 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0591/1887] drm/bridge: adv7511: fix crash on irq during probe Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0593/1887] Bluetooth: hci_core: Fix possible buffer overflow Greg Kroah-Hartman
` (406 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit f7b94bdc1ec107c92262716b073b3e816d4784fb ]
Attemting to do sock_lock on .recvmsg may cause a deadlock as shown
bellow, so instead of using sock_sock this uses sk_receive_queue.lock
on bt_sock_ioctl to avoid the UAF:
INFO: task kworker/u9:1:121 blocked for more than 30 seconds.
Not tainted 6.7.6-lemon #183
Workqueue: hci0 hci_rx_work
Call Trace:
<TASK>
__schedule+0x37d/0xa00
schedule+0x32/0xe0
__lock_sock+0x68/0xa0
? __pfx_autoremove_wake_function+0x10/0x10
lock_sock_nested+0x43/0x50
l2cap_sock_recv_cb+0x21/0xa0
l2cap_recv_frame+0x55b/0x30a0
? psi_task_switch+0xeb/0x270
? finish_task_switch.isra.0+0x93/0x2a0
hci_rx_work+0x33a/0x3f0
process_one_work+0x13a/0x2f0
worker_thread+0x2f0/0x410
? __pfx_worker_thread+0x10/0x10
kthread+0xe0/0x110
? __pfx_kthread+0x10/0x10
ret_from_fork+0x2c/0x50
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1b/0x30
</TASK>
Fixes: 2e07e8348ea4 ("Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/af_bluetooth.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 2e37841e4835f..212ac760f3d91 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -363,14 +363,11 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
if (flags & MSG_OOB)
return -EOPNOTSUPP;
- lock_sock(sk);
-
skb = skb_recv_datagram(sk, flags, &err);
if (!skb) {
if (sk->sk_shutdown & RCV_SHUTDOWN)
err = 0;
- release_sock(sk);
return err;
}
@@ -396,8 +393,6 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
skb_free_datagram(sk, skb);
- release_sock(sk);
-
if (flags & MSG_TRUNC)
copied = skblen;
@@ -630,10 +625,11 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (sk->sk_state == BT_LISTEN)
return -EINVAL;
- lock_sock(sk);
+ spin_lock(&sk->sk_receive_queue.lock);
skb = skb_peek(&sk->sk_receive_queue);
amount = skb ? skb->len : 0;
- release_sock(sk);
+ spin_unlock(&sk->sk_receive_queue.lock);
+
err = put_user(amount, (int __user *)arg);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0593/1887] Bluetooth: hci_core: Fix possible buffer overflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (591 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0592/1887] Bluetooth: af_bluetooth: Fix deadlock Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0594/1887] perf: RISC-V: Define helper functions expose hpm counter width and count Greg Kroah-Hartman
` (405 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit 81137162bfaa7278785b24c1fd2e9e74f082e8e4 ]
struct hci_dev_info has a fixed size name[8] field so in the event that
hdev->name is bigger than that strcpy would attempt to write past its
size, so this fixes this problem by switching to use strscpy.
Fixes: dcda165706b9 ("Bluetooth: hci_core: Fix build warnings")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f79c84a9e0c05..20bf36e88bea3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -877,7 +877,7 @@ int hci_get_dev_info(void __user *arg)
else
flags = hdev->flags;
- strcpy(di.name, hdev->name);
+ strscpy(di.name, hdev->name, sizeof(di.name));
di.bdaddr = hdev->bdaddr;
di.type = (hdev->bus & 0x0f);
di.flags = flags;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0594/1887] perf: RISC-V: Define helper functions expose hpm counter width and count
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (592 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0593/1887] Bluetooth: hci_core: Fix possible buffer overflow Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0595/1887] perf: RISCV: Fix panic on pmu overflow handler Greg Kroah-Hartman
` (404 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anup Patel, Andrew Jones,
Atish Patra, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Atish Patra <atishp@rivosinc.com>
[ Upstream commit 585e351ff359c032ea7ab48d999b252ba09f8051 ]
KVM module needs to know how many hardware counters and the counter
width that the platform supports. Otherwise, it will not be able to show
optimal value of virtual counters to the guest. The virtual hardware
counters also need to have the same width as the logical hardware
counters for simplicity. However, there shouldn't be mapping between
virtual hardware counters and logical hardware counters. As we don't
support hetergeneous harts or counters with different width as of now,
the implementation relies on the counter width of the first available
programmable counter.
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
Stable-dep-of: 34b567868777 ("perf: RISCV: Fix panic on pmu overflow handler")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/perf/riscv_pmu_sbi.c | 37 ++++++++++++++++++++++++++++++++--
include/linux/perf/riscv_pmu.h | 3 +++
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 5aab43a3ffb92..622fe7c982509 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -43,12 +43,15 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = {
};
/*
- * RISC-V doesn't have hetergenous harts yet. This need to be part of
+ * RISC-V doesn't have heterogeneous harts yet. This need to be part of
* per_cpu in case of harts with different pmu counters
*/
static union sbi_pmu_ctr_info *pmu_ctr_list;
static unsigned int riscv_pmu_irq;
+/* Cache the available counters in a bitmask */
+static unsigned long cmask;
+
struct sbi_pmu_event_data {
union {
union {
@@ -264,6 +267,37 @@ static bool pmu_sbi_ctr_is_fw(int cidx)
return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
}
+/*
+ * Returns the counter width of a programmable counter and number of hardware
+ * counters. As we don't support heterogeneous CPUs yet, it is okay to just
+ * return the counter width of the first programmable counter.
+ */
+int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr)
+{
+ int i;
+ union sbi_pmu_ctr_info *info;
+ u32 hpm_width = 0, hpm_count = 0;
+
+ if (!cmask)
+ return -EINVAL;
+
+ for_each_set_bit(i, &cmask, RISCV_MAX_COUNTERS) {
+ info = &pmu_ctr_list[i];
+ if (!info)
+ continue;
+ if (!hpm_width && info->csr != CSR_CYCLE && info->csr != CSR_INSTRET)
+ hpm_width = info->width;
+ if (info->type == SBI_PMU_CTR_TYPE_HW)
+ hpm_count++;
+ }
+
+ *hw_ctr_width = hpm_width;
+ *num_hw_ctr = hpm_count;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(riscv_pmu_get_hpm_info);
+
static int pmu_sbi_ctr_get_idx(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -798,7 +832,6 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
static int pmu_sbi_device_probe(struct platform_device *pdev)
{
struct riscv_pmu *pmu = NULL;
- unsigned long cmask = 0;
int ret = -ENODEV;
int num_counters;
diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
index e17e86ad6f3a2..a1c3f77714810 100644
--- a/include/linux/perf/riscv_pmu.h
+++ b/include/linux/perf/riscv_pmu.h
@@ -73,6 +73,9 @@ void riscv_pmu_legacy_skip_init(void);
static inline void riscv_pmu_legacy_skip_init(void) {};
#endif
struct riscv_pmu *riscv_pmu_alloc(void);
+#ifdef CONFIG_RISCV_PMU_SBI
+int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr);
+#endif
#endif /* CONFIG_RISCV_PMU */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0595/1887] perf: RISCV: Fix panic on pmu overflow handler
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (593 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0594/1887] perf: RISC-V: Define helper functions expose hpm counter width and count Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0596/1887] ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses Greg Kroah-Hartman
` (403 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandre Ghiti, Atish Patra, Fei Wu,
Palmer Dabbelt, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fei Wu <fei2.wu@intel.com>
[ Upstream commit 34b567868777e9fd39ec5333969728a7f0cf179c ]
(1 << idx) of int is not desired when setting bits in unsigned long
overflowed_ctrs, use BIT() instead. This panic happens when running
'perf record -e branches' on sophgo sg2042.
[ 273.311852] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000098
[ 273.320851] Oops [#1]
[ 273.323179] Modules linked in:
[ 273.326303] CPU: 0 PID: 1475 Comm: perf Not tainted 6.6.0-rc3+ #9
[ 273.332521] Hardware name: Sophgo Mango (DT)
[ 273.336878] epc : riscv_pmu_ctr_get_width_mask+0x8/0x62
[ 273.342291] ra : pmu_sbi_ovf_handler+0x2e0/0x34e
[ 273.347091] epc : ffffffff80aecd98 ra : ffffffff80aee056 sp : fffffff6e36928b0
[ 273.354454] gp : ffffffff821f82d0 tp : ffffffd90c353200 t0 : 0000002ade4f9978
[ 273.361815] t1 : 0000000000504d55 t2 : ffffffff8016cd8c s0 : fffffff6e3692a70
[ 273.369180] s1 : 0000000000000020 a0 : 0000000000000000 a1 : 00001a8e81800000
[ 273.376540] a2 : 0000003c00070198 a3 : 0000003c00db75a4 a4 : 0000000000000015
[ 273.383901] a5 : ffffffd7ff8804b0 a6 : 0000000000000015 a7 : 000000000000002a
[ 273.391327] s2 : 000000000000ffff s3 : 0000000000000000 s4 : ffffffd7ff8803b0
[ 273.398773] s5 : 0000000000504d55 s6 : ffffffd905069800 s7 : ffffffff821fe210
[ 273.406139] s8 : 000000007fffffff s9 : ffffffd7ff8803b0 s10: ffffffd903f29098
[ 273.413660] s11: 0000000080000000 t3 : 0000000000000003 t4 : ffffffff8017a0ca
[ 273.421022] t5 : ffffffff8023cfc2 t6 : ffffffd9040780e8
[ 273.426437] status: 0000000200000100 badaddr: 0000000000000098 cause: 000000000000000d
[ 273.434512] [<ffffffff80aecd98>] riscv_pmu_ctr_get_width_mask+0x8/0x62
[ 273.441169] [<ffffffff80076bd8>] handle_percpu_devid_irq+0x98/0x1ee
[ 273.447562] [<ffffffff80071158>] generic_handle_domain_irq+0x28/0x36
[ 273.454151] [<ffffffff8047a99a>] riscv_intc_irq+0x36/0x4e
[ 273.459659] [<ffffffff80c944de>] handle_riscv_irq+0x4a/0x74
[ 273.465442] [<ffffffff80c94c48>] do_irq+0x62/0x92
[ 273.470360] Code: 0420 60a2 6402 5529 0141 8082 0013 0000 0013 0000 (6d5c) b783
[ 273.477921] ---[ end trace 0000000000000000 ]---
[ 273.482630] Kernel panic - not syncing: Fatal exception in interrupt
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Fei Wu <fei2.wu@intel.com>
Link: https://lore.kernel.org/r/20240228115425.2613856-1-fei2.wu@intel.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/perf/riscv_pmu_sbi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 622fe7c982509..9dbbcdbb97ce0 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -651,14 +651,14 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
/* compute hardware counter index */
hidx = info->csr - CSR_CYCLE;
/* check if the corresponding bit is set in sscountovf */
- if (!(overflow & (1 << hidx)))
+ if (!(overflow & BIT(hidx)))
continue;
/*
* Keep a track of overflowed counters so that they can be started
* with updated initial value.
*/
- overflowed_ctrs |= 1 << lidx;
+ overflowed_ctrs |= BIT(lidx);
hw_evt = &event->hw;
riscv_pmu_event_update(event);
perf_sample_data_init(&data, 0, hw_evt->last_period);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0596/1887] ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (594 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0595/1887] perf: RISCV: Fix panic on pmu overflow handler Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0597/1887] drm/amd/display: Add a dc_state NULL check in dc_state_release Greg Kroah-Hartman
` (402 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mike Rapoport, Yongqiang Liu,
Russell King (Oracle), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongqiang Liu <liuyongqiang13@huawei.com>
[ Upstream commit 0c66c6f4e21cb22220cbd8821c5c73fc157d20dc ]
Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
freed memory map alignment") changes the semantics of pfn_valid() to check
presence of the memory map for a PFN. A valid page for an address which
is reserved but not mapped by the kernel[1], the system crashed during
some uio test with the following memory layout:
node 0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
node 0: [mem 0x00000000d0000000-0x00000000da1fffff]
the uio layout is:0xc0900000, 0x100000
the crash backtrace like:
Unable to handle kernel paging request at virtual address bff00000
[...]
CPU: 1 PID: 465 Comm: startapp.bin Tainted: G O 5.10.0 #1
Hardware name: Generic DT based system
PC is at b15_flush_kern_dcache_area+0x24/0x3c
LR is at __sync_icache_dcache+0x6c/0x98
[...]
(b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
(__sync_icache_dcache) from (set_pte_at+0x28/0x54)
(set_pte_at) from (remap_pfn_range+0x1a0/0x274)
(remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
(uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
(__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
(__do_mmap_mm) from (do_mmap+0x50/0x58)
(do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
(vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
(ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
---[ end trace 09cf0734c3805d52 ]---
Kernel panic - not syncing: Fatal exception
So check if PG_reserved was set to solve this issue.
[1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM@linux.ibm.com/
Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
Suggested-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13@huawei.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/mm/flush.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 7ff9feea13a6a..b19ecc307ad46 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -280,6 +280,8 @@ void __sync_icache_dcache(pte_t pteval)
return;
page = pfn_to_page(pfn);
+ if (PageReserved(page))
+ return;
if (cache_is_vipt_aliasing())
mapping = page_mapping_file(page);
else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0597/1887] drm/amd/display: Add a dc_state NULL check in dc_state_release
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (595 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0596/1887] ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0598/1887] net: esp: fix bad handling of pages from page_pool Greg Kroah-Hartman
` (401 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Alex Deucher,
Charlene Liu, Alex Hung, Allen Pan, Daniel Wheeler, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allen Pan <allen.pan@amd.com>
[ Upstream commit 334b56cea5d9df5989be6cf1a5898114fa70ad98 ]
[How]
Check wheather state is NULL before releasing it.
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Allen Pan <allen.pan@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 6a415e2e6b8ee..7594aaf79a101 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2283,7 +2283,8 @@ static void dc_state_free(struct kref *kref)
void dc_release_state(struct dc_state *context)
{
- kref_put(&context->refcount, dc_state_free);
+ if (context != NULL)
+ kref_put(&context->refcount, dc_state_free);
}
bool dc_set_generic_gpio_for_stereo(bool enable,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0598/1887] net: esp: fix bad handling of pages from page_pool
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (596 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0597/1887] drm/amd/display: Add a dc_state NULL check in dc_state_release Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0599/1887] net/sched: Fix mirred deadlock on device recursion Greg Kroah-Hartman
` (400 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ian Kumlien, Dragos Tatulea,
Mina Almasry, Jakub Kicinski, Ilias Apalodimas, Steffen Klassert,
Sasha Levin, Anatoli N.Chechelnickiy
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <dtatulea@nvidia.com>
[ Upstream commit c3198822c6cb9fb588e446540485669cc81c5d34 ]
When the skb is reorganized during esp_output (!esp->inline), the pages
coming from the original skb fragments are supposed to be released back
to the system through put_page. But if the skb fragment pages are
originating from a page_pool, calling put_page on them will trigger a
page_pool leak which will eventually result in a crash.
This leak can be easily observed when using CONFIG_DEBUG_VM and doing
ipsec + gre (non offloaded) forwarding:
BUG: Bad page state in process ksoftirqd/16 pfn:1451b6
page:00000000de2b8d32 refcount:0 mapcount:0 mapping:0000000000000000 index:0x1451b6000 pfn:0x1451b6
flags: 0x200000000000000(node=0|zone=2)
page_type: 0xffffffff()
raw: 0200000000000000 dead000000000040 ffff88810d23c000 0000000000000000
raw: 00000001451b6000 0000000000000001 00000000ffffffff 0000000000000000
page dumped because: page_pool leak
Modules linked in: ip_gre gre mlx5_ib mlx5_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink iptable_nat nf_nat xt_addrtype br_netfilter rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm ib_uverbs ib_core overlay zram zsmalloc fuse [last unloaded: mlx5_core]
CPU: 16 PID: 96 Comm: ksoftirqd/16 Not tainted 6.8.0-rc4+ #22
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x36/0x50
bad_page+0x70/0xf0
free_unref_page_prepare+0x27a/0x460
free_unref_page+0x38/0x120
esp_ssg_unref.isra.0+0x15f/0x200
esp_output_tail+0x66d/0x780
esp_xmit+0x2c5/0x360
validate_xmit_xfrm+0x313/0x370
? validate_xmit_skb+0x1d/0x330
validate_xmit_skb_list+0x4c/0x70
sch_direct_xmit+0x23e/0x350
__dev_queue_xmit+0x337/0xba0
? nf_hook_slow+0x3f/0xd0
ip_finish_output2+0x25e/0x580
iptunnel_xmit+0x19b/0x240
ip_tunnel_xmit+0x5fb/0xb60
ipgre_xmit+0x14d/0x280 [ip_gre]
dev_hard_start_xmit+0xc3/0x1c0
__dev_queue_xmit+0x208/0xba0
? nf_hook_slow+0x3f/0xd0
ip_finish_output2+0x1ca/0x580
ip_sublist_rcv_finish+0x32/0x40
ip_sublist_rcv+0x1b2/0x1f0
? ip_rcv_finish_core.constprop.0+0x460/0x460
ip_list_rcv+0x103/0x130
__netif_receive_skb_list_core+0x181/0x1e0
netif_receive_skb_list_internal+0x1b3/0x2c0
napi_gro_receive+0xc8/0x200
gro_cell_poll+0x52/0x90
__napi_poll+0x25/0x1a0
net_rx_action+0x28e/0x300
__do_softirq+0xc3/0x276
? sort_range+0x20/0x20
run_ksoftirqd+0x1e/0x30
smpboot_thread_fn+0xa6/0x130
kthread+0xcd/0x100
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x31/0x50
? kthread_complete_and_exit+0x20/0x20
ret_from_fork_asm+0x11/0x20
</TASK>
The suggested fix is to introduce a new wrapper (skb_page_unref) that
covers page refcounting for page_pool pages as well.
Cc: stable@vger.kernel.org
Fixes: 6a5bcd84e886 ("page_pool: Allow drivers to hint on SKB recycling")
Reported-and-tested-by: Anatoli N.Chechelnickiy <Anatoli.Chechelnickiy@m.interpipe.biz>
Reported-by: Ian Kumlien <ian.kumlien@gmail.com>
Link: https://lore.kernel.org/netdev/CAA85sZvvHtrpTQRqdaOx6gd55zPAVsqMYk_Lwh4Md5knTq7AyA@mail.gmail.com
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/skbuff.h | 10 ++++++++++
net/ipv4/esp4.c | 8 ++++----
net/ipv6/esp6.c | 8 ++++----
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2d5cf255cf73a..1f646364926e4 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3480,6 +3480,16 @@ static inline void skb_frag_ref(struct sk_buff *skb, int f)
__skb_frag_ref(&skb_shinfo(skb)->frags[f]);
}
+static inline void
+skb_page_unref(const struct sk_buff *skb, struct page *page, bool napi_safe)
+{
+#ifdef CONFIG_PAGE_POOL
+ if (skb->pp_recycle && page_pool_return_skb_page(page))
+ return;
+#endif
+ put_page(page);
+}
+
/**
* __skb_frag_unref - release a reference on a paged fragment.
* @frag: the paged fragment
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 09c2efa3a5b10..55b5c890b15a8 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -95,7 +95,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
__alignof__(struct scatterlist));
}
-static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
+static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
{
struct crypto_aead *aead = x->data;
int extralen = 0;
@@ -114,7 +114,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
*/
if (req->src != req->dst)
for (sg = sg_next(req->src); sg; sg = sg_next(sg))
- put_page(sg_page(sg));
+ skb_page_unref(skb, sg_page(sg), false);
}
#ifdef CONFIG_INET_ESPINTCP
@@ -218,7 +218,7 @@ static void esp_output_done(struct crypto_async_request *base, int err)
}
tmp = ESP_SKB_CB(skb)->tmp;
- esp_ssg_unref(x, tmp);
+ esp_ssg_unref(x, tmp, skb);
kfree(tmp);
if (xo && (xo->flags & XFRM_DEV_RESUME)) {
@@ -608,7 +608,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
}
if (sg != dsg)
- esp_ssg_unref(x, tmp);
+ esp_ssg_unref(x, tmp, skb);
if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
err = esp_output_tail_tcp(x, skb);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index d404f7bec268c..72490d27d15f5 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -112,7 +112,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
__alignof__(struct scatterlist));
}
-static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
+static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
{
struct crypto_aead *aead = x->data;
int extralen = 0;
@@ -131,7 +131,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
*/
if (req->src != req->dst)
for (sg = sg_next(req->src); sg; sg = sg_next(sg))
- put_page(sg_page(sg));
+ skb_page_unref(skb, sg_page(sg), false);
}
#ifdef CONFIG_INET6_ESPINTCP
@@ -252,7 +252,7 @@ static void esp_output_done(struct crypto_async_request *base, int err)
}
tmp = ESP_SKB_CB(skb)->tmp;
- esp_ssg_unref(x, tmp);
+ esp_ssg_unref(x, tmp, skb);
kfree(tmp);
esp_output_encap_csum(skb);
@@ -646,7 +646,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
}
if (sg != dsg)
- esp_ssg_unref(x, tmp);
+ esp_ssg_unref(x, tmp, skb);
if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
err = esp_output_tail_tcp(x, skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0599/1887] net/sched: Fix mirred deadlock on device recursion
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (597 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0598/1887] net: esp: fix bad handling of pages from page_pool Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0600/1887] netfilter: nf_tables: fix memleak in map from abort path Greg Kroah-Hartman
` (399 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mingshuai Ren, Eric Dumazet,
Victor Nogueira, Pedro Tammela, Jamal Hadi Salim, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 0f022d32c3eca477fbf79a205243a6123ed0fe11 ]
When the mirred action is used on a classful egress qdisc and a packet is
mirrored or redirected to self we hit a qdisc lock deadlock.
See trace below.
[..... other info removed for brevity....]
[ 82.890906]
[ 82.890906] ============================================
[ 82.890906] WARNING: possible recursive locking detected
[ 82.890906] 6.8.0-05205-g77fadd89fe2d-dirty #213 Tainted: G W
[ 82.890906] --------------------------------------------
[ 82.890906] ping/418 is trying to acquire lock:
[ 82.890906] ffff888006994110 (&sch->q.lock){+.-.}-{3:3}, at:
__dev_queue_xmit+0x1778/0x3550
[ 82.890906]
[ 82.890906] but task is already holding lock:
[ 82.890906] ffff888006994110 (&sch->q.lock){+.-.}-{3:3}, at:
__dev_queue_xmit+0x1778/0x3550
[ 82.890906]
[ 82.890906] other info that might help us debug this:
[ 82.890906] Possible unsafe locking scenario:
[ 82.890906]
[ 82.890906] CPU0
[ 82.890906] ----
[ 82.890906] lock(&sch->q.lock);
[ 82.890906] lock(&sch->q.lock);
[ 82.890906]
[ 82.890906] *** DEADLOCK ***
[ 82.890906]
[..... other info removed for brevity....]
Example setup (eth0->eth0) to recreate
tc qdisc add dev eth0 root handle 1: htb default 30
tc filter add dev eth0 handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth0
Another example(eth0->eth1->eth0) to recreate
tc qdisc add dev eth0 root handle 1: htb default 30
tc filter add dev eth0 handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth1
tc qdisc add dev eth1 root handle 1: htb default 30
tc filter add dev eth1 handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth0
We fix this by adding an owner field (CPU id) to struct Qdisc set after
root qdisc is entered. When the softirq enters it a second time, if the
qdisc owner is the same CPU, the packet is dropped to break the loop.
Reported-by: Mingshuai Ren <renmingshuai@huawei.com>
Closes: https://lore.kernel.org/netdev/20240314111713.5979-1-renmingshuai@huawei.com/
Fixes: 3bcb846ca4cf ("net: get rid of spin_trylock() in net_tx_action()")
Fixes: e578d9c02587 ("net: sched: use counter to break reclassify loops")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Tested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://lore.kernel.org/r/20240415210728.36949-1-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sch_generic.h | 1 +
net/core/dev.c | 6 ++++++
net/sched/sch_generic.c | 1 +
3 files changed, 8 insertions(+)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index b694d27f41714..d932af97fa579 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -117,6 +117,7 @@ struct Qdisc {
struct qdisc_skb_head q;
struct gnet_stats_basic_sync bstats;
struct gnet_stats_queue qstats;
+ int owner;
unsigned long state;
unsigned long state2; /* must be written under qdisc spinlock */
struct Qdisc *next_sched;
diff --git a/net/core/dev.c b/net/core/dev.c
index f9597dbfd4225..e467e81226396 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3948,6 +3948,10 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
return rc;
}
+ if (unlikely(READ_ONCE(q->owner) == smp_processor_id())) {
+ kfree_skb_reason(skb, SKB_DROP_REASON_TC_EGRESS);
+ return NET_XMIT_DROP;
+ }
/*
* Heuristic to force contended enqueues to serialize on a
* separate lock before trying to get qdisc main lock.
@@ -3987,7 +3991,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
qdisc_run_end(q);
rc = NET_XMIT_SUCCESS;
} else {
+ WRITE_ONCE(q->owner, smp_processor_id());
rc = dev_qdisc_enqueue(skb, q, &to_free, txq);
+ WRITE_ONCE(q->owner, -1);
if (qdisc_run_begin(q)) {
if (unlikely(contended)) {
spin_unlock(&q->busylock);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index f58ec57e31f46..b9cc8e90d6554 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -986,6 +986,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev_queue = dev_queue;
+ sch->owner = -1;
netdev_hold(dev, &sch->dev_tracker, GFP_KERNEL);
refcount_set(&sch->refcnt, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0600/1887] netfilter: nf_tables: fix memleak in map from abort path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (598 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0599/1887] net/sched: Fix mirred deadlock on device recursion Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0601/1887] drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini() Greg Kroah-Hartman
` (398 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit 86a1471d7cde792941109b93b558b5dc078b9ee9 ]
The delete set command does not rely on the transaction object for
element removal, therefore, a combination of delete element + delete set
from the abort path could result in restoring twice the refcount of the
mapping.
Check for inactive element in the next generation for the delete element
command in the abort path, skip restoring state if next generation bit
has been already cleared. This is similar to the activate logic using
the set walk iterator.
[ 6170.286929] ------------[ cut here ]------------
[ 6170.286939] WARNING: CPU: 6 PID: 790302 at net/netfilter/nf_tables_api.c:2086 nf_tables_chain_destroy+0x1f7/0x220 [nf_tables]
[ 6170.287071] Modules linked in: [...]
[ 6170.287633] CPU: 6 PID: 790302 Comm: kworker/6:2 Not tainted 6.9.0-rc3+ #365
[ 6170.287768] RIP: 0010:nf_tables_chain_destroy+0x1f7/0x220 [nf_tables]
[ 6170.287886] Code: df 48 8d 7d 58 e8 69 2e 3b df 48 8b 7d 58 e8 80 1b 37 df 48 8d 7d 68 e8 57 2e 3b df 48 8b 7d 68 e8 6e 1b 37 df 48 89 ef eb c4 <0f> 0b 48 83 c4 08 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 0f
[ 6170.287895] RSP: 0018:ffff888134b8fd08 EFLAGS: 00010202
[ 6170.287904] RAX: 0000000000000001 RBX: ffff888125bffb28 RCX: dffffc0000000000
[ 6170.287912] RDX: 0000000000000003 RSI: ffffffffa20298ab RDI: ffff88811ebe4750
[ 6170.287919] RBP: ffff88811ebe4700 R08: ffff88838e812650 R09: fffffbfff0623a55
[ 6170.287926] R10: ffffffff8311d2af R11: 0000000000000001 R12: ffff888125bffb10
[ 6170.287933] R13: ffff888125bffb10 R14: dead000000000122 R15: dead000000000100
[ 6170.287940] FS: 0000000000000000(0000) GS:ffff888390b00000(0000) knlGS:0000000000000000
[ 6170.287948] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 6170.287955] CR2: 00007fd31fc00710 CR3: 0000000133f60004 CR4: 00000000001706f0
[ 6170.287962] Call Trace:
[ 6170.287967] <TASK>
[ 6170.287973] ? __warn+0x9f/0x1a0
[ 6170.287986] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables]
[ 6170.288092] ? report_bug+0x1b1/0x1e0
[ 6170.287986] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables]
[ 6170.288092] ? report_bug+0x1b1/0x1e0
[ 6170.288104] ? handle_bug+0x3c/0x70
[ 6170.288112] ? exc_invalid_op+0x17/0x40
[ 6170.288120] ? asm_exc_invalid_op+0x1a/0x20
[ 6170.288132] ? nf_tables_chain_destroy+0x2b/0x220 [nf_tables]
[ 6170.288243] ? nf_tables_chain_destroy+0x1f7/0x220 [nf_tables]
[ 6170.288366] ? nf_tables_chain_destroy+0x2b/0x220 [nf_tables]
[ 6170.288483] nf_tables_trans_destroy_work+0x588/0x590 [nf_tables]
Fixes: 591054469b3e ("netfilter: nf_tables: revisit chain/object refcounting from elements")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_tables_api.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9f71ad2669c7e..226fedc7477b1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6869,6 +6869,16 @@ void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
}
}
+static int nft_setelem_active_next(const struct net *net,
+ const struct nft_set *set,
+ struct nft_set_elem *elem)
+{
+ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+ u8 genmask = nft_genmask_next(net);
+
+ return nft_set_elem_active(ext, genmask);
+}
+
static void nft_setelem_data_activate(const struct net *net,
const struct nft_set *set,
struct nft_set_elem *elem)
@@ -10233,8 +10243,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
case NFT_MSG_DELSETELEM:
te = (struct nft_trans_elem *)trans->data;
- nft_setelem_data_activate(net, te->set, &te->elem);
- nft_setelem_activate(net, te->set, &te->elem);
+ if (!nft_setelem_active_next(net, te->set, &te->elem)) {
+ nft_setelem_data_activate(net, te->set, &te->elem);
+ nft_setelem_activate(net, te->set, &te->elem);
+ }
if (!nft_setelem_is_catchall(te->set, &te->elem))
te->set->ndeact--;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0601/1887] drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (599 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0600/1887] netfilter: nf_tables: fix memleak in map from abort path Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0602/1887] ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend Greg Kroah-Hartman
` (397 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikita Zhandarovich, Alex Deucher,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
[ Upstream commit 2a3cfb9a24a28da9cc13d2c525a76548865e182c ]
Since 'adev->dm.dc' in amdgpu_dm_fini() might turn out to be NULL
before the call to dc_enable_dmub_notifications(), check
beforehand to ensure there will not be a possible NULL-ptr-deref
there.
Also, since commit 1e88eb1b2c25 ("drm/amd/display: Drop
CONFIG_DRM_AMD_DC_HDCP") there are two separate checks for NULL in
'adev->dm.dc' before dc_deinit_callbacks() and dc_dmub_srv_destroy().
Clean up by combining them all under one 'if'.
Found by Linux Verification Center (linuxtesting.org) with static
analysis tool SVACE.
Fixes: 81927e2808be ("drm/amd/display: Support for DMUB AUX")
Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8c150bf0aa1dd..53ec5f3a8e6f3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1881,19 +1881,19 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
hdcp_destroy(&adev->dev->kobj, adev->dm.hdcp_workqueue);
adev->dm.hdcp_workqueue = NULL;
}
+#endif
- if (adev->dm.dc)
+ if (adev->dm.dc) {
+#ifdef CONFIG_DRM_AMD_DC_HDCP
dc_deinit_callbacks(adev->dm.dc);
#endif
-
- if (adev->dm.dc)
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
-
- if (dc_enable_dmub_notifications(adev->dm.dc)) {
- kfree(adev->dm.dmub_notify);
- adev->dm.dmub_notify = NULL;
- destroy_workqueue(adev->dm.delayed_hpd_wq);
- adev->dm.delayed_hpd_wq = NULL;
+ if (dc_enable_dmub_notifications(adev->dm.dc)) {
+ kfree(adev->dm.dmub_notify);
+ adev->dm.dmub_notify = NULL;
+ destroy_workqueue(adev->dm.delayed_hpd_wq);
+ adev->dm.delayed_hpd_wq = NULL;
+ }
}
if (adev->dm.dmub_bo)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0602/1887] ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (600 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0601/1887] drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini() Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:44 ` [PATCH 6.1 0603/1887] nouveau: lock the client object tree Greg Kroah-Hartman
` (396 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Ranjani Sridharan,
Pierre-Louis Bossart, Bard Liao, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
[ Upstream commit c40aad7c81e5fba34b70123ed7ce3397fa62a4d2 ]
When the system is suspended while audio is active, the
sof_ipc4_pcm_hw_free() is invoked to reset the pipelines since during
suspend the DSP is turned off, streams will be re-started after resume.
If the firmware crashes during while audio is running (or when we reset
the stream before suspend) then the sof_ipc4_set_multi_pipeline_state()
will fail with IPC error and the state change is interrupted.
This will cause misalignment between the kernel and firmware state on next
DSP boot resulting errors returned by firmware for IPC messages, eventually
failing the audio resume.
On stream close the errors are ignored so the kernel state will be
corrected on the next DSP boot, so the second boot after the DSP panic.
If sof_ipc4_trigger_pipelines() is called from sof_ipc4_pcm_hw_free() then
state parameter is SOF_IPC4_PIPE_RESET and only in this case.
Treat a forced pipeline reset similarly to how we treat a pcm_free by
ignoring error on state sending to allow the kernel's state to be
consistent with the state the firmware will have after the next boot.
Link: https://github.com/thesofproject/sof/issues/8721
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://msgid.link/r/20240213115233.15716-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sof/ipc4-pcm.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
index 732872395980a..2a8501d14e0af 100644
--- a/sound/soc/sof/ipc4-pcm.c
+++ b/sound/soc/sof/ipc4-pcm.c
@@ -86,7 +86,9 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
if (ret < 0) {
dev_err(sdev->dev, "failed to pause pipeline %d\n",
swidget->pipeline_id);
- return ret;
+ if (sdev->fw_state != SOF_FW_CRASHED ||
+ state != SOF_IPC4_PIPE_RESET)
+ return ret;
}
}
@@ -100,7 +102,18 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
if (ret < 0) {
dev_err(sdev->dev, "failed to set state %d for pipeline %d\n",
state, swidget->pipeline_id);
- break;
+ /*
+ * workaround: if the firmware is crashed while setting the
+ * pipelines to reset state we must ignore the error code and
+ * reset it to 0.
+ * Since the firmware is crashed we will not send IPC messages
+ * and we are going to see errors printed, but the state of the
+ * widgets will be correct for the next boot.
+ */
+ if (sdev->fw_state != SOF_FW_CRASHED || state != SOF_IPC4_PIPE_RESET)
+ break;
+
+ ret = 0;
}
pipeline->state = state;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0603/1887] nouveau: lock the client object tree.
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (601 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0602/1887] ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend Greg Kroah-Hartman
@ 2026-10-28 16:44 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0604/1887] dmaengine: dw-edma: eDMA: Add sync read before starting the DMA transfer in remote setup Greg Kroah-Hartman
` (395 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Dave Airlie, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <airlied@redhat.com>
[ Upstream commit b7cc4ff787a572edf2c55caeffaa88cd801eb135 ]
It appears the client object tree has no locking unless I've missed
something else. Fix races around adding/removing client objects,
mostly vram bar mappings.
4562.099306] general protection fault, probably for non-canonical address 0x6677ed422bceb80c: 0000 [#1] PREEMPT SMP PTI
[ 4562.099314] CPU: 2 PID: 23171 Comm: deqp-vk Not tainted 6.8.0-rc6+ #27
[ 4562.099324] Hardware name: Gigabyte Technology Co., Ltd. Z390 I AORUS PRO WIFI/Z390 I AORUS PRO WIFI-CF, BIOS F8 11/05/2021
[ 4562.099330] RIP: 0010:nvkm_object_search+0x1d/0x70 [nouveau]
[ 4562.099503] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 66 0f 1f 00 0f 1f 44 00 00 48 89 f8 48 85 f6 74 39 48 8b 87 a0 00 00 00 48 85 c0 74 12 <48> 8b 48 f8 48 39 ce 73 15 48 8b 40 10 48 85 c0 75 ee 48 c7 c0 fe
[ 4562.099506] RSP: 0000:ffffa94cc420bbf8 EFLAGS: 00010206
[ 4562.099512] RAX: 6677ed422bceb814 RBX: ffff98108791f400 RCX: ffff9810f26b8f58
[ 4562.099517] RDX: 0000000000000000 RSI: ffff9810f26b9158 RDI: ffff98108791f400
[ 4562.099519] RBP: ffff9810f26b9158 R08: 0000000000000000 R09: 0000000000000000
[ 4562.099521] R10: ffffa94cc420bc48 R11: 0000000000000001 R12: ffff9810f02a7cc0
[ 4562.099526] R13: 0000000000000000 R14: 00000000000000ff R15: 0000000000000007
[ 4562.099528] FS: 00007f629c5017c0(0000) GS:ffff98142c700000(0000) knlGS:0000000000000000
[ 4562.099534] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 4562.099536] CR2: 00007f629a882000 CR3: 000000017019e004 CR4: 00000000003706f0
[ 4562.099541] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 4562.099542] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 4562.099544] Call Trace:
[ 4562.099555] <TASK>
[ 4562.099573] ? die_addr+0x36/0x90
[ 4562.099583] ? exc_general_protection+0x246/0x4a0
[ 4562.099593] ? asm_exc_general_protection+0x26/0x30
[ 4562.099600] ? nvkm_object_search+0x1d/0x70 [nouveau]
[ 4562.099730] nvkm_ioctl+0xa1/0x250 [nouveau]
[ 4562.099861] nvif_object_map_handle+0xc8/0x180 [nouveau]
[ 4562.099986] nouveau_ttm_io_mem_reserve+0x122/0x270 [nouveau]
[ 4562.100156] ? dma_resv_test_signaled+0x26/0xb0
[ 4562.100163] ttm_bo_vm_fault_reserved+0x97/0x3c0 [ttm]
[ 4562.100182] ? __mutex_unlock_slowpath+0x2a/0x270
[ 4562.100189] nouveau_ttm_fault+0x69/0xb0 [nouveau]
[ 4562.100356] __do_fault+0x32/0x150
[ 4562.100362] do_fault+0x7c/0x560
[ 4562.100369] __handle_mm_fault+0x800/0xc10
[ 4562.100382] handle_mm_fault+0x17c/0x3e0
[ 4562.100388] do_user_addr_fault+0x208/0x860
[ 4562.100395] exc_page_fault+0x7f/0x200
[ 4562.100402] asm_exc_page_fault+0x26/0x30
[ 4562.100412] RIP: 0033:0x9b9870
[ 4562.100419] Code: 85 a8 f7 ff ff 8b 8d 80 f7 ff ff 89 08 e9 18 f2 ff ff 0f 1f 84 00 00 00 00 00 44 89 32 e9 90 fa ff ff 0f 1f 84 00 00 00 00 00 <44> 89 32 e9 f8 f1 ff ff 0f 1f 84 00 00 00 00 00 66 44 89 32 e9 e7
[ 4562.100422] RSP: 002b:00007fff9ba2dc70 EFLAGS: 00010246
[ 4562.100426] RAX: 0000000000000004 RBX: 000000000dd65e10 RCX: 000000fff0000000
[ 4562.100428] RDX: 00007f629a882000 RSI: 00007f629a882000 RDI: 0000000000000066
[ 4562.100432] RBP: 00007fff9ba2e570 R08: 0000000000000000 R09: 0000000123ddf000
[ 4562.100434] R10: 0000000000000001 R11: 0000000000000246 R12: 000000007fffffff
[ 4562.100436] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[ 4562.100446] </TASK>
[ 4562.100448] Modules linked in: nf_conntrack_netbios_ns nf_conntrack_broadcast nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables libcrc32c nfnetlink cmac bnep sunrpc iwlmvm intel_rapl_msr intel_rapl_common snd_sof_pci_intel_cnl x86_pkg_temp_thermal intel_powerclamp snd_sof_intel_hda_common mac80211 coretemp snd_soc_acpi_intel_match kvm_intel snd_soc_acpi snd_soc_hdac_hda snd_sof_pci snd_sof_xtensa_dsp snd_sof_intel_hda_mlink snd_sof_intel_hda snd_sof kvm snd_sof_utils snd_soc_core snd_hda_codec_realtek libarc4 snd_hda_codec_generic snd_compress snd_hda_ext_core vfat fat snd_hda_intel snd_intel_dspcfg irqbypass iwlwifi snd_hda_codec snd_hwdep snd_hda_core btusb btrtl mei_hdcp iTCO_wdt rapl mei_pxp btintel snd_seq iTCO_vendor_support btbcm snd_seq_device intel_cstate bluetooth snd_pcm cfg80211 intel_wmi_thunderbolt wmi_bmof intel_uncore snd_timer mei_me snd ecdh_generic i2c_i801
[ 4562.100541] ecc mei i2c_smbus soundcore rfkill intel_pch_thermal acpi_pad zram nouveau drm_ttm_helper ttm gpu_sched i2c_algo_bit drm_gpuvm drm_exec mxm_wmi drm_display_helper drm_kms_helper drm crct10dif_pclmul crc32_pclmul nvme e1000e crc32c_intel nvme_core ghash_clmulni_intel video wmi pinctrl_cannonlake ip6_tables ip_tables fuse
[ 4562.100616] ---[ end trace 0000000000000000 ]---
Signed-off-by: Dave Airlie <airlied@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/nouveau/include/nvkm/core/client.h | 1 +
drivers/gpu/drm/nouveau/nvkm/core/client.c | 1 +
drivers/gpu/drm/nouveau/nvkm/core/object.c | 26 ++++++++++++++-----
3 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
index 2f86606e708c9..e0d79bb7a1d8b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
@@ -12,6 +12,7 @@ struct nvkm_client {
struct nvkm_client_notify *notify[32];
struct rb_root objroot;
+ spinlock_t obj_lock;
void *data;
int (*ntfy)(const void *, u32, const void *, u32);
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c
index 0c8c55c73b122..db96699c5b2bd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/client.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c
@@ -300,6 +300,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg,
client->device = device;
client->debug = nvkm_dbgopt(dbg, "CLIENT");
client->objroot = RB_ROOT;
+ spin_lock_init(&client->obj_lock);
client->ntfy = ntfy;
INIT_LIST_HEAD(&client->umem);
spin_lock_init(&client->lock);
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c
index 301a5e5b5f7f9..4c038d5715b92 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/object.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c
@@ -30,8 +30,10 @@ nvkm_object_search(struct nvkm_client *client, u64 handle,
const struct nvkm_object_func *func)
{
struct nvkm_object *object;
+ unsigned long flags;
if (handle) {
+ spin_lock_irqsave(&client->obj_lock, flags);
struct rb_node *node = client->objroot.rb_node;
while (node) {
object = rb_entry(node, typeof(*object), node);
@@ -40,9 +42,12 @@ nvkm_object_search(struct nvkm_client *client, u64 handle,
else
if (handle > object->object)
node = node->rb_right;
- else
+ else {
+ spin_unlock_irqrestore(&client->obj_lock, flags);
goto done;
+ }
}
+ spin_unlock_irqrestore(&client->obj_lock, flags);
return ERR_PTR(-ENOENT);
} else {
object = &client->object;
@@ -57,30 +62,39 @@ nvkm_object_search(struct nvkm_client *client, u64 handle,
void
nvkm_object_remove(struct nvkm_object *object)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&object->client->obj_lock, flags);
if (!RB_EMPTY_NODE(&object->node))
rb_erase(&object->node, &object->client->objroot);
+ spin_unlock_irqrestore(&object->client->obj_lock, flags);
}
bool
nvkm_object_insert(struct nvkm_object *object)
{
- struct rb_node **ptr = &object->client->objroot.rb_node;
+ struct rb_node **ptr;
struct rb_node *parent = NULL;
+ unsigned long flags;
+ spin_lock_irqsave(&object->client->obj_lock, flags);
+ ptr = &object->client->objroot.rb_node;
while (*ptr) {
struct nvkm_object *this = rb_entry(*ptr, typeof(*this), node);
parent = *ptr;
- if (object->object < this->object)
+ if (object->object < this->object) {
ptr = &parent->rb_left;
- else
- if (object->object > this->object)
+ } else if (object->object > this->object) {
ptr = &parent->rb_right;
- else
+ } else {
+ spin_unlock_irqrestore(&object->client->obj_lock, flags);
return false;
+ }
}
rb_link_node(&object->node, parent, ptr);
rb_insert_color(&object->node, &object->client->objroot);
+ spin_unlock_irqrestore(&object->client->obj_lock, flags);
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0604/1887] dmaengine: dw-edma: eDMA: Add sync read before starting the DMA transfer in remote setup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (602 preceding siblings ...)
2026-10-28 16:44 ` [PATCH 6.1 0603/1887] nouveau: lock the client object tree Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0605/1887] btrfs: fix deadlock with fiemap and extent locking Greg Kroah-Hartman
` (394 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Serge Semin, Manivannan Sadhasivam,
Kory Maincent, Vinod Koul, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <kory.maincent@bootlin.com>
[ Upstream commit bbcc1c83f343e580c3aa1f2a8593343bf7b55bba ]
The Linked list element and pointer are not stored in the same memory as
the eDMA controller register. If the doorbell register is toggled before
the full write of the linked list a race condition error will occur.
In remote setup we can only use a readl to the memory to assure the full
write has occurred.
Fixes: 7e4b8a4fbe2c ("dmaengine: Add Synopsys eDMA IP version 0 support")
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Link: https://lore.kernel.org/r/20240129-b4-feature_hdma_mainline-v7-6-8e8c1acb7a46@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dw-edma/dw-edma-v0-core.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c b/drivers/dma/dw-edma/dw-edma-v0-core.c
index ace8980c40d54..1fb1b4d18e261 100644
--- a/drivers/dma/dw-edma/dw-edma-v0-core.c
+++ b/drivers/dma/dw-edma/dw-edma-v0-core.c
@@ -357,6 +357,20 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
#endif /* CONFIG_64BIT */
}
+static void dw_edma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
+{
+ /*
+ * In case of remote eDMA engine setup, the DW PCIe RP/EP internal
+ * configuration registers and application memory are normally accessed
+ * over different buses. Ensure LL-data reaches the memory before the
+ * doorbell register is toggled by issuing the dummy-read from the remote
+ * LL memory in a hope that the MRd TLP will return only after the
+ * last MWr TLP is completed
+ */
+ if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
+ readl(chunk->ll_region.vaddr);
+}
+
void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
{
struct dw_edma_chan *chan = chunk->chan;
@@ -429,6 +443,9 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
SET_CH_32(dw, chan->dir, chan->id, llp.msb,
upper_32_bits(chunk->ll_region.paddr));
}
+
+ dw_edma_v0_sync_ll_data(chunk);
+
/* Doorbell */
SET_RW_32(dw, chan->dir, doorbell,
FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id));
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0605/1887] btrfs: fix deadlock with fiemap and extent locking
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (603 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0604/1887] dmaengine: dw-edma: eDMA: Add sync read before starting the DMA transfer in remote setup Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0606/1887] drm/amd/display: Prevent crash when disable stream Greg Kroah-Hartman
` (393 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Filipe Manana, Josef Bacik,
David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit b0ad381fa7690244802aed119b478b4bdafc31dd ]
While working on the patchset to remove extent locking I got a lockdep
splat with fiemap and pagefaulting with my new extent lock replacement
lock.
This deadlock exists with our normal code, we just don't have lockdep
annotations with the extent locking so we've never noticed it.
Since we're copying the fiemap extent to user space on every iteration
we have the chance of pagefaulting. Because we hold the extent lock for
the entire range we could mkwrite into a range in the file that we have
mmap'ed. This would deadlock with the following stack trace
[<0>] lock_extent+0x28d/0x2f0
[<0>] btrfs_page_mkwrite+0x273/0x8a0
[<0>] do_page_mkwrite+0x50/0xb0
[<0>] do_fault+0xc1/0x7b0
[<0>] __handle_mm_fault+0x2fa/0x460
[<0>] handle_mm_fault+0xa4/0x330
[<0>] do_user_addr_fault+0x1f4/0x800
[<0>] exc_page_fault+0x7c/0x1e0
[<0>] asm_exc_page_fault+0x26/0x30
[<0>] rep_movs_alternative+0x33/0x70
[<0>] _copy_to_user+0x49/0x70
[<0>] fiemap_fill_next_extent+0xc8/0x120
[<0>] emit_fiemap_extent+0x4d/0xa0
[<0>] extent_fiemap+0x7f8/0xad0
[<0>] btrfs_fiemap+0x49/0x80
[<0>] __x64_sys_ioctl+0x3e1/0xb50
[<0>] do_syscall_64+0x94/0x1a0
[<0>] entry_SYSCALL_64_after_hwframe+0x6e/0x76
I wrote an fstest to reproduce this deadlock without my replacement lock
and verified that the deadlock exists with our existing locking.
To fix this simply don't take the extent lock for the entire duration of
the fiemap. This is safe in general because we keep track of where we
are when we're searching the tree, so if an ordered extent updates in
the middle of our fiemap call we'll still emit the correct extents
because we know what offset we were on before.
The only place we maintain the lock is searching delalloc. Since the
delalloc stuff can change during writeback we want to lock the extent
range so we have a consistent view of delalloc at the time we're
checking to see if we need to set the delalloc flag.
With this patch applied we no longer deadlock with my testcase.
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/extent_io.c | 62 ++++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 17 deletions(-)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index aeea8930b973f..1427c42007300 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3706,15 +3706,33 @@ static int fiemap_process_hole(struct btrfs_inode *inode,
* it beyond i_size.
*/
while (cur_offset < end && cur_offset < i_size) {
+ struct extent_state *cached_state = NULL;
u64 delalloc_start;
u64 delalloc_end;
u64 prealloc_start;
+ u64 lockstart;
+ u64 lockend;
u64 prealloc_len = 0;
bool delalloc;
+ lockstart = round_down(cur_offset, inode->root->fs_info->sectorsize);
+ lockend = round_up(end, inode->root->fs_info->sectorsize);
+
+ /*
+ * We are only locking for the delalloc range because that's the
+ * only thing that can change here. With fiemap we have a lock
+ * on the inode, so no buffered or direct writes can happen.
+ *
+ * However mmaps and normal page writeback will cause this to
+ * change arbitrarily. We have to lock the extent lock here to
+ * make sure that nobody messes with the tree while we're doing
+ * btrfs_find_delalloc_in_range.
+ */
+ lock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
delalloc = btrfs_find_delalloc_in_range(inode, cur_offset, end,
&delalloc_start,
&delalloc_end);
+ unlock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
if (!delalloc)
break;
@@ -3884,7 +3902,6 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
const u64 ino = btrfs_ino(inode);
- struct extent_state *cached_state = NULL;
struct btrfs_path *path;
struct btrfs_root *root = inode->root;
struct fiemap_cache cache = { 0 };
@@ -3893,8 +3910,9 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
struct ulist *tmp_ulist;
u64 last_extent_end;
u64 prev_extent_end;
- u64 lockstart;
- u64 lockend;
+ u64 range_start;
+ u64 range_end;
+ const u64 sectorsize = inode->root->fs_info->sectorsize;
bool stopped = false;
int ret;
@@ -3907,12 +3925,11 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
goto out;
}
- lockstart = round_down(start, root->fs_info->sectorsize);
- lockend = round_up(start + len, root->fs_info->sectorsize);
- prev_extent_end = lockstart;
+ range_start = round_down(start, sectorsize);
+ range_end = round_up(start + len, sectorsize);
+ prev_extent_end = range_start;
btrfs_inode_lock(&inode->vfs_inode, BTRFS_ILOCK_SHARED);
- lock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
ret = fiemap_find_last_extent_offset(inode, path, &last_extent_end);
if (ret < 0)
@@ -3920,7 +3937,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
btrfs_release_path(path);
path->reada = READA_FORWARD;
- ret = fiemap_search_slot(inode, path, lockstart);
+ ret = fiemap_search_slot(inode, path, range_start);
if (ret < 0) {
goto out_unlock;
} else if (ret > 0) {
@@ -3932,7 +3949,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
goto check_eof_delalloc;
}
- while (prev_extent_end < lockend) {
+ while (prev_extent_end < range_end) {
struct extent_buffer *leaf = path->nodes[0];
struct btrfs_file_extent_item *ei;
struct btrfs_key key;
@@ -3955,17 +3972,17 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
* The first iteration can leave us at an extent item that ends
* before our range's start. Move to the next item.
*/
- if (extent_end <= lockstart)
+ if (extent_end <= range_start)
goto next_item;
/* We have in implicit hole (NO_HOLES feature enabled). */
if (prev_extent_end < key.offset) {
- const u64 range_end = min(key.offset, lockend) - 1;
+ const u64 hole_end = min(key.offset, range_end) - 1;
ret = fiemap_process_hole(inode, fieinfo, &cache,
backref_cache, 0, 0, 0,
roots, tmp_ulist,
- prev_extent_end, range_end);
+ prev_extent_end, hole_end);
if (ret < 0) {
goto out_unlock;
} else if (ret > 0) {
@@ -3975,7 +3992,7 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
}
/* We've reached the end of the fiemap range, stop. */
- if (key.offset >= lockend) {
+ if (key.offset >= range_end) {
stopped = true;
break;
}
@@ -4070,28 +4087,40 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
btrfs_free_path(path);
path = NULL;
- if (!stopped && prev_extent_end < lockend) {
+ if (!stopped && prev_extent_end < range_end) {
ret = fiemap_process_hole(inode, fieinfo, &cache, backref_cache,
0, 0, 0, roots, tmp_ulist,
- prev_extent_end, lockend - 1);
+ prev_extent_end, range_end - 1);
if (ret < 0)
goto out_unlock;
- prev_extent_end = lockend;
+ prev_extent_end = range_end;
}
if (cache.cached && cache.offset + cache.len >= last_extent_end) {
const u64 i_size = i_size_read(&inode->vfs_inode);
if (prev_extent_end < i_size) {
+ struct extent_state *cached_state = NULL;
u64 delalloc_start;
u64 delalloc_end;
+ u64 lockstart;
+ u64 lockend;
bool delalloc;
+ lockstart = round_down(prev_extent_end, sectorsize);
+ lockend = round_up(i_size, sectorsize);
+
+ /*
+ * See the comment in fiemap_process_hole as to why
+ * we're doing the locking here.
+ */
+ lock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
delalloc = btrfs_find_delalloc_in_range(inode,
prev_extent_end,
i_size - 1,
&delalloc_start,
&delalloc_end);
+ unlock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
if (!delalloc)
cache.flags |= FIEMAP_EXTENT_LAST;
} else {
@@ -4102,7 +4131,6 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo,
ret = emit_last_fiemap_cache(fieinfo, &cache);
out_unlock:
- unlock_extent(&inode->io_tree, lockstart, lockend, &cached_state);
btrfs_inode_unlock(&inode->vfs_inode, BTRFS_ILOCK_SHARED);
out:
kfree(backref_cache);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0606/1887] drm/amd/display: Prevent crash when disable stream
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (604 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0605/1887] btrfs: fix deadlock with fiemap and extent locking Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0607/1887] bpf: support deferring bpf_link dealloc to after RCU grace period Greg Kroah-Hartman
` (392 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Alex Deucher,
Charlene Liu, Wayne Lin, Chris Park, Daniel Wheeler, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Park <chris.park@amd.com>
[ Upstream commit 72d72e8fddbcd6c98e1b02d32cf6f2b04e10bd1c ]
[Why]
Disabling stream encoder invokes a function that no longer exists.
[How]
Check if the function declaration is NULL in disable stream encoder.
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Chris Park <chris.park@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
index fd9809b17882a..7dbe7909f163f 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
@@ -137,7 +137,8 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
dto_params.timing = &pipe_ctx->stream->timing;
stream_enc->funcs->disable(stream_enc);
- dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+ if (dccg && dccg->funcs->set_dtbclk_dto)
+ dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, stream_enc->inst);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0607/1887] bpf: support deferring bpf_link dealloc to after RCU grace period
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (605 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0606/1887] drm/amd/display: Prevent crash when disable stream Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0608/1887] selinux: avoid dereference of garbage after mount failure Greg Kroah-Hartman
` (391 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+981935d9485a560bfbcb,
syzbot+2cb5a6c573e98db598cc, syzbot+62d8b26793e8a2bd0516,
Andrii Nakryiko, Jiri Olsa, Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <andrii@kernel.org>
[ Upstream commit 1a80dbcb2dbaf6e4c216e62e30fa7d3daa8001ce ]
BPF link for some program types is passed as a "context" which can be
used by those BPF programs to look up additional information. E.g., for
multi-kprobes and multi-uprobes, link is used to fetch BPF cookie values.
Because of this runtime dependency, when bpf_link refcnt drops to zero
there could still be active BPF programs running accessing link data.
This patch adds generic support to defer bpf_link dealloc callback to
after RCU GP, if requested. This is done by exposing two different
deallocation callbacks, one synchronous and one deferred. If deferred
one is provided, bpf_link_free() will schedule dealloc_deferred()
callback to happen after RCU GP.
BPF is using two flavors of RCU: "classic" non-sleepable one and RCU
tasks trace one. The latter is used when sleepable BPF programs are
used. bpf_link_free() accommodates that by checking underlying BPF
program's sleepable flag, and goes either through normal RCU GP only for
non-sleepable, or through RCU tasks trace GP *and* then normal RCU GP
(taking into account rcu_trace_implies_rcu_gp() optimization), if BPF
program is sleepable.
We use this for multi-kprobe and multi-uprobe links, which dereference
link during program run. We also preventively switch raw_tp link to use
deferred dealloc callback, as upcoming changes in bpf-next tree expose
raw_tp link data (specifically, cookie value) to BPF program at runtime
as well.
Fixes: 0dcac2725406 ("bpf: Add multi kprobe link")
Fixes: 89ae89f53d20 ("bpf: Add multi uprobe link")
Reported-by: syzbot+981935d9485a560bfbcb@syzkaller.appspotmail.com
Reported-by: syzbot+2cb5a6c573e98db598cc@syzkaller.appspotmail.com
Reported-by: syzbot+62d8b26793e8a2bd0516@syzkaller.appspotmail.com
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20240328052426.3042617-2-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf.h | 16 +++++++++++++++-
kernel/bpf/syscall.c | 35 ++++++++++++++++++++++++++++++++---
kernel/trace/bpf_trace.c | 2 +-
3 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 92884bf344f8c..085bb4e420ef3 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1305,12 +1305,26 @@ struct bpf_link {
enum bpf_link_type type;
const struct bpf_link_ops *ops;
struct bpf_prog *prog;
- struct work_struct work;
+ /* rcu is used before freeing, work can be used to schedule that
+ * RCU-based freeing before that, so they never overlap
+ */
+ union {
+ struct rcu_head rcu;
+ struct work_struct work;
+ };
};
struct bpf_link_ops {
void (*release)(struct bpf_link *link);
+ /* deallocate link resources callback, called without RCU grace period
+ * waiting
+ */
void (*dealloc)(struct bpf_link *link);
+ /* deallocate link resources callback, called after RCU grace period;
+ * if underlying BPF program is sleepable we go through tasks trace
+ * RCU GP and then "classic" RCU GP
+ */
+ void (*dealloc_deferred)(struct bpf_link *link);
int (*detach)(struct bpf_link *link);
int (*update_prog)(struct bpf_link *link, struct bpf_prog *new_prog,
struct bpf_prog *old_prog);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index d630d1665c6b0..ec1e0c1a6dd87 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2760,17 +2760,46 @@ void bpf_link_inc(struct bpf_link *link)
atomic64_inc(&link->refcnt);
}
+static void bpf_link_defer_dealloc_rcu_gp(struct rcu_head *rcu)
+{
+ struct bpf_link *link = container_of(rcu, struct bpf_link, rcu);
+
+ /* free bpf_link and its containing memory */
+ link->ops->dealloc_deferred(link);
+}
+
+static void bpf_link_defer_dealloc_mult_rcu_gp(struct rcu_head *rcu)
+{
+ if (rcu_trace_implies_rcu_gp())
+ bpf_link_defer_dealloc_rcu_gp(rcu);
+ else
+ call_rcu(rcu, bpf_link_defer_dealloc_rcu_gp);
+}
+
/* bpf_link_free is guaranteed to be called from process context */
static void bpf_link_free(struct bpf_link *link)
{
+ bool sleepable = false;
+
bpf_link_free_id(link->id);
if (link->prog) {
+ sleepable = link->prog->aux->sleepable;
/* detach BPF program, clean up used resources */
link->ops->release(link);
bpf_prog_put(link->prog);
}
- /* free bpf_link and its containing memory */
- link->ops->dealloc(link);
+ if (link->ops->dealloc_deferred) {
+ /* schedule BPF link deallocation; if underlying BPF program
+ * is sleepable, we need to first wait for RCU tasks trace
+ * sync, then go through "classic" RCU grace period
+ */
+ if (sleepable)
+ call_rcu_tasks_trace(&link->rcu, bpf_link_defer_dealloc_mult_rcu_gp);
+ else
+ call_rcu(&link->rcu, bpf_link_defer_dealloc_rcu_gp);
+ }
+ if (link->ops->dealloc)
+ link->ops->dealloc(link);
}
static void bpf_link_put_deferred(struct work_struct *work)
@@ -3256,7 +3285,7 @@ static int bpf_raw_tp_link_fill_link_info(const struct bpf_link *link,
static const struct bpf_link_ops bpf_raw_tp_link_lops = {
.release = bpf_raw_tp_link_release,
- .dealloc = bpf_raw_tp_link_dealloc,
+ .dealloc_deferred = bpf_raw_tp_link_dealloc,
.show_fdinfo = bpf_raw_tp_link_show_fdinfo,
.fill_link_info = bpf_raw_tp_link_fill_link_info,
};
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index fcddc223c3f06..5342e0574b9d9 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -2565,7 +2565,7 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
static const struct bpf_link_ops bpf_kprobe_multi_link_lops = {
.release = bpf_kprobe_multi_link_release,
- .dealloc = bpf_kprobe_multi_link_dealloc,
+ .dealloc_deferred = bpf_kprobe_multi_link_dealloc,
};
static void bpf_kprobe_multi_cookie_swap(void *a, void *b, int size, const void *priv)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0608/1887] selinux: avoid dereference of garbage after mount failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (606 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0607/1887] bpf: support deferring bpf_link dealloc to after RCU grace period Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0609/1887] usb: typec: ucsi: Limit read size on v1.2 Greg Kroah-Hartman
` (390 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Göttsche, Paul Moore,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Göttsche <cgzones@googlemail.com>
[ Upstream commit 37801a36b4d68892ce807264f784d818f8d0d39b ]
In case kern_mount() fails and returns an error pointer return in the
error branch instead of continuing and dereferencing the error pointer.
While on it drop the never read static variable selinuxfs_mount.
Cc: stable@vger.kernel.org
Fixes: 0619f0f5e36f ("selinux: wrap selinuxfs state")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/selinux/selinuxfs.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f74fdabaa541b..8fd1428a60e18 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2211,7 +2211,6 @@ static struct file_system_type sel_fs_type = {
.kill_sb = sel_kill_sb,
};
-static struct vfsmount *selinuxfs_mount __ro_after_init;
struct path selinux_null __ro_after_init;
static int __init init_sel_fs(void)
@@ -2233,18 +2232,21 @@ static int __init init_sel_fs(void)
return err;
}
- selinux_null.mnt = selinuxfs_mount = kern_mount(&sel_fs_type);
- if (IS_ERR(selinuxfs_mount)) {
+ selinux_null.mnt = kern_mount(&sel_fs_type);
+ if (IS_ERR(selinux_null.mnt)) {
pr_err("selinuxfs: could not mount!\n");
- err = PTR_ERR(selinuxfs_mount);
- selinuxfs_mount = NULL;
+ err = PTR_ERR(selinux_null.mnt);
+ selinux_null.mnt = NULL;
+ return err;
}
+
selinux_null.dentry = d_hash_and_lookup(selinux_null.mnt->mnt_root,
&null_name);
if (IS_ERR(selinux_null.dentry)) {
pr_err("selinuxfs: could not lookup null!\n");
err = PTR_ERR(selinux_null.dentry);
selinux_null.dentry = NULL;
+ return err;
}
return err;
@@ -2257,7 +2259,7 @@ void exit_sel_fs(void)
{
sysfs_remove_mount_point(fs_kobj, "selinux");
dput(selinux_null.dentry);
- kern_unmount(selinuxfs_mount);
+ kern_unmount(selinux_null.mnt);
unregister_filesystem(&sel_fs_type);
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0609/1887] usb: typec: ucsi: Limit read size on v1.2
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (607 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0608/1887] selinux: avoid dereference of garbage after mount failure Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0610/1887] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain Greg Kroah-Hartman
` (389 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Neil Armstrong, Prashant Malani,
Heikki Krogerus, Abhishek Pandit-Subedi, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
[ Upstream commit b3db266fb031fba88c423d4bb8983a73a3db6527 ]
Between UCSI 1.2 and UCSI 2.0, the size of the MESSAGE_IN region was
increased from 16 to 256. In order to avoid overflowing reads for older
systems, add a mechanism to use the read UCSI version to truncate read
sizes on UCSI v1.2.
Tested-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Link: https://lore.kernel.org/r/20240209143723.v5.1.Iacf5570a66b82b73ef03daa6557e2fc0db10266a@changeid
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi.c | 26 ++++++++++++++++++++++++--
drivers/usb/typec/ucsi/ucsi.h | 11 +++++++++++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 1cf711f7866fe..221fe9ade9580 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -36,6 +36,19 @@
*/
#define UCSI_SWAP_TIMEOUT_MS 5000
+static int ucsi_read_message_in(struct ucsi *ucsi, void *buf,
+ size_t buf_size)
+{
+ /*
+ * Below UCSI 2.0, MESSAGE_IN was limited to 16 bytes. Truncate the
+ * reads here.
+ */
+ if (ucsi->version <= UCSI_VERSION_1_2)
+ buf_size = clamp(buf_size, 0, 16);
+
+ return ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, buf, buf_size);
+}
+
static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
{
u64 ctrl;
@@ -66,7 +79,7 @@ static int ucsi_read_error(struct ucsi *ucsi)
if (ret < 0)
return ret;
- ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, &error, sizeof(error));
+ ret = ucsi_read_message_in(ucsi, &error, sizeof(error));
if (ret)
return ret;
@@ -173,7 +186,7 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 command,
length = ret;
if (data) {
- ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, data, size);
+ ret = ucsi_read_message_in(ucsi, data, size);
if (ret)
goto out;
}
@@ -1589,6 +1602,15 @@ int ucsi_register(struct ucsi *ucsi)
if (!ucsi->version)
return -ENODEV;
+ /*
+ * Version format is JJ.M.N (JJ = Major version, M = Minor version,
+ * N = sub-minor version).
+ */
+ dev_dbg(ucsi->dev, "Registered UCSI interface with version %x.%x.%x",
+ UCSI_BCD_GET_MAJOR(ucsi->version),
+ UCSI_BCD_GET_MINOR(ucsi->version),
+ UCSI_BCD_GET_SUBMINOR(ucsi->version));
+
queue_delayed_work(system_long_wq, &ucsi->work, 0);
return 0;
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index cee43f19adf5d..16ead80d3a4e7 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -23,6 +23,17 @@ struct ucsi_connector;
#define UCSI_CONTROL 8
#define UCSI_MESSAGE_IN 16
#define UCSI_MESSAGE_OUT 32
+#define UCSIv2_MESSAGE_OUT 272
+
+/* UCSI versions */
+#define UCSI_VERSION_1_2 0x0120
+#define UCSI_VERSION_2_0 0x0200
+#define UCSI_VERSION_2_1 0x0210
+#define UCSI_VERSION_3_0 0x0300
+
+#define UCSI_BCD_GET_MAJOR(_v_) (((_v_) >> 8) & 0xFF)
+#define UCSI_BCD_GET_MINOR(_v_) (((_v_) >> 4) & 0x0F)
+#define UCSI_BCD_GET_SUBMINOR(_v_) ((_v_) & 0x0F)
/* Command Status and Connector Change Indication (CCI) bits */
#define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 1)) >> 1)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0610/1887] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (608 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0609/1887] usb: typec: ucsi: Limit read size on v1.2 Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0611/1887] net: phy: phy_device: Prevent nullptr exceptions on ISR Greg Kroah-Hartman
` (388 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adam Ford, Jacky Bai, Sandor Yu,
Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Ford <aford173@gmail.com>
[ Upstream commit 697624ee8ad557ab5417f985d2c804241a7ad30d ]
According to i.MX8MP RM and HDMI ADD, the fdcc clock is part of
hdmi rx verification IP that should not enable for HDMI TX.
But actually if the clock is disabled before HDMI/LCDIF probe,
LCDIF will not get pixel clock from HDMI PHY and print the error
logs:
[CRTC:39:crtc-2] vblank wait timed out
WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260
Add fdcc clock to LCDIF and HDMI TX power domains to fix the issue.
Signed-off-by: Adam Ford <aford173@gmail.com>
Reviewed-by: Jacky Bai <ping.bai@nxp.com>
Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
Link: https://lore.kernel.org/r/20240203165307.7806-5-aford173@gmail.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/imx/imx8mp-blk-ctrl.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c
index 575ed8e3a5209..65848f6b8f352 100644
--- a/drivers/soc/imx/imx8mp-blk-ctrl.c
+++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
@@ -45,7 +45,7 @@ struct imx8mp_blk_ctrl_domain_data {
const unsigned int flags;
};
-#define DOMAIN_MAX_CLKS 2
+#define DOMAIN_MAX_CLKS 3
#define DOMAIN_MAX_PATHS 3
struct imx8mp_blk_ctrl_domain {
@@ -359,8 +359,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
},
[IMX8MP_HDMIBLK_PD_LCDIF] = {
.name = "hdmiblk-lcdif",
- .clk_names = (const char *[]){ "axi", "apb" },
- .num_clks = 2,
+ .clk_names = (const char *[]){ "axi", "apb", "fdcc" },
+ .num_clks = 3,
.gpc_name = "lcdif",
.path_names = (const char *[]){"lcdif-hdmi"},
.num_paths = 1,
@@ -385,8 +385,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
},
[IMX8MP_HDMIBLK_PD_HDMI_TX] = {
.name = "hdmiblk-hdmi-tx",
- .clk_names = (const char *[]){ "apb", "ref_266m" },
- .num_clks = 2,
+ .clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
+ .num_clks = 3,
.gpc_name = "hdmi-tx",
},
[IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0611/1887] net: phy: phy_device: Prevent nullptr exceptions on ISR
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (609 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0610/1887] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0612/1887] wifi: rtw89: fix null pointer access when abort scan Greg Kroah-Hartman
` (387 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andre Werner, Andrew Lunn,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Werner <andre.werner@systec-electronic.com>
[ Upstream commit 61c81872815f46006982bb80460c0c80a949b35b ]
If phydev->irq is set unconditionally, check
for valid interrupt handler or fall back to polling mode to prevent
nullptr exceptions in interrupt service routine.
Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240129135734.18975-2-andre.werner@systec-electronic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/phy/phy_device.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 9b0c88c19795e..96dcd1d70bf4a 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1404,6 +1404,11 @@ int phy_sfp_probe(struct phy_device *phydev,
}
EXPORT_SYMBOL(phy_sfp_probe);
+static bool phy_drv_supports_irq(struct phy_driver *phydrv)
+{
+ return phydrv->config_intr && phydrv->handle_interrupt;
+}
+
/**
* phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
@@ -1513,6 +1518,9 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
phydev->interrupts = PHY_INTERRUPT_DISABLED;
+ if (!phy_drv_supports_irq(phydev->drv) && phy_interrupt_is_valid(phydev))
+ phydev->irq = PHY_POLL;
+
/* Port is set to PORT_TP by default and the actual PHY driver will set
* it to different value depending on the PHY configuration. If we have
* the generic PHY driver we can't figure it out, thus set the old
@@ -2951,11 +2959,6 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
}
EXPORT_SYMBOL(phy_get_internal_delay);
-static bool phy_drv_supports_irq(struct phy_driver *phydrv)
-{
- return phydrv->config_intr && phydrv->handle_interrupt;
-}
-
/**
* fwnode_mdio_find_device - Given a fwnode, find the mdio_device
* @fwnode: pointer to the mdio_device's fwnode
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0612/1887] wifi: rtw89: fix null pointer access when abort scan
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (610 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0611/1887] net: phy: phy_device: Prevent nullptr exceptions on ISR Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0613/1887] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Greg Kroah-Hartman
` (386 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Po-Hao Huang, Ping-Ke Shih,
Kalle Valo, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Po-Hao Huang <phhuang@realtek.com>
[ Upstream commit 7e11a2966f51695c0af0b1f976a32d64dee243b2 ]
During cancel scan we might use vif that weren't scanning.
Fix this by using the actual scanning vif.
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240119081501.25223-6-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw89/mac80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index f7880499aeb09..2c3a72900b9fb 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -383,7 +383,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
* when disconnected by peer
*/
if (rtwdev->scanning)
- rtw89_hw_scan_abort(rtwdev, vif);
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0613/1887] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (611 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0612/1887] wifi: rtw89: fix null pointer access when abort scan Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0614/1887] mm/userfaultfd: reset ptes when close() for wr-protected ones Greg Kroah-Hartman
` (385 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Steven Price,
AngeloGioacchino Del Regno, Boris Brezillon, Dmitry Osipenko,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <boris.brezillon@collabora.com>
[ Upstream commit 1fc9af813b25e146d3607669247d0f970f5a87c3 ]
Subject: [PATCH 6.1 0613/1887] [PATCH] drm/panfrost: Fix the error path in
panfrost_mmu_map_fault_addr()
If some the pages or sgt allocation failed, we shouldn't release the
pages ref we got earlier, otherwise we will end up with unbalanced
get/put_pages() calls. We should instead leave everything in place
and let the BO release function deal with extra cleanup when the object
is destroyed, or let the fault handler try again next time it's called.
Fixes: 187d2929206e ("drm/panfrost: Add support for GPU heap allocations")
Cc: <stable@vger.kernel.org>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Co-developed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240105184624.508603-18-dmitry.osipenko@collabora.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/panfrost/panfrost_mmu.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index e961fa27702ce..5aa6d94e95c98 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -500,12 +500,19 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
mapping_set_unevictable(mapping);
for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) {
+ /* Can happen if the last fault only partially filled this
+ * section of the pages array before failing. In that case
+ * we skip already filled pages.
+ */
+ if (pages[i])
+ continue;
+
pages[i] = shmem_read_mapping_page(mapping, i);
if (IS_ERR(pages[i])) {
mutex_unlock(&bo->base.pages_lock);
ret = PTR_ERR(pages[i]);
pages[i] = NULL;
- goto err_pages;
+ goto err_bo;
}
}
@@ -515,7 +522,7 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL);
if (ret)
- goto err_pages;
+ goto err_bo;
ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0);
if (ret)
@@ -535,8 +542,6 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
err_map:
sg_free_table(sgt);
-err_pages:
- drm_gem_shmem_put_pages(&bo->base);
err_bo:
panfrost_gem_mapping_put(bomapping);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0614/1887] mm/userfaultfd: reset ptes when close() for wr-protected ones
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (612 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0613/1887] drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0615/1887] hv_netvsc: Dont free decrypted memory Greg Kroah-Hartman
` (384 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d8426b591c36b21c750e,
Peter Xu, David Hildenbrand, Nadav Amit, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Xu <peterx@redhat.com>
[ Upstream commit c88033efe9a391e72ba6b5df4b01d6e628f4e734 ]
Userfaultfd unregister includes a step to remove wr-protect bits from all
the relevant pgtable entries, but that only covered an explicit
UFFDIO_UNREGISTER ioctl, not a close() on the userfaultfd itself. Cover
that too. This fixes a WARN trace.
The only user visible side effect is the user can observe leftover
wr-protect bits even if the user close()ed on an userfaultfd when
releasing the last reference of it. However hopefully that should be
harmless, and nothing bad should happen even if so.
This change is now more important after the recent page-table-check
patch we merged in mm-unstable (446dd9ad37d0 ("mm/page_table_check:
support userfault wr-protect entries")), as we'll do sanity check on
uffd-wp bits without vma context. So it's better if we can 100%
guarantee no uffd-wp bit leftovers, to make sure each report will be
valid.
Link: https://lore.kernel.org/all/000000000000ca4df20616a0fe16@google.com/
Fixes: f369b07c8614 ("mm/uffd: reset write protection when unregister with wp-mode")
Analyzed-by: David Hildenbrand <david@redhat.com>
Link: https://lkml.kernel.org/r/20240422133311.2987675-1-peterx@redhat.com
Reported-by: syzbot+d8426b591c36b21c750e@syzkaller.appspotmail.com
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/userfaultfd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 6ebee2b3a5a83..79b0f22eedd71 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -908,6 +908,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
prev = vma;
continue;
}
+ /* Reset ptes for the whole vma range if wr-protected */
+ if (userfaultfd_wp(vma))
+ uffd_wp_range(mm, vma, vma->vm_start,
+ vma->vm_end - vma->vm_start, false);
new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
prev = vma_merge(mm, prev, vma->vm_start, vma->vm_end,
new_flags, vma->anon_vma,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0615/1887] hv_netvsc: Dont free decrypted memory
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (613 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0614/1887] mm/userfaultfd: reset ptes when close() for wr-protected ones Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0616/1887] Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() Greg Kroah-Hartman
` (383 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rick Edgecombe, Michael Kelley,
Kuppuswamy Sathyanarayanan, Kirill A. Shutemov, Wei Liu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
[ Upstream commit bbf9ac34677b57506a13682b31a2a718934c0e31 ]
In CoCo VMs it is possible for the untrusted host to cause
set_memory_encrypted() or set_memory_decrypted() to fail such that an
error is returned and the resulting memory is shared. Callers need to
take care to handle these errors to avoid returning decrypted (shared)
memory to the page allocator, which could lead to functional or security
issues.
The netvsc driver could free decrypted/shared pages if
set_memory_decrypted() fails. Check the decrypted field in the gpadl
to decide whether to free the memory.
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Link: https://lore.kernel.org/r/20240311161558.1310-4-mhklinux@outlook.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <20240311161558.1310-4-mhklinux@outlook.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hyperv/netvsc.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 077595b42d4a7..e17c6dadfef86 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -156,15 +156,19 @@ static void free_netvsc_device(struct rcu_head *head)
kfree(nvdev->extension);
- if (nvdev->recv_original_buf)
- vfree(nvdev->recv_original_buf);
- else
- vfree(nvdev->recv_buf);
+ if (!nvdev->recv_buf_gpadl_handle.decrypted) {
+ if (nvdev->recv_original_buf)
+ vfree(nvdev->recv_original_buf);
+ else
+ vfree(nvdev->recv_buf);
+ }
- if (nvdev->send_original_buf)
- vfree(nvdev->send_original_buf);
- else
- vfree(nvdev->send_buf);
+ if (!nvdev->send_buf_gpadl_handle.decrypted) {
+ if (nvdev->send_original_buf)
+ vfree(nvdev->send_original_buf);
+ else
+ vfree(nvdev->send_buf);
+ }
bitmap_free(nvdev->send_section_map);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0616/1887] Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (614 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0615/1887] hv_netvsc: Dont free decrypted memory Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0617/1887] net/mlx5: Reload only IB representors upon lag disable/enable Greg Kroah-Hartman
` (382 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sungwoo Kim,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sungwoo Kim <iam@sung-woo.kim>
[ Upstream commit a5b862c6a221459d54e494e88965b48dcfa6cc44 ]
l2cap_le_flowctl_init() can cause both div-by-zero and an integer
overflow since hdev->le_mtu may not fall in the valid range.
Move MTU from hci_dev to hci_conn to validate MTU and stop the connection
process earlier if MTU is invalid.
Also, add a missing validation in read_buffer_size() and make it return
an error value if the validation fails.
Now hci_conn_add() returns ERR_PTR() as it can fail due to the both a
kzalloc failure and invalid MTU value.
divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 0 PID: 67 Comm: kworker/u5:0 Tainted: G W 6.9.0-rc5+ #20
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
Workqueue: hci0 hci_rx_work
RIP: 0010:l2cap_le_flowctl_init+0x19e/0x3f0 net/bluetooth/l2cap_core.c:547
Code: e8 17 17 0c 00 66 41 89 9f 84 00 00 00 bf 01 00 00 00 41 b8 02 00 00 00 4c
89 fe 4c 89 e2 89 d9 e8 27 17 0c 00 44 89 f0 31 d2 <66> f7 f3 89 c3 ff c3 4d 8d
b7 88 00 00 00 4c 89 f0 48 c1 e8 03 42
RSP: 0018:ffff88810bc0f858 EFLAGS: 00010246
RAX: 00000000000002a0 RBX: 0000000000000000 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: ffff88810bc0f7c0 RDI: ffffc90002dcb66f
RBP: ffff88810bc0f880 R08: aa69db2dda70ff01 R09: 0000ffaaaaaaaaaa
R10: 0084000000ffaaaa R11: 0000000000000000 R12: ffff88810d65a084
R13: dffffc0000000000 R14: 00000000000002a0 R15: ffff88810d65a000
FS: 0000000000000000(0000) GS:ffff88811ac00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000100 CR3: 0000000103268003 CR4: 0000000000770ef0
PKRU: 55555554
Call Trace:
<TASK>
l2cap_le_connect_req net/bluetooth/l2cap_core.c:4902 [inline]
l2cap_le_sig_cmd net/bluetooth/l2cap_core.c:5420 [inline]
l2cap_le_sig_channel net/bluetooth/l2cap_core.c:5486 [inline]
l2cap_recv_frame+0xe59d/0x11710 net/bluetooth/l2cap_core.c:6809
l2cap_recv_acldata+0x544/0x10a0 net/bluetooth/l2cap_core.c:7506
hci_acldata_packet net/bluetooth/hci_core.c:3939 [inline]
hci_rx_work+0x5e5/0xb20 net/bluetooth/hci_core.c:4176
process_one_work kernel/workqueue.c:3254 [inline]
process_scheduled_works+0x90f/0x1530 kernel/workqueue.c:3335
worker_thread+0x926/0xe70 kernel/workqueue.c:3416
kthread+0x2e3/0x380 kernel/kthread.c:388
ret_from_fork+0x5c/0x90 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
Fixes: 6ed58ec520ad ("Bluetooth: Use LE buffers for LE traffic")
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/bluetooth/hci.h | 9 ++++
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_conn.c | 71 ++++++++++++++++++++++----------
net/bluetooth/hci_event.c | 29 ++++++++-----
net/bluetooth/iso.c | 2 +-
net/bluetooth/l2cap_core.c | 17 ++------
net/bluetooth/sco.c | 6 +--
7 files changed, 85 insertions(+), 50 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index fcab978894b12..473d13f9e5dd6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1532,6 +1532,15 @@ struct hci_cp_le_set_event_mask {
__u8 mask[8];
} __packed;
+/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
+ * 7.8.2 LE Read Buffer Size command
+ * MAX_LE_MTU is 0xffff.
+ * 0 is also valid. It means that no dedicated LE Buffer exists.
+ * It should use the HCI_Read_Buffer_Size command and mtu is shared
+ * between BR/EDR and LE.
+ */
+#define HCI_MIN_LE_MTU 0x001b
+
#define HCI_OP_LE_READ_BUFFER_SIZE 0x2002
struct hci_rp_le_read_buffer_size {
__u8 status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 89721d9ffc68b..1502affe5e5ec 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -675,6 +675,7 @@ struct hci_conn {
__u16 handle;
__u16 sync_handle;
__u16 state;
+ __u16 mtu;
__u8 mode;
__u8 type;
__u8 role;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 55b9f3e713f72..5bc58e465146c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1014,11 +1014,37 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
{
struct hci_conn *conn;
+ switch (type) {
+ case ACL_LINK:
+ if (!hdev->acl_mtu)
+ return ERR_PTR(-ECONNREFUSED);
+ break;
+ case ISO_LINK:
+ if (hdev->iso_mtu)
+ /* Dedicated ISO Buffer exists */
+ break;
+ fallthrough;
+ case LE_LINK:
+ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
+ return ERR_PTR(-ECONNREFUSED);
+ if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
+ return ERR_PTR(-ECONNREFUSED);
+ break;
+ case SCO_LINK:
+ case ESCO_LINK:
+ if (!hdev->sco_pkts)
+ /* Controller does not support SCO or eSCO over HCI */
+ return ERR_PTR(-ECONNREFUSED);
+ break;
+ default:
+ return ERR_PTR(-ECONNREFUSED);
+ }
+
bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle);
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
if (!conn)
- return NULL;
+ return ERR_PTR(-ENOMEM);
bacpy(&conn->dst, dst);
bacpy(&conn->src, &hdev->bdaddr);
@@ -1048,10 +1074,12 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
switch (type) {
case ACL_LINK:
conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
+ conn->mtu = hdev->acl_mtu;
break;
case LE_LINK:
/* conn->src should reflect the local identity address */
hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
+ conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
break;
case ISO_LINK:
/* conn->src should reflect the local identity address */
@@ -1063,6 +1091,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
else if (conn->role == HCI_ROLE_MASTER)
conn->cleanup = cis_cleanup;
+ conn->mtu = hdev->iso_mtu ? hdev->iso_mtu :
+ hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
break;
case SCO_LINK:
if (lmp_esco_capable(hdev))
@@ -1070,9 +1100,12 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
(hdev->esco_type & EDR_ESCO_MASK);
else
conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
+
+ conn->mtu = hdev->sco_mtu;
break;
case ESCO_LINK:
conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
+ conn->mtu = hdev->sco_mtu;
break;
}
@@ -1115,7 +1148,7 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
handle = hci_conn_hash_alloc_unset(hdev);
if (unlikely(handle < 0))
- return NULL;
+ return ERR_PTR(-ECONNREFUSED);
return __hci_conn_add(hdev, type, dst, role, handle);
}
@@ -1386,8 +1419,8 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
bacpy(&conn->dst, dst);
} else {
conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
- if (!conn)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(conn))
+ return conn;
hci_conn_hold(conn);
conn->pending_sec_level = sec_level;
}
@@ -1553,8 +1586,8 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
return ERR_PTR(-EADDRINUSE);
conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
- if (!conn)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(conn))
+ return conn;
set_bit(HCI_CONN_PER_ADV, &conn->flags);
conn->state = BT_CONNECT;
@@ -1598,8 +1631,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
BT_DBG("requesting refresh of dst_addr");
conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
- if (!conn)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(conn))
+ return conn;
if (hci_explicit_conn_params_set(hdev, dst, dst_type) < 0) {
hci_conn_del(conn);
@@ -1646,8 +1679,8 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!acl) {
acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
- if (!acl)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(acl))
+ return acl;
}
hci_conn_hold(acl);
@@ -1677,9 +1710,9 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
if (!sco) {
sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
- if (!sco) {
+ if (IS_ERR(sco)) {
hci_conn_drop(acl);
- return ERR_PTR(-ENOMEM);
+ return sco;
}
}
@@ -1888,8 +1921,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
qos->cis);
if (!cis) {
cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
- if (!cis)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(cis))
+ return cis;
cis->cleanup = cis_cleanup;
cis->dst_type = dst_type;
}
@@ -2069,14 +2102,8 @@ static void hci_iso_qos_setup(struct hci_dev *hdev, struct hci_conn *conn,
struct bt_iso_io_qos *qos, __u8 phy)
{
/* Only set MTU if PHY is enabled */
- if (!qos->sdu && qos->phy) {
- if (hdev->iso_mtu > 0)
- qos->sdu = hdev->iso_mtu;
- else if (hdev->le_mtu > 0)
- qos->sdu = hdev->le_mtu;
- else
- qos->sdu = hdev->acl_mtu;
- }
+ if (!qos->sdu && qos->phy)
+ qos->sdu = conn->mtu;
/* Use the same PHY as ACL if set to any */
if (qos->phy == BT_ISO_PHY_ANY)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c6cf8b348314e..97899057a262c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -939,6 +939,9 @@ static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
+ if (!hdev->acl_mtu || !hdev->acl_pkts)
+ return HCI_ERROR_INVALID_PARAMETERS;
+
return rp->status;
}
@@ -1202,6 +1205,9 @@ static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
+ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
+ return HCI_ERROR_INVALID_PARAMETERS;
+
return rp->status;
}
@@ -2263,8 +2269,8 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
if (!conn) {
conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
HCI_ROLE_MASTER);
- if (!conn)
- bt_dev_err(hdev, "no memory for new connection");
+ if (IS_ERR(conn))
+ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
}
}
@@ -3106,8 +3112,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
BDADDR_BREDR)) {
conn = hci_conn_add_unset(hdev, ev->link_type,
&ev->bdaddr, HCI_ROLE_SLAVE);
- if (!conn) {
- bt_dev_err(hdev, "no memory for new conn");
+ if (IS_ERR(conn)) {
+ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
goto unlock;
}
} else {
@@ -3305,8 +3311,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
if (!conn) {
conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
HCI_ROLE_SLAVE);
- if (!conn) {
- bt_dev_err(hdev, "no memory for new connection");
+ if (IS_ERR(conn)) {
+ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
goto unlock;
}
}
@@ -3785,6 +3791,9 @@ static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
+ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
+ return HCI_ERROR_INVALID_PARAMETERS;
+
return rp->status;
}
@@ -5640,8 +5649,8 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
goto unlock;
conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
- if (!conn) {
- bt_dev_err(hdev, "no memory for new connection");
+ if (IS_ERR(conn)) {
+ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
goto unlock;
}
@@ -6740,7 +6749,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
if (!cis) {
cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
cis_handle);
- if (!cis) {
+ if (IS_ERR(cis)) {
hci_le_reject_cis(hdev, ev->cis_handle);
goto unlock;
}
@@ -6836,7 +6845,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
}
bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
HCI_ROLE_SLAVE, handle);
- if (!bis)
+ if (IS_ERR(bis))
continue;
}
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index d809c5c13319c..bb6e02f7e32e6 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -1103,7 +1103,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg,
return -ENOTCONN;
}
- mtu = iso_pi(sk)->conn->hcon->hdev->iso_mtu;
+ mtu = iso_pi(sk)->conn->hcon->mtu;
release_sock(sk);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 88ddd8eabae93..cdbb8dc3b7267 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6547,7 +6547,7 @@ static int l2cap_finish_move(struct l2cap_chan *chan)
BT_DBG("chan %p", chan);
chan->rx_state = L2CAP_RX_STATE_RECV;
- chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
+ chan->conn->mtu = chan->conn->hcon->mtu;
return l2cap_resegment(chan);
}
@@ -6614,7 +6614,7 @@ static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
*/
chan->next_tx_seq = control->reqseq;
chan->unacked_frames = 0;
- chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
+ chan->conn->mtu = chan->conn->hcon->mtu;
err = l2cap_resegment(chan);
@@ -7213,18 +7213,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
- switch (hcon->type) {
- case LE_LINK:
- if (hcon->hdev->le_mtu) {
- conn->mtu = hcon->hdev->le_mtu;
- break;
- }
- fallthrough;
- default:
- conn->mtu = hcon->hdev->acl_mtu;
- break;
- }
-
+ conn->mtu = hcon->mtu;
conn->feat_mask = 0;
conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index f957a68aafee3..178b1afa35eef 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -135,7 +135,6 @@ static void sco_sock_clear_timer(struct sock *sk)
/* ---- SCO connections ---- */
static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
{
- struct hci_dev *hdev = hcon->hdev;
struct sco_conn *conn = hcon->sco_data;
if (conn) {
@@ -153,9 +152,10 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
hcon->sco_data = conn;
conn->hcon = hcon;
+ conn->mtu = hcon->mtu;
- if (hdev->sco_mtu > 0)
- conn->mtu = hdev->sco_mtu;
+ if (hcon->mtu > 0)
+ conn->mtu = hcon->mtu;
else
conn->mtu = 60;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0617/1887] net/mlx5: Reload only IB representors upon lag disable/enable
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (615 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0616/1887] Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0618/1887] bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE Greg Kroah-Hartman
` (381 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Bloch, Maher Sanalla,
Tariq Toukan, Simon Horman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Sanalla <msanalla@nvidia.com>
[ Upstream commit 0f06228d4a2dcc1fca5b3ddb0eefa09c05b102c4 ]
On lag disable, the bond IB device along with all of its
representors are destroyed, and then the slaves' representors get reloaded.
In case the slave IB representor load fails, the eswitch error flow
unloads all representors, including ethernet representors, where the
netdevs get detached and removed from lag bond. Such flow is inaccurate
as the lag driver is not responsible for loading/unloading ethernet
representors. Furthermore, the flow described above begins by holding
lag lock to prevent bond changes during disable flow. However, when
reaching the ethernet representors detachment from lag, the lag lock is
required again, triggering the following deadlock:
Call trace:
__switch_to+0xf4/0x148
__schedule+0x2c8/0x7d0
schedule+0x50/0xe0
schedule_preempt_disabled+0x18/0x28
__mutex_lock.isra.13+0x2b8/0x570
__mutex_lock_slowpath+0x1c/0x28
mutex_lock+0x4c/0x68
mlx5_lag_remove_netdev+0x3c/0x1a0 [mlx5_core]
mlx5e_uplink_rep_disable+0x70/0xa0 [mlx5_core]
mlx5e_detach_netdev+0x6c/0xb0 [mlx5_core]
mlx5e_netdev_change_profile+0x44/0x138 [mlx5_core]
mlx5e_netdev_attach_nic_profile+0x28/0x38 [mlx5_core]
mlx5e_vport_rep_unload+0x184/0x1b8 [mlx5_core]
mlx5_esw_offloads_rep_load+0xd8/0xe0 [mlx5_core]
mlx5_eswitch_reload_reps+0x74/0xd0 [mlx5_core]
mlx5_disable_lag+0x130/0x138 [mlx5_core]
mlx5_lag_disable_change+0x6c/0x70 [mlx5_core] // hold ldev->lock
mlx5_devlink_eswitch_mode_set+0xc0/0x410 [mlx5_core]
devlink_nl_cmd_eswitch_set_doit+0xdc/0x180
genl_family_rcv_msg_doit.isra.17+0xe8/0x138
genl_rcv_msg+0xe4/0x220
netlink_rcv_skb+0x44/0x108
genl_rcv+0x40/0x58
netlink_unicast+0x198/0x268
netlink_sendmsg+0x1d4/0x418
sock_sendmsg+0x54/0x60
__sys_sendto+0xf4/0x120
__arm64_sys_sendto+0x30/0x40
el0_svc_common+0x8c/0x120
do_el0_svc+0x30/0xa0
el0_svc+0x20/0x30
el0_sync_handler+0x90/0xb8
el0_sync+0x160/0x180
Thus, upon lag enable/disable, load and unload only the IB representors
of the slaves preventing the deadlock mentioned above.
While at it, refactor the mlx5_esw_offloads_rep_load() function to have
a static helper method for its internal logic, in symmetry with the
representor unload design.
Fixes: 598fe77df855 ("net/mlx5: Lag, Create shared FDB when in switchdev mode")
Co-developed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240509112951.590184-4-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 4 +--
.../mellanox/mlx5/core/eswitch_offloads.c | 28 ++++++++++++-------
.../net/ethernet/mellanox/mlx5/core/lag/lag.c | 12 ++++----
3 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 00d169a11a0a8..b410e836169fe 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -746,7 +746,7 @@ int mlx5_eswitch_offloads_config_single_fdb(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw);
void mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw);
-int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
+int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw);
static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
{
@@ -798,7 +798,7 @@ mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw) {}
static inline int
-mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
+mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
{
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 2a64d0fd2fe52..3e2f28c08b2b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -2405,6 +2405,16 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw)
return err;
}
+static int __esw_offloads_load_rep(struct mlx5_eswitch *esw,
+ struct mlx5_eswitch_rep *rep, u8 rep_type)
+{
+ if (atomic_cmpxchg(&rep->rep_data[rep_type].state,
+ REP_REGISTERED, REP_LOADED) == REP_REGISTERED)
+ return esw->offloads.rep_ops[rep_type]->load(esw->dev, rep);
+
+ return 0;
+}
+
static void __esw_offloads_unload_rep(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep, u8 rep_type)
{
@@ -2453,13 +2463,11 @@ int mlx5_esw_offloads_rep_load(struct mlx5_eswitch *esw, u16 vport_num)
int err;
rep = mlx5_eswitch_get_rep(esw, vport_num);
- for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++)
- if (atomic_cmpxchg(&rep->rep_data[rep_type].state,
- REP_REGISTERED, REP_LOADED) == REP_REGISTERED) {
- err = esw->offloads.rep_ops[rep_type]->load(esw->dev, rep);
- if (err)
- goto err_reps;
- }
+ for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
+ err = __esw_offloads_load_rep(esw, rep, rep_type);
+ if (err)
+ goto err_reps;
+ }
return 0;
@@ -3102,7 +3110,7 @@ static void esw_destroy_uplink_offloads_acl_tables(struct mlx5_eswitch *esw)
esw_vport_destroy_offloads_acl_tables(esw, vport);
}
-int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
+int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
{
struct mlx5_eswitch_rep *rep;
unsigned long i;
@@ -3115,13 +3123,13 @@ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED)
return 0;
- ret = mlx5_esw_offloads_rep_load(esw, MLX5_VPORT_UPLINK);
+ ret = __esw_offloads_load_rep(esw, rep, REP_IB);
if (ret)
return ret;
mlx5_esw_for_each_rep(esw, i, rep) {
if (atomic_read(&rep->rep_data[REP_ETH].state) == REP_LOADED)
- mlx5_esw_offloads_rep_load(esw, rep->vport);
+ __esw_offloads_load_rep(esw, rep, REP_IB);
}
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
index 4b4d761081115..e127cbdf2bbf7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -796,9 +796,9 @@ void mlx5_disable_lag(struct mlx5_lag *ldev)
if (shared_fdb) {
if (!(dev0->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
- mlx5_eswitch_reload_reps(dev0->priv.eswitch);
+ mlx5_eswitch_reload_ib_reps(dev0->priv.eswitch);
if (!(dev1->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
- mlx5_eswitch_reload_reps(dev1->priv.eswitch);
+ mlx5_eswitch_reload_ib_reps(dev1->priv.eswitch);
}
}
@@ -898,17 +898,17 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
mlx5_rescan_drivers_locked(dev0);
- err = mlx5_eswitch_reload_reps(dev0->priv.eswitch);
+ err = mlx5_eswitch_reload_ib_reps(dev0->priv.eswitch);
if (!err)
- err = mlx5_eswitch_reload_reps(dev1->priv.eswitch);
+ err = mlx5_eswitch_reload_ib_reps(dev1->priv.eswitch);
if (err) {
dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
mlx5_rescan_drivers_locked(dev0);
mlx5_deactivate_lag(ldev);
mlx5_lag_add_devices(ldev);
- mlx5_eswitch_reload_reps(dev0->priv.eswitch);
- mlx5_eswitch_reload_reps(dev1->priv.eswitch);
+ mlx5_eswitch_reload_ib_reps(dev0->priv.eswitch);
+ mlx5_eswitch_reload_ib_reps(dev1->priv.eswitch);
mlx5_core_err(dev0, "Failed to enable lag\n");
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0618/1887] bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (616 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0617/1887] net/mlx5: Reload only IB representors upon lag disable/enable Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0619/1887] gfs2: Fix potential glock use-after-free on unmount Greg Kroah-Hartman
` (380 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+838346b979830606c854,
Stanislav Fomichev, Eduard Zingerman, Martin KaFai Lau,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislav Fomichev <sdf@google.com>
[ Upstream commit 543576ec15b17c0c93301ac8297333c7b6e84ac7 ]
bpf_prog_attach uses attach_type_to_prog_type to enforce proper
attach type for BPF_PROG_TYPE_CGROUP_SKB. link_create uses
bpf_prog_get and relies on bpf_prog_attach_check_attach_type
to properly verify prog_type <> attach_type association.
Add missing attach_type enforcement for the link_create case.
Otherwise, it's currently possible to attach cgroup_skb prog
types to other cgroup hooks.
Fixes: af6eea57437a ("bpf: Implement bpf_link-based cgroup BPF program attachment")
Link: https://lore.kernel.org/bpf/0000000000004792a90615a1dde0@google.com/
Reported-by: syzbot+838346b979830606c854@syzkaller.appspotmail.com
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20240426231621.2716876-2-sdf@google.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/syscall.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index ec1e0c1a6dd87..e997f7594c975 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3456,9 +3456,14 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
return fd;
}
+static enum bpf_prog_type
+attach_type_to_prog_type(enum bpf_attach_type attach_type);
+
static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
enum bpf_attach_type attach_type)
{
+ enum bpf_prog_type ptype;
+
switch (prog->type) {
case BPF_PROG_TYPE_CGROUP_SOCK:
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
@@ -3471,6 +3476,11 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
* check permissions at attach time.
*/
return -EPERM;
+
+ ptype = attach_type_to_prog_type(attach_type);
+ if (prog->type != ptype)
+ return -EINVAL;
+
return prog->enforce_expected_attach_type &&
prog->expected_attach_type != attach_type ?
-EINVAL : 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0619/1887] gfs2: Fix potential glock use-after-free on unmount
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (617 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0618/1887] bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0620/1887] net: stmmac: move the EST lock to struct stmmac_priv Greg Kroah-Hartman
` (379 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andreas Gruenbacher, David Teigland,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <agruenba@redhat.com>
[ Upstream commit d98779e687726d8f8860f1c54b5687eec5f63a73 ]
When a DLM lockspace is released and there ares still locks in that
lockspace, DLM will unlock those locks automatically. Commit
fb6791d100d1b started exploiting this behavior to speed up filesystem
unmount: gfs2 would simply free glocks it didn't want to unlock and then
release the lockspace. This didn't take the bast callbacks for
asynchronous lock contention notifications into account, which remain
active until until a lock is unlocked or its lockspace is released.
To prevent those callbacks from accessing deallocated objects, put the
glocks that should not be unlocked on the sd_dead_glocks list, release
the lockspace, and only then free those glocks.
As an additional measure, ignore unexpected ast and bast callbacks if
the receiving glock is dead.
Fixes: fb6791d100d1b ("GFS2: skip dlm_unlock calls in unmount")
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Cc: David Teigland <teigland@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/gfs2/glock.c | 35 ++++++++++++++++++++++++++++++++---
fs/gfs2/glock.h | 1 +
fs/gfs2/incore.h | 1 +
fs/gfs2/lock_dlm.c | 12 +++++++++++-
fs/gfs2/ops_fstype.c | 1 +
fs/gfs2/super.c | 3 ---
6 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 428c1db295fa1..d0ec9487e8820 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -167,19 +167,46 @@ static bool glock_blocked_by_withdraw(struct gfs2_glock *gl)
return true;
}
-void gfs2_glock_free(struct gfs2_glock *gl)
+static void __gfs2_glock_free(struct gfs2_glock *gl)
{
- struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
-
gfs2_glock_assert_withdraw(gl, atomic_read(&gl->gl_revokes) == 0);
rhashtable_remove_fast(&gl_hash_table, &gl->gl_node, ht_parms);
smp_mb();
wake_up_glock(gl);
call_rcu(&gl->gl_rcu, gfs2_glock_dealloc);
+}
+
+void gfs2_glock_free(struct gfs2_glock *gl) {
+ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+ __gfs2_glock_free(gl);
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
wake_up(&sdp->sd_glock_wait);
}
+void gfs2_glock_free_later(struct gfs2_glock *gl) {
+ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+ spin_lock(&lru_lock);
+ list_add(&gl->gl_lru, &sdp->sd_dead_glocks);
+ spin_unlock(&lru_lock);
+ if (atomic_dec_and_test(&sdp->sd_glock_disposal))
+ wake_up(&sdp->sd_glock_wait);
+}
+
+static void gfs2_free_dead_glocks(struct gfs2_sbd *sdp)
+{
+ struct list_head *list = &sdp->sd_dead_glocks;
+
+ while(!list_empty(list)) {
+ struct gfs2_glock *gl;
+
+ gl = list_first_entry(list, struct gfs2_glock, gl_lru);
+ list_del_init(&gl->gl_lru);
+ __gfs2_glock_free(gl);
+ }
+}
+
/**
* gfs2_glock_hold() - increment reference count on glock
* @gl: The glock to hold
@@ -2263,6 +2290,8 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
wait_event_timeout(sdp->sd_glock_wait,
atomic_read(&sdp->sd_glock_disposal) == 0,
HZ * 600);
+ gfs2_lm_unmount(sdp);
+ gfs2_free_dead_glocks(sdp);
glock_hash_walk(dump_glock_func, sdp);
}
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index f6dd94ce74998..ca1669cf9299e 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -270,6 +270,7 @@ extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
extern void gfs2_glock_free(struct gfs2_glock *gl);
+extern void gfs2_glock_free_later(struct gfs2_glock *gl);
extern int __init gfs2_glock_init(void);
extern void gfs2_glock_exit(void);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 113aeb5877027..7a630de1c1a0b 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -837,6 +837,7 @@ struct gfs2_sbd {
struct gfs2_holder sd_freeze_gh;
atomic_t sd_freeze_state;
struct mutex sd_freeze_mutex;
+ struct list_head sd_dead_glocks;
char sd_fsname[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2];
char sd_table_name[GFS2_FSNAME_LEN];
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 4f44173e8a361..001555ccceebc 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -121,6 +121,11 @@ static void gdlm_ast(void *arg)
struct gfs2_glock *gl = arg;
unsigned ret = gl->gl_state;
+ /* If the glock is dead, we only react to a dlm_unlock() reply. */
+ if (__lockref_is_dead(&gl->gl_lockref) &&
+ gl->gl_lksb.sb_status != -DLM_EUNLOCK)
+ return;
+
gfs2_update_reply_times(gl);
BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED);
@@ -171,6 +176,9 @@ static void gdlm_bast(void *arg, int mode)
{
struct gfs2_glock *gl = arg;
+ if (__lockref_is_dead(&gl->gl_lockref))
+ return;
+
switch (mode) {
case DLM_LOCK_EX:
gfs2_glock_cb(gl, LM_ST_UNLOCKED);
@@ -291,6 +299,8 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
int error;
+ BUG_ON(!__lockref_is_dead(&gl->gl_lockref));
+
if (gl->gl_lksb.sb_lkid == 0) {
gfs2_glock_free(gl);
return;
@@ -305,7 +315,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
!gl->gl_lksb.sb_lvbptr) {
- gfs2_glock_free(gl);
+ gfs2_glock_free_later(gl);
return;
}
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 26a70b9676d53..ec019e38cf7fa 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -137,6 +137,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
init_waitqueue_head(&sdp->sd_log_flush_wait);
atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
mutex_init(&sdp->sd_freeze_mutex);
+ INIT_LIST_HEAD(&sdp->sd_dead_glocks);
return sdp;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 14b3f66938ea8..4b56a163669ca 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -641,10 +641,7 @@ static void gfs2_put_super(struct super_block *sb)
gfs2_gl_hash_clear(sdp);
truncate_inode_pages_final(&sdp->sd_aspace);
gfs2_delete_debugfs_file(sdp);
- /* Unmount the locking protocol */
- gfs2_lm_unmount(sdp);
- /* At this point, we're through participating in the lockspace */
gfs2_sys_fs_del(sdp);
free_sbd(sdp);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0620/1887] net: stmmac: move the EST lock to struct stmmac_priv
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (618 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0619/1887] gfs2: Fix potential glock use-after-free on unmount Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0621/1887] drm/msm/dpu: Add callback function pointer check before its call Greg Kroah-Hartman
` (378 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiaolei Wang, Simon Horman,
Serge Semin, Andrew Halaney, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaolei Wang <xiaolei.wang@windriver.com>
[ Upstream commit 36ac9e7f2e5786bd37c5cd91132e1f39c29b8197 ]
Reinitialize the whole EST structure would also reset the mutex
lock which is embedded in the EST structure, and then trigger
the following warning. To address this, move the lock to struct
stmmac_priv. We also need to reacquire the mutex lock when doing
this initialization.
DEBUG_LOCKS_WARN_ON(lock->magic != lock)
WARNING: CPU: 3 PID: 505 at kernel/locking/mutex.c:587 __mutex_lock+0xd84/0x1068
Modules linked in:
CPU: 3 PID: 505 Comm: tc Not tainted 6.9.0-rc6-00053-g0106679839f7-dirty #29
Hardware name: NXP i.MX8MPlus EVK board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __mutex_lock+0xd84/0x1068
lr : __mutex_lock+0xd84/0x1068
sp : ffffffc0864e3570
x29: ffffffc0864e3570 x28: ffffffc0817bdc78 x27: 0000000000000003
x26: ffffff80c54f1808 x25: ffffff80c9164080 x24: ffffffc080d723ac
x23: 0000000000000000 x22: 0000000000000002 x21: 0000000000000000
x20: 0000000000000000 x19: ffffffc083bc3000 x18: ffffffffffffffff
x17: ffffffc08117b080 x16: 0000000000000002 x15: ffffff80d2d40000
x14: 00000000000002da x13: ffffff80d2d404b8 x12: ffffffc082b5a5c8
x11: ffffffc082bca680 x10: ffffffc082bb2640 x9 : ffffffc082bb2698
x8 : 0000000000017fe8 x7 : c0000000ffffefff x6 : 0000000000000001
x5 : ffffff8178fe0d48 x4 : 0000000000000000 x3 : 0000000000000027
x2 : ffffff8178fe0d50 x1 : 0000000000000000 x0 : 0000000000000000
Call trace:
__mutex_lock+0xd84/0x1068
mutex_lock_nested+0x28/0x34
tc_setup_taprio+0x118/0x68c
stmmac_setup_tc+0x50/0xf0
taprio_change+0x868/0xc9c
Fixes: b2aae654a479 ("net: stmmac: add mutex lock to protect est parameters")
Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Link: https://lore.kernel.org/r/20240513014346.1718740-2-xiaolei.wang@windriver.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 ++
.../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 8 ++++----
.../net/ethernet/stmicro/stmmac/stmmac_tc.c | 18 ++++++++++--------
include/linux/stmmac.h | 1 -
4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 0b9cc3fbf5d69..7c7ed92094d11 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -243,6 +243,8 @@ struct stmmac_priv {
struct stmmac_extra_stats xstats ____cacheline_aligned_in_smp;
struct stmmac_safety_stats sstats;
struct plat_stmmacenet_data *plat;
+ /* Protect est parameters */
+ struct mutex est_lock;
struct dma_features dma_cap;
struct stmmac_counters mmc;
int hw_cap_support;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index d1ad9161de3ae..db5b03d48afef 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -79,11 +79,11 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
/* If EST is enabled, disabled it before adjust ptp time. */
if (priv->plat->est && priv->plat->est->enable) {
est_rst = true;
- mutex_lock(&priv->plat->est->lock);
+ mutex_lock(&priv->est_lock);
priv->plat->est->enable = false;
stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
}
write_lock_irqsave(&priv->ptp_lock, flags);
@@ -96,7 +96,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
ktime_t current_time_ns, basetime;
u64 cycle_time;
- mutex_lock(&priv->plat->est->lock);
+ mutex_lock(&priv->est_lock);
priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, ¤t_time);
current_time_ns = timespec64_to_ktime(current_time);
time.tv_nsec = priv->plat->est->btr_reserve[0];
@@ -113,7 +113,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
priv->plat->est->enable = true;
ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
if (ret)
netdev_err(priv->dev, "failed to configure EST\n");
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index e9aac51c1b9b7..1ff53ffb05a5a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -1013,17 +1013,19 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
if (!plat->est)
return -ENOMEM;
- mutex_init(&priv->plat->est->lock);
+ mutex_init(&priv->est_lock);
} else {
+ mutex_lock(&priv->est_lock);
memset(plat->est, 0, sizeof(*plat->est));
+ mutex_unlock(&priv->est_lock);
}
size = qopt->num_entries;
- mutex_lock(&priv->plat->est->lock);
+ mutex_lock(&priv->est_lock);
priv->plat->est->gcl_size = size;
priv->plat->est->enable = qopt->enable;
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
for (i = 0; i < size; i++) {
s64 delta_ns = qopt->entries[i].interval;
@@ -1054,7 +1056,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
priv->plat->est->gcl[i] = delta_ns | (gates << wid);
}
- mutex_lock(&priv->plat->est->lock);
+ mutex_lock(&priv->est_lock);
/* Adjust for real system time */
priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, ¤t_time);
current_time_ns = timespec64_to_ktime(current_time);
@@ -1073,7 +1075,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
priv->plat->est->ctr[1] = (u32)ctr;
if (fpe && !priv->dma_cap.fpesel) {
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
return -EOPNOTSUPP;
}
@@ -1084,7 +1086,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
if (ret) {
netdev_err(priv->dev, "failed to configure EST\n");
goto disable;
@@ -1101,11 +1103,11 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
disable:
if (priv->plat->est) {
- mutex_lock(&priv->plat->est->lock);
+ mutex_lock(&priv->est_lock);
priv->plat->est->enable = false;
stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
priv->plat->clk_ptp_rate);
- mutex_unlock(&priv->plat->est->lock);
+ mutex_unlock(&priv->est_lock);
}
priv->plat->fpe_cfg->enable = false;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 06e879cdbff82..ffa2e307ff407 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -115,7 +115,6 @@ struct stmmac_axi {
#define EST_GCL 1024
struct stmmac_est {
- struct mutex lock;
int enable;
u32 btr_reserve[2];
u32 btr_offset[2];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0621/1887] drm/msm/dpu: Add callback function pointer check before its call
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (619 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0620/1887] net: stmmac: move the EST lock to struct stmmac_priv Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0622/1887] fs/ntfs3: Check folio pointer for NULL Greg Kroah-Hartman
` (377 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksandr Mishin, Dmitry Baryshkov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <amishin@t-argos.ru>
[ Upstream commit 530f272053a5e72243a9cb07bb1296af6c346002 ]
In dpu_core_irq_callback_handler() callback function pointer is compared to NULL,
but then callback function is unconditionally called by this pointer.
Fix this bug by adding conditional return.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: c929ac60b3ed ("drm/msm/dpu: allow just single IRQ callback")
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/588237/
Link: https://lore.kernel.org/r/20240408085523.12231-1-amishin@t-argos.ru
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 75e1b89c9eacf..346bb684a35d0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -156,8 +156,10 @@ static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx)
{
VERB("irq_idx=%d\n", irq_idx);
- if (!dpu_kms->hw_intr->irq_tbl[irq_idx].cb)
+ if (!dpu_kms->hw_intr->irq_tbl[irq_idx].cb) {
DRM_ERROR("no registered cb, idx:%d\n", irq_idx);
+ return;
+ }
atomic_inc(&dpu_kms->hw_intr->irq_tbl[irq_idx].count);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0622/1887] fs/ntfs3: Check folio pointer for NULL
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (620 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0621/1887] drm/msm/dpu: Add callback function pointer check before its call Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0623/1887] platform/x86: x86-android-tablets: Unregister devices in reverse order Greg Kroah-Hartman
` (376 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Konstantin Komarov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Upstream commit 1cd6c96219c429ebcfa8e79a865277376c563803 ]
It can be NULL if bmap is called.
Fixes: 82cae269cfa95 ("fs/ntfs3: Add initialization of super block")
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/inode.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index b8ac0943e9325..e38f8fac1130b 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -580,13 +580,18 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo,
}
if (is_resident(ni)) {
- ni_lock(ni);
- err = attr_data_read_resident(ni, page);
- ni_unlock(ni);
-
- if (!err)
- set_buffer_uptodate(bh);
+ bh->b_blocknr = RESIDENT_LCN;
bh->b_size = block_size;
+ if (!page) {
+ err = 0;
+ } else {
+ ni_lock(ni);
+ err = attr_data_read_resident(ni, page);
+ ni_unlock(ni);
+
+ if (!err)
+ set_buffer_uptodate(bh);
+ }
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0623/1887] platform/x86: x86-android-tablets: Unregister devices in reverse order
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (621 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0622/1887] fs/ntfs3: Check folio pointer for NULL Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0624/1887] ext4: refactoring to use the unified helper ext4_quotas_off() Greg Kroah-Hartman
` (375 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hans de Goede, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <hdegoede@redhat.com>
[ Upstream commit 3de0f2627ef849735f155c1818247f58404dddfe ]
Not all subsystems support a device getting removed while there are
still consumers of the device with a reference to the device.
One example of this is the regulator subsystem. If a regulator gets
unregistered while there are still drivers holding a reference
a WARN() at drivers/regulator/core.c:5829 triggers, e.g.:
WARNING: CPU: 1 PID: 1587 at drivers/regulator/core.c:5829 regulator_unregister
Hardware name: Intel Corp. VALLEYVIEW C0 PLATFORM/BYT-T FFD8, BIOS BLADE_21.X64.0005.R00.1504101516 FFD8_X64_R_2015_04_10_1516 04/10/2015
RIP: 0010:regulator_unregister
Call Trace:
<TASK>
regulator_unregister
devres_release_group
i2c_device_remove
device_release_driver_internal
bus_remove_device
device_del
device_unregister
x86_android_tablet_remove
On the Lenovo Yoga Tablet 2 series the bq24190 charger chip also provides
a 5V boost converter output for powering USB devices connected to the micro
USB port, the bq24190-charger driver exports this as a Vbus regulator.
On the 830 (8") and 1050 ("10") models this regulator is controlled by
a platform_device and x86_android_tablet_remove() removes platform_device-s
before i2c_clients so the consumer gets removed first.
But on the 1380 (13") model there is a lc824206xa micro-USB switch
connected over I2C and the extcon driver for that controls the regulator.
The bq24190 i2c-client *must* be registered first, because that creates
the regulator with the lc824206xa listed as its consumer. If the regulator
has not been registered yet the lc824206xa driver will end up getting
a dummy regulator.
Since in this case both the regulator provider and consumer are I2C
devices, the only way to ensure that the consumer is unregistered first
is to unregister the I2C devices in reverse order of in which they were
created.
For consistency and to avoid similar problems in the future change
x86_android_tablet_remove() to unregister all device types in reverse
order.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20240406125058.13624-1-hdegoede@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/x86-android-tablets.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c
index 94710471d7dd2..2063e1ac9d0bd 100644
--- a/drivers/platform/x86/x86-android-tablets.c
+++ b/drivers/platform/x86/x86-android-tablets.c
@@ -1748,19 +1748,19 @@ static void x86_android_tablet_cleanup(void)
{
int i;
- for (i = 0; i < serdev_count; i++) {
+ for (i = serdev_count - 1; i >= 0; i--) {
if (serdevs[i])
serdev_device_remove(serdevs[i]);
}
kfree(serdevs);
- for (i = 0; i < pdev_count; i++)
+ for (i = pdev_count - 1; i >= 0; i--)
platform_device_unregister(pdevs[i]);
kfree(pdevs);
- for (i = 0; i < i2c_client_count; i++)
+ for (i = i2c_client_count - 1; i >= 0; i--)
i2c_unregister_device(i2c_clients[i]);
kfree(i2c_clients);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0624/1887] ext4: refactoring to use the unified helper ext4_quotas_off()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (622 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0623/1887] platform/x86: x86-android-tablets: Unregister devices in reverse order Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0625/1887] ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super() Greg Kroah-Hartman
` (374 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baokun Li, Jan Kara, Theodore Tso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <libaokun1@huawei.com>
[ Upstream commit f3c1c42e0c40656e73f12ab5dcb1110f83ef8e65 ]
Rename ext4_quota_off_umount() to ext4_quotas_off(), and add type
parameter to replace open code in ext4_enable_quotas().
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230327141630.156875-3-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: b4b4fda34e53 ("ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 26 +++++++-------------------
1 file changed, 7 insertions(+), 19 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index f2a569868e416..76c8c364c5dd1 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1167,12 +1167,12 @@ static void dump_orphan_list(struct super_block *sb, struct ext4_sb_info *sbi)
#ifdef CONFIG_QUOTA
static int ext4_quota_off(struct super_block *sb, int type);
-static inline void ext4_quota_off_umount(struct super_block *sb)
+static inline void ext4_quotas_off(struct super_block *sb, int type)
{
- int type;
+ BUG_ON(type > EXT4_MAXQUOTAS);
/* Use our quota_off function to clear inode flags etc. */
- for (type = 0; type < EXT4_MAXQUOTAS; type++)
+ for (type--; type >= 0; type--)
ext4_quota_off(sb, type);
}
@@ -1188,7 +1188,7 @@ static inline char *get_qf_name(struct super_block *sb,
lockdep_is_held(&sb->s_umount));
}
#else
-static inline void ext4_quota_off_umount(struct super_block *sb)
+static inline void ext4_quotas_off(struct super_block *sb, int type)
{
}
#endif
@@ -1283,7 +1283,7 @@ static void ext4_put_super(struct super_block *sb)
ext4_msg(sb, KERN_INFO, "unmounting filesystem.");
ext4_unregister_li_request(sb);
- ext4_quota_off_umount(sb);
+ ext4_quotas_off(sb, EXT4_MAXQUOTAS);
flush_work(&sbi->s_error_work);
destroy_workqueue(sbi->rsv_conversion_wq);
@@ -5605,7 +5605,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
return 0;
failed_mount10:
- ext4_quota_off_umount(sb);
+ ext4_quotas_off(sb, EXT4_MAXQUOTAS);
failed_mount9: __maybe_unused
ext4_release_orphan_info(sb);
failed_mount8:
@@ -7091,20 +7091,8 @@ int ext4_enable_quotas(struct super_block *sb)
"(type=%d, err=%d, ino=%lu). "
"Please run e2fsck to fix.", type,
err, qf_inums[type]);
- for (type--; type >= 0; type--) {
- struct inode *inode;
-
- inode = sb_dqopt(sb)->files[type];
- if (inode)
- inode = igrab(inode);
- dquot_quota_off(sb, type);
- if (inode) {
- lockdep_set_quota_inode(inode,
- I_DATA_SEM_NORMAL);
- iput(inode);
- }
- }
+ ext4_quotas_off(sb, type);
return err;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0625/1887] ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (623 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0624/1887] ext4: refactoring to use the unified helper ext4_quotas_off() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0626/1887] drm/amdgpu: change vm->task_info handling Greg Kroah-Hartman
` (373 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baokun Li, Jan Kara, Theodore Tso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <libaokun1@huawei.com>
[ Upstream commit b4b4fda34e535756f9e774fb2d09c4537b7dfd1c ]
In the following concurrency we will access the uninitialized rs->lock:
ext4_fill_super
ext4_register_sysfs
// sysfs registered msg_ratelimit_interval_ms
// Other processes modify rs->interval to
// non-zero via msg_ratelimit_interval_ms
ext4_orphan_cleanup
ext4_msg(sb, KERN_INFO, "Errors on filesystem, "
__ext4_msg
___ratelimit(&(EXT4_SB(sb)->s_msg_ratelimit_state)
if (!rs->interval) // do nothing if interval is 0
return 1;
raw_spin_trylock_irqsave(&rs->lock, flags)
raw_spin_trylock(lock)
_raw_spin_trylock
__raw_spin_trylock
spin_acquire(&lock->dep_map, 0, 1, _RET_IP_)
lock_acquire
__lock_acquire
register_lock_class
assign_lock_key
dump_stack();
ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10);
raw_spin_lock_init(&rs->lock);
// init rs->lock here
and get the following dump_stack:
=========================================================
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe
you didn't initialize this object before use?
turning off the locking correctness validator.
CPU: 12 PID: 753 Comm: mount Tainted: G E 6.7.0-rc6-next-20231222 #504
[...]
Call Trace:
dump_stack_lvl+0xc5/0x170
dump_stack+0x18/0x30
register_lock_class+0x740/0x7c0
__lock_acquire+0x69/0x13a0
lock_acquire+0x120/0x450
_raw_spin_trylock+0x98/0xd0
___ratelimit+0xf6/0x220
__ext4_msg+0x7f/0x160 [ext4]
ext4_orphan_cleanup+0x665/0x740 [ext4]
__ext4_fill_super+0x21ea/0x2b10 [ext4]
ext4_fill_super+0x14d/0x360 [ext4]
[...]
=========================================================
Normally interval is 0 until s_msg_ratelimit_state is initialized, so
___ratelimit() does nothing. But registering sysfs precedes initializing
rs->lock, so it is possible to change rs->interval to a non-zero value
via the msg_ratelimit_interval_ms interface of sysfs while rs->lock is
uninitialized, and then a call to ext4_msg triggers the problem by
accessing an uninitialized rs->lock. Therefore register sysfs after all
initializations are complete to avoid such problems.
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20240102133730.1098120-1-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 76c8c364c5dd1..828cbf2da05cb 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5547,19 +5547,15 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
if (err)
goto failed_mount6;
- err = ext4_register_sysfs(sb);
- if (err)
- goto failed_mount7;
-
err = ext4_init_orphan_info(sb);
if (err)
- goto failed_mount8;
+ goto failed_mount7;
#ifdef CONFIG_QUOTA
/* Enable quota usage during mount. */
if (ext4_has_feature_quota(sb) && !sb_rdonly(sb)) {
err = ext4_enable_quotas(sb);
if (err)
- goto failed_mount9;
+ goto failed_mount8;
}
#endif /* CONFIG_QUOTA */
@@ -5585,7 +5581,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
ext4_msg(sb, KERN_INFO, "recovery complete");
err = ext4_mark_recovery_complete(sb, es);
if (err)
- goto failed_mount10;
+ goto failed_mount9;
}
if (test_opt(sb, DISCARD) && !bdev_max_discard_sectors(sb->s_bdev))
@@ -5602,15 +5598,17 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
atomic_set(&sbi->s_warning_count, 0);
atomic_set(&sbi->s_msg_count, 0);
+ /* Register sysfs after all initializations are complete. */
+ err = ext4_register_sysfs(sb);
+ if (err)
+ goto failed_mount9;
+
return 0;
-failed_mount10:
+failed_mount9:
ext4_quotas_off(sb, EXT4_MAXQUOTAS);
-failed_mount9: __maybe_unused
+failed_mount8: __maybe_unused
ext4_release_orphan_info(sb);
-failed_mount8:
- ext4_unregister_sysfs(sb);
- kobject_put(&sbi->s_kobj);
failed_mount7:
ext4_unregister_li_request(sb);
failed_mount6:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0626/1887] drm/amdgpu: change vm->task_info handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (624 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0625/1887] ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0627/1887] LoongArch: Update cpu_sibling_map when disabling nonboot CPUs Greg Kroah-Hartman
` (372 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Koenig, Alex Deucher,
Felix Kuehling, Shashank Sharma, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shashank Sharma <shashank.sharma@amd.com>
[ Upstream commit b8f67b9ddf4f8fe6dd536590712b5912ad78f99c ]
This patch changes the handling and lifecycle of vm->task_info object.
The major changes are:
- vm->task_info is a dynamically allocated ptr now, and its uasge is
reference counted.
- introducing two new helper funcs for task_info lifecycle management
- amdgpu_vm_get_task_info: reference counts up task_info before
returning this info
- amdgpu_vm_put_task_info: reference counts down task_info
- last put to task_info() frees task_info from the vm.
This patch also does logistical changes required for existing usage
of vm->task_info.
V2: Do not block all the prints when task_info not found (Felix)
V3: Fixed review comments from Felix
- Fix wrong indentation
- No debug message for -ENOMEM
- Add NULL check for task_info
- Do not duplicate the debug messages (ti vs no ti)
- Get first reference of task_info in vm_init(), put last
in vm_fini()
V4: Fixed review comments from Felix
- fix double reference increment in create_task_info
- change amdgpu_vm_get_task_info_pasid
- additional changes in amdgpu_gem.c while porting
Cc: Christian Koenig <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 9 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 18 ++-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 149 ++++++++++++++------
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 21 ++-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 2 +-
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 25 ++--
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 24 ++--
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 20 ++-
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 24 ++--
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 23 +--
drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 20 +--
12 files changed, 229 insertions(+), 119 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index b80b34b8aa5c4..ffbb0a4ae0de1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1621,9 +1621,14 @@ static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
list_for_each_entry(file, &dev->filelist, lhead) {
struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
+ struct amdgpu_task_info *ti;
+
+ ti = amdgpu_vm_get_task_info_vm(vm);
+ if (ti) {
+ seq_printf(m, "pid:%d\tProcess:%s ----------\n", ti->pid, ti->process_name);
+ amdgpu_vm_put_task_info(ti);
+ }
- seq_printf(m, "pid:%d\tProcess:%s ----------\n",
- vm->task_info.pid, vm->task_info.process_name);
r = amdgpu_bo_reserve(vm->root.bo, true);
if (r)
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index f17577ed6252f..8aaa437a06139 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5170,9 +5170,16 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
tmp_adev->reset_vram_lost = vram_lost;
memset(&tmp_adev->reset_task_info, 0,
sizeof(tmp_adev->reset_task_info));
- if (reset_context->job && reset_context->job->vm)
- tmp_adev->reset_task_info =
- reset_context->job->vm->task_info;
+ if (reset_context->job && reset_context->job->vm) {
+ struct amdgpu_task_info *ti;
+ struct amdgpu_vm *vm = reset_context->job->vm;
+
+ ti = amdgpu_vm_get_task_info_vm(vm);
+ if (ti) {
+ tmp_adev->reset_task_info = *ti;
+ amdgpu_vm_put_task_info(ti);
+ }
+ }
amdgpu_reset_capture_coredumpm(tmp_adev);
#endif
if (vram_lost) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 5a14d51c32d62..d321db549a1e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -35,7 +35,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
{
struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
struct amdgpu_job *job = to_amdgpu_job(s_job);
- struct amdgpu_task_info ti;
+ struct amdgpu_task_info *ti;
struct amdgpu_device *adev = ring->adev;
int idx;
int r;
@@ -48,7 +48,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
return DRM_GPU_SCHED_STAT_ENODEV;
}
- memset(&ti, 0, sizeof(struct amdgpu_task_info));
+
adev->job_hang = true;
if (amdgpu_gpu_recovery &&
@@ -58,12 +58,16 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
goto exit;
}
- amdgpu_vm_get_task_info(ring->adev, job->pasid, &ti);
DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n",
- job->base.sched->name, atomic_read(&ring->fence_drv.last_seq),
- ring->fence_drv.sync_seq);
- DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
- ti.process_name, ti.tgid, ti.task_name, ti.pid);
+ job->base.sched->name, atomic_read(&ring->fence_drv.last_seq),
+ ring->fence_drv.sync_seq);
+
+ ti = amdgpu_vm_get_task_info_pasid(ring->adev, job->pasid);
+ if (ti) {
+ DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
+ ti->process_name, ti->tgid, ti->task_name, ti->pid);
+ amdgpu_vm_put_task_info(ti);
+ }
if (amdgpu_device_should_recover_gpu(ring->adev)) {
struct amdgpu_reset_context reset_context;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 3c07f956381a2..84e5fe9949f18 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2033,6 +2033,108 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
return dma_fence_wait_timeout(vm->last_unlocked, true, timeout);
}
+static void amdgpu_vm_destroy_task_info(struct kref *kref)
+{
+ struct amdgpu_task_info *ti = container_of(kref, struct amdgpu_task_info, refcount);
+
+ kfree(ti);
+}
+
+static inline struct amdgpu_vm *
+amdgpu_vm_get_vm_from_pasid(struct amdgpu_device *adev, u32 pasid)
+{
+ struct amdgpu_vm *vm;
+ unsigned long flags;
+
+ xa_lock_irqsave(&adev->vm_manager.pasids, flags);
+ vm = xa_load(&adev->vm_manager.pasids, pasid);
+ xa_unlock_irqrestore(&adev->vm_manager.pasids, flags);
+
+ return vm;
+}
+
+/**
+ * amdgpu_vm_put_task_info - reference down the vm task_info ptr
+ *
+ * @task_info: task_info struct under discussion.
+ *
+ * frees the vm task_info ptr at the last put
+ */
+void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info)
+{
+ kref_put(&task_info->refcount, amdgpu_vm_destroy_task_info);
+}
+
+/**
+ * amdgpu_vm_get_task_info_vm - Extracts task info for a vm.
+ *
+ * @vm: VM to get info from
+ *
+ * Returns the reference counted task_info structure, which must be
+ * referenced down with amdgpu_vm_put_task_info.
+ */
+struct amdgpu_task_info *
+amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm)
+{
+ struct amdgpu_task_info *ti = NULL;
+
+ if (vm) {
+ ti = vm->task_info;
+ kref_get(&vm->task_info->refcount);
+ }
+
+ return ti;
+}
+
+/**
+ * amdgpu_vm_get_task_info_pasid - Extracts task info for a PASID.
+ *
+ * @adev: drm device pointer
+ * @pasid: PASID identifier for VM
+ *
+ * Returns the reference counted task_info structure, which must be
+ * referenced down with amdgpu_vm_put_task_info.
+ */
+struct amdgpu_task_info *
+amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid)
+{
+ return amdgpu_vm_get_task_info_vm(
+ amdgpu_vm_get_vm_from_pasid(adev, pasid));
+}
+
+static int amdgpu_vm_create_task_info(struct amdgpu_vm *vm)
+{
+ vm->task_info = kzalloc(sizeof(struct amdgpu_task_info), GFP_KERNEL);
+ if (!vm->task_info)
+ return -ENOMEM;
+
+ kref_init(&vm->task_info->refcount);
+ return 0;
+}
+
+/**
+ * amdgpu_vm_set_task_info - Sets VMs task info.
+ *
+ * @vm: vm for which to set the info
+ */
+void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
+{
+ if (!vm->task_info)
+ return;
+
+ if (vm->task_info->pid == current->pid)
+ return;
+
+ vm->task_info->pid = current->pid;
+ get_task_comm(vm->task_info->task_name, current);
+
+ if (current->group_leader->mm != current->mm)
+ return;
+
+ vm->task_info->tgid = current->group_leader->pid;
+ get_task_comm(vm->task_info->process_name, current->group_leader);
+}
+
/**
* amdgpu_vm_init - initialize a vm instance
*
@@ -2120,6 +2222,10 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
if (r)
goto error_unreserve;
+ r = amdgpu_vm_create_task_info(vm);
+ if (r)
+ DRM_DEBUG("Failed to create task info for VM\n");
+
amdgpu_bo_unreserve(vm->root.bo);
INIT_KFIFO(vm->faults);
@@ -2270,6 +2376,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
root = amdgpu_bo_ref(vm->root.bo);
amdgpu_bo_reserve(root, true);
+ amdgpu_vm_put_task_info(vm->task_info);
amdgpu_vm_set_pasid(adev, vm, 0);
dma_fence_wait(vm->last_unlocked, false);
dma_fence_put(vm->last_unlocked);
@@ -2434,48 +2541,6 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return 0;
}
-/**
- * amdgpu_vm_get_task_info - Extracts task info for a PASID.
- *
- * @adev: drm device pointer
- * @pasid: PASID identifier for VM
- * @task_info: task_info to fill.
- */
-void amdgpu_vm_get_task_info(struct amdgpu_device *adev, u32 pasid,
- struct amdgpu_task_info *task_info)
-{
- struct amdgpu_vm *vm;
- unsigned long flags;
-
- xa_lock_irqsave(&adev->vm_manager.pasids, flags);
-
- vm = xa_load(&adev->vm_manager.pasids, pasid);
- if (vm)
- *task_info = vm->task_info;
-
- xa_unlock_irqrestore(&adev->vm_manager.pasids, flags);
-}
-
-/**
- * amdgpu_vm_set_task_info - Sets VMs task info.
- *
- * @vm: vm for which to set the info
- */
-void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
-{
- if (vm->task_info.pid)
- return;
-
- vm->task_info.pid = current->pid;
- get_task_comm(vm->task_info.task_name, current);
-
- if (current->group_leader->mm != current->mm)
- return;
-
- vm->task_info.tgid = current->group_leader->pid;
- get_task_comm(vm->task_info.process_name, current->group_leader);
-}
-
/**
* amdgpu_vm_handle_fault - graceful handling of VM faults.
* @adev: amdgpu device pointer
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 6546e786bf008..ac2f8a043bc1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -174,10 +174,11 @@ struct amdgpu_vm_pte_funcs {
};
struct amdgpu_task_info {
- char process_name[TASK_COMM_LEN];
- char task_name[TASK_COMM_LEN];
- pid_t pid;
- pid_t tgid;
+ char process_name[TASK_COMM_LEN];
+ char task_name[TASK_COMM_LEN];
+ pid_t pid;
+ pid_t tgid;
+ struct kref refcount;
};
/**
@@ -323,7 +324,7 @@ struct amdgpu_vm {
uint64_t pd_phys_addr;
/* Some basic info about the task */
- struct amdgpu_task_info task_info;
+ struct amdgpu_task_info *task_info;
/* Store positions of group of BOs */
struct ttm_lru_bulk_move lru_bulk_move;
@@ -452,8 +453,14 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
struct amdgpu_job *job);
void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev);
-void amdgpu_vm_get_task_info(struct amdgpu_device *adev, u32 pasid,
- struct amdgpu_task_info *task_info);
+struct amdgpu_task_info *
+amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid);
+
+struct amdgpu_task_info *
+amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm);
+
+void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info);
+
bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
uint64_t addr, bool write_fault);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
index 370d02bdde862..c9930abada8d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -978,7 +978,7 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
trace_amdgpu_vm_update_ptes(params, frag_start, upd_end,
min(nptes, 32u), dst, incr,
upd_flags,
- vm->task_info.tgid,
+ vm->task_info ? vm->task_info->tgid : 0,
vm->immediate.fence_context);
amdgpu_vm_pte_update_flags(params, to_amdgpu_bo_vm(pt),
cursor.level, pe_start, dst,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 918cf169cb951..5cdecf52fda69 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -100,7 +100,7 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
bool retry_fault = !!(entry->src_data[1] & 0x80);
bool write_fault = !!(entry->src_data[1] & 0x20);
struct amdgpu_vmhub *hub = &adev->vmhub[entry->vmid_src];
- struct amdgpu_task_info task_info;
+ struct amdgpu_task_info *task_info;
uint32_t status = 0;
u64 addr;
@@ -148,19 +148,22 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
if (!printk_ratelimit())
return 0;
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
-
dev_err(adev->dev,
- "[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u, "
- "for process %s pid %d thread %s pid %d)\n",
+ "[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n",
entry->vmid_src ? "mmhub" : "gfxhub",
- entry->src_id, entry->ring_id, entry->vmid,
- entry->pasid, task_info.process_name, task_info.tgid,
- task_info.task_name, task_info.pid);
+ entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
+ task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
+ if (task_info) {
+ dev_err(adev->dev,
+ " in process %s pid %d thread %s pid %d\n",
+ task_info->process_name, task_info->tgid,
+ task_info->task_name, task_info->pid);
+ amdgpu_vm_put_task_info(task_info);
+ }
+
dev_err(adev->dev, " in page starting at address 0x%016llx from client 0x%x (%s)\n",
- addr, entry->client_id,
- soc15_ih_clientid_name[entry->client_id]);
+ addr, entry->client_id,
+ soc15_ih_clientid_name[entry->client_id]);
if (!amdgpu_sriov_vf(adev))
hub->vmhub_funcs->print_l2_protection_fault_status(adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index 310a5607d83b6..db50f2ab7ec43 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -106,20 +106,24 @@ static int gmc_v11_0_process_interrupt(struct amdgpu_device *adev,
}
if (printk_ratelimit()) {
- struct amdgpu_task_info task_info;
-
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
+ struct amdgpu_task_info *task_info;
dev_err(adev->dev,
- "[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u, "
- "for process %s pid %d thread %s pid %d)\n",
+ "[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n",
entry->vmid_src ? "mmhub" : "gfxhub",
- entry->src_id, entry->ring_id, entry->vmid,
- entry->pasid, task_info.process_name, task_info.tgid,
- task_info.task_name, task_info.pid);
+ entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
+ task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
+ if (task_info) {
+ dev_err(adev->dev,
+ " in process %s pid %d thread %s pid %d)\n",
+ task_info->process_name, task_info->tgid,
+ task_info->task_name, task_info->pid);
+ amdgpu_vm_put_task_info(task_info);
+ }
+
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
- addr, entry->client_id);
+ addr, entry->client_id);
+
if (!amdgpu_sriov_vf(adev))
hub->vmhub_funcs->print_l2_protection_fault_status(adev, status);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index c17a36504d17b..4cd8ee614753c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -1461,18 +1461,24 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
gmc_v8_0_set_fault_enable_default(adev, false);
if (printk_ratelimit()) {
- struct amdgpu_task_info task_info;
+ struct amdgpu_task_info *task_info;
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
+ dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n",
+ entry->src_id, entry->src_data[0]);
+
+ task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
+ if (task_info) {
+ dev_err(adev->dev, " for process %s pid %d thread %s pid %d\n",
+ task_info->process_name, task_info->tgid,
+ task_info->task_name, task_info->pid);
+ amdgpu_vm_put_task_info(task_info);
+ }
- dev_err(adev->dev, "GPU fault detected: %d 0x%08x for process %s pid %d thread %s pid %d\n",
- entry->src_id, entry->src_data[0], task_info.process_name,
- task_info.tgid, task_info.task_name, task_info.pid);
dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
- addr);
+ addr);
dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
status);
+
gmc_v8_0_vm_decode_fault(adev, status, addr, mc_client,
entry->pasid);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 3e631aefa7917..5b26ef0df5e2d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -532,7 +532,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
bool retry_fault = !!(entry->src_data[1] & 0x80);
bool write_fault = !!(entry->src_data[1] & 0x20);
uint32_t status = 0, cid = 0, rw = 0;
- struct amdgpu_task_info task_info;
+ struct amdgpu_task_info *task_info;
struct amdgpu_vmhub *hub;
const char *mmhub_cid;
const char *hub_name;
@@ -579,16 +579,20 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
hub = &adev->vmhub[AMDGPU_GFXHUB_0];
}
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
-
dev_err(adev->dev,
- "[%s] %s page fault (src_id:%u ring:%u vmid:%u "
- "pasid:%u, for process %s pid %d thread %s pid %d)\n",
- hub_name, retry_fault ? "retry" : "no-retry",
- entry->src_id, entry->ring_id, entry->vmid,
- entry->pasid, task_info.process_name, task_info.tgid,
- task_info.task_name, task_info.pid);
+ "[%s] %s page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n", hub_name,
+ retry_fault ? "retry" : "no-retry",
+ entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
+
+ task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
+ if (task_info) {
+ dev_err(adev->dev,
+ " for process %s pid %d thread %s pid %d)\n",
+ task_info->process_name, task_info->tgid,
+ task_info->task_name, task_info->pid);
+ amdgpu_vm_put_task_info(task_info);
+ }
+
dev_err(adev->dev, " in page starting at address 0x%016llx from IH client 0x%x (%s)\n",
addr, entry->client_id,
soc15_ih_clientid_name[entry->client_id]);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index d029984eb9a14..16fb6f8af8727 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -2133,7 +2133,7 @@ static int sdma_v4_0_print_iv_entry(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry)
{
int instance;
- struct amdgpu_task_info task_info;
+ struct amdgpu_task_info *task_info;
u64 addr;
instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
@@ -2145,15 +2145,20 @@ static int sdma_v4_0_print_iv_entry(struct amdgpu_device *adev,
addr = (u64)entry->src_data[0] << 12;
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
-
dev_dbg_ratelimited(adev->dev,
- "[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u "
- "pasid:%u, for process %s pid %d thread %s pid %d\n",
- instance, addr, entry->src_id, entry->ring_id, entry->vmid,
- entry->pasid, task_info.process_name, task_info.tgid,
- task_info.task_name, task_info.pid);
+ "[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u pasid:%u\n",
+ instance, addr, entry->src_id, entry->ring_id, entry->vmid,
+ entry->pasid);
+
+ task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
+ if (task_info) {
+ dev_dbg_ratelimited(adev->dev,
+ " for process %s pid %d thread %s pid %d\n",
+ task_info->process_name, task_info->tgid,
+ task_info->task_name, task_info->pid);
+ amdgpu_vm_put_task_info(task_info);
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
index 0472b56de2457..7640fb76884ff 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
@@ -238,16 +238,16 @@ void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev,
void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid)
{
- struct amdgpu_task_info task_info;
-
- memset(&task_info, 0, sizeof(struct amdgpu_task_info));
- amdgpu_vm_get_task_info(dev->adev, pasid, &task_info);
- /* Report VM faults from user applications, not retry from kernel */
- if (!task_info.pid)
- return;
-
- kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, "%x:%s\n",
- task_info.pid, task_info.task_name);
+ struct amdgpu_task_info *task_info;
+
+ task_info = amdgpu_vm_get_task_info_pasid(dev->adev, pasid);
+ if (task_info) {
+ /* Report VM faults from user applications, not retry from kernel */
+ if (task_info->pid)
+ kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, "%x:%s\n",
+ task_info->pid, task_info->task_name);
+ amdgpu_vm_put_task_info(task_info);
+ }
}
void kfd_smi_event_page_fault_start(struct kfd_dev *dev, pid_t pid,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0627/1887] LoongArch: Update cpu_sibling_map when disabling nonboot CPUs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (625 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0626/1887] drm/amdgpu: change vm->task_info handling Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0628/1887] fork: defer linking file vma until vma is fully initialized Greg Kroah-Hartman
` (371 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Huacai Chen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <chenhuacai@loongson.cn>
[ Upstream commit 752cd08da320a667a833803a8fd6bb266114cce5 ]
Update cpu_sibling_map when disabling nonboot CPUs by defining & calling
clear_cpu_sibling_map(), otherwise we get such errors on SMT systems:
jump label: negative count!
WARNING: CPU: 6 PID: 45 at kernel/jump_label.c:263 __static_key_slow_dec_cpuslocked+0xec/0x100
CPU: 6 PID: 45 Comm: cpuhp/6 Not tainted 6.8.0-rc5+ #1340
pc 90000000004c302c ra 90000000004c302c tp 90000001005bc000 sp 90000001005bfd20
a0 000000000000001b a1 900000000224c278 a2 90000001005bfb58 a3 900000000224c280
a4 900000000224c278 a5 90000001005bfb50 a6 0000000000000001 a7 0000000000000001
t0 ce87a4763eb5234a t1 ce87a4763eb5234a t2 0000000000000000 t3 0000000000000000
t4 0000000000000006 t5 0000000000000000 t6 0000000000000064 t7 0000000000001964
t8 000000000009ebf6 u0 9000000001f2a068 s9 0000000000000000 s0 900000000246a2d8
s1 ffffffffffffffff s2 ffffffffffffffff s3 90000000021518c0 s4 0000000000000040
s5 9000000002151058 s6 9000000009828e40 s7 00000000000000b4 s8 0000000000000006
ra: 90000000004c302c __static_key_slow_dec_cpuslocked+0xec/0x100
ERA: 90000000004c302c __static_key_slow_dec_cpuslocked+0xec/0x100
CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
PRMD: 00000004 (PPLV0 +PIE -PWE)
EUEN: 00000000 (-FPE -SXE -ASXE -BTE)
ECFG: 00071c1c (LIE=2-4,10-12 VS=7)
ESTAT: 000c0000 [BRK] (IS= ECode=12 EsubCode=0)
PRID: 0014d000 (Loongson-64bit, Loongson-3A6000-HV)
CPU: 6 PID: 45 Comm: cpuhp/6 Not tainted 6.8.0-rc5+ #1340
Stack : 0000000000000000 900000000203f258 900000000179afc8 90000001005bc000
90000001005bf980 0000000000000000 90000001005bf988 9000000001fe0be0
900000000224c280 900000000224c278 90000001005bf8c0 0000000000000001
0000000000000001 ce87a4763eb5234a 0000000007f38000 90000001003f8cc0
0000000000000000 0000000000000006 0000000000000000 4c206e6f73676e6f
6f4c203a656d616e 000000000009ec99 0000000007f38000 0000000000000000
900000000214b000 9000000001fe0be0 0000000000000004 0000000000000000
0000000000000107 0000000000000009 ffffffffffafdabe 00000000000000b4
0000000000000006 90000000004c302c 9000000000224528 00005555939a0c7c
00000000000000b0 0000000000000004 0000000000000000 0000000000071c1c
...
Call Trace:
[<9000000000224528>] show_stack+0x48/0x1a0
[<900000000179afc8>] dump_stack_lvl+0x78/0xa0
[<9000000000263ed0>] __warn+0x90/0x1a0
[<90000000017419b8>] report_bug+0x1b8/0x280
[<900000000179c564>] do_bp+0x264/0x420
[<90000000004c302c>] __static_key_slow_dec_cpuslocked+0xec/0x100
[<90000000002b4d7c>] sched_cpu_deactivate+0x2fc/0x300
[<9000000000266498>] cpuhp_invoke_callback+0x178/0x8a0
[<9000000000267f70>] cpuhp_thread_fun+0xf0/0x240
[<90000000002a117c>] smpboot_thread_fn+0x1dc/0x2e0
[<900000000029a720>] kthread+0x140/0x160
[<9000000000222288>] ret_from_kernel_thread+0xc/0xa4
Cc: stable@vger.kernel.org
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/kernel/smp.c | 129 ++++++++++++++++++++----------------
1 file changed, 72 insertions(+), 57 deletions(-)
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index 356918d5aa28f..671e660746c01 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -89,6 +89,77 @@ void show_ipi_list(struct seq_file *p, int prec)
}
}
+static inline void set_cpu_core_map(int cpu)
+{
+ int i;
+
+ cpumask_set_cpu(cpu, &cpu_core_setup_map);
+
+ for_each_cpu(i, &cpu_core_setup_map) {
+ if (cpu_data[cpu].package == cpu_data[i].package) {
+ cpumask_set_cpu(i, &cpu_core_map[cpu]);
+ cpumask_set_cpu(cpu, &cpu_core_map[i]);
+ }
+ }
+}
+
+static inline void set_cpu_sibling_map(int cpu)
+{
+ int i;
+
+ cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
+
+ if (smp_num_siblings <= 1)
+ cpumask_set_cpu(cpu, &cpu_sibling_map[cpu]);
+ else {
+ for_each_cpu(i, &cpu_sibling_setup_map) {
+ if (cpus_are_siblings(cpu, i)) {
+ cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
+ cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
+ }
+ }
+ }
+}
+
+static inline void clear_cpu_sibling_map(int cpu)
+{
+ int i;
+
+ for_each_cpu(i, &cpu_sibling_setup_map) {
+ if (cpus_are_siblings(cpu, i)) {
+ cpumask_clear_cpu(i, &cpu_sibling_map[cpu]);
+ cpumask_clear_cpu(cpu, &cpu_sibling_map[i]);
+ }
+ }
+
+ cpumask_clear_cpu(cpu, &cpu_sibling_setup_map);
+}
+
+/*
+ * Calculate a new cpu_foreign_map mask whenever a
+ * new cpu appears or disappears.
+ */
+void calculate_cpu_foreign_map(void)
+{
+ int i, k, core_present;
+ cpumask_t temp_foreign_map;
+
+ /* Re-calculate the mask */
+ cpumask_clear(&temp_foreign_map);
+ for_each_online_cpu(i) {
+ core_present = 0;
+ for_each_cpu(k, &temp_foreign_map)
+ if (cpus_are_siblings(i, k))
+ core_present = 1;
+ if (!core_present)
+ cpumask_set_cpu(i, &temp_foreign_map);
+ }
+
+ for_each_online_cpu(i)
+ cpumask_andnot(&cpu_foreign_map[i],
+ &temp_foreign_map, &cpu_sibling_map[i]);
+}
+
/* Send mailbox buffer via Mail_Send */
static void csr_mail_send(uint64_t data, int cpu, int mailbox)
{
@@ -263,6 +334,7 @@ int loongson_cpu_disable(void)
numa_remove_cpu(cpu);
#endif
set_cpu_online(cpu, false);
+ clear_cpu_sibling_map(cpu);
calculate_cpu_foreign_map();
local_irq_save(flags);
irq_migrate_all_off_this_cpu();
@@ -340,63 +412,6 @@ static int __init ipi_pm_init(void)
core_initcall(ipi_pm_init);
#endif
-static inline void set_cpu_sibling_map(int cpu)
-{
- int i;
-
- cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
-
- if (smp_num_siblings <= 1)
- cpumask_set_cpu(cpu, &cpu_sibling_map[cpu]);
- else {
- for_each_cpu(i, &cpu_sibling_setup_map) {
- if (cpus_are_siblings(cpu, i)) {
- cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
- cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
- }
- }
- }
-}
-
-static inline void set_cpu_core_map(int cpu)
-{
- int i;
-
- cpumask_set_cpu(cpu, &cpu_core_setup_map);
-
- for_each_cpu(i, &cpu_core_setup_map) {
- if (cpu_data[cpu].package == cpu_data[i].package) {
- cpumask_set_cpu(i, &cpu_core_map[cpu]);
- cpumask_set_cpu(cpu, &cpu_core_map[i]);
- }
- }
-}
-
-/*
- * Calculate a new cpu_foreign_map mask whenever a
- * new cpu appears or disappears.
- */
-void calculate_cpu_foreign_map(void)
-{
- int i, k, core_present;
- cpumask_t temp_foreign_map;
-
- /* Re-calculate the mask */
- cpumask_clear(&temp_foreign_map);
- for_each_online_cpu(i) {
- core_present = 0;
- for_each_cpu(k, &temp_foreign_map)
- if (cpus_are_siblings(i, k))
- core_present = 1;
- if (!core_present)
- cpumask_set_cpu(i, &temp_foreign_map);
- }
-
- for_each_online_cpu(i)
- cpumask_andnot(&cpu_foreign_map[i],
- &temp_foreign_map, &cpu_sibling_map[i]);
-}
-
/* Preload SMP state for boot cpu */
void smp_prepare_boot_cpu(void)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0628/1887] fork: defer linking file vma until vma is fully initialized
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (626 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0627/1887] LoongArch: Update cpu_sibling_map when disabling nonboot CPUs Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0629/1887] sched/deadline: Fix task_struct reference leak Greg Kroah-Hartman
` (370 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miaohe Lin, Thorvald Natvig,
Jane Chu, Christian Brauner, Heiko Carstens, Kent Overstreet,
Liam R. Howlett, Mateusz Guzik, Matthew Wilcox (Oracle),
Muchun Song, Oleg Nesterov, Peng Zhang, Tycho Andersen,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaohe Lin <linmiaohe@huawei.com>
[ Upstream commit 35e351780fa9d8240dd6f7e4f245f9ea37e96c19 ]
Thorvald reported a WARNING [1]. And the root cause is below race:
CPU 1 CPU 2
fork hugetlbfs_fallocate
dup_mmap hugetlbfs_punch_hole
i_mmap_lock_write(mapping);
vma_interval_tree_insert_after -- Child vma is visible through i_mmap tree.
i_mmap_unlock_write(mapping);
hugetlb_dup_vma_private -- Clear vma_lock outside i_mmap_rwsem!
i_mmap_lock_write(mapping);
hugetlb_vmdelete_list
vma_interval_tree_foreach
hugetlb_vma_trylock_write -- Vma_lock is cleared.
tmp->vm_ops->open -- Alloc new vma_lock outside i_mmap_rwsem!
hugetlb_vma_unlock_write -- Vma_lock is assigned!!!
i_mmap_unlock_write(mapping);
hugetlb_dup_vma_private() and hugetlb_vm_op_open() are called outside
i_mmap_rwsem lock while vma lock can be used in the same time. Fix this
by deferring linking file vma until vma is fully initialized. Those vmas
should be initialized first before they can be used.
Link: https://lkml.kernel.org/r/20240410091441.3539905-1-linmiaohe@huawei.com
Fixes: 8d9bfb260814 ("hugetlb: add vma based lock for pmd sharing")
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Reported-by: Thorvald Natvig <thorvald@google.com>
Closes: https://lore.kernel.org/linux-mm/20240129161735.6gmjsswx62o4pbja@revolver/T/ [1]
Reviewed-by: Jane Chu <jane.chu@oracle.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peng Zhang <zhangpeng.00@bytedance.com>
Cc: Tycho Andersen <tandersen@netflix.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/fork.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 39b8483e07003..1a480f30ca985 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -669,6 +669,24 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
} else if (anon_vma_fork(tmp, mpnt))
goto fail_nomem_anon_vma_fork;
tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT);
+ /*
+ * Copy/update hugetlb private vma information.
+ */
+ if (is_vm_hugetlb_page(tmp))
+ hugetlb_dup_vma_private(tmp);
+
+ /* Link the vma into the MT */
+ mas.index = tmp->vm_start;
+ mas.last = tmp->vm_end - 1;
+ mas_store(&mas, tmp);
+ if (mas_is_err(&mas))
+ goto fail_nomem_mas_store;
+
+ mm->map_count++;
+
+ if (tmp->vm_ops && tmp->vm_ops->open)
+ tmp->vm_ops->open(tmp);
+
file = tmp->vm_file;
if (file) {
struct address_space *mapping = file->f_mapping;
@@ -685,26 +703,9 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
i_mmap_unlock_write(mapping);
}
- /*
- * Copy/update hugetlb private vma information.
- */
- if (is_vm_hugetlb_page(tmp))
- hugetlb_dup_vma_private(tmp);
-
- /* Link the vma into the MT */
- mas.index = tmp->vm_start;
- mas.last = tmp->vm_end - 1;
- mas_store(&mas, tmp);
- if (mas_is_err(&mas))
- goto fail_nomem_mas_store;
-
- mm->map_count++;
if (!(tmp->vm_flags & VM_WIPEONFORK))
retval = copy_page_range(tmp, mpnt);
- if (tmp->vm_ops && tmp->vm_ops->open)
- tmp->vm_ops->open(tmp);
-
if (retval)
goto loop_out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0629/1887] sched/deadline: Fix task_struct reference leak
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (627 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0628/1887] fork: defer linking file vma until vma is fully initialized Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0630/1887] f2fs: fix to shrink read extent node in batches Greg Kroah-Hartman
` (369 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wander Lairson Costa,
Peter Zijlstra (Intel), Juri Lelli, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wander Lairson Costa <wander@redhat.com>
[ Upstream commit b58652db66c910c2245f5bee7deca41c12d707b9 ]
During the execution of the following stress test with linux-rt:
stress-ng --cyclic 30 --timeout 30 --minimize --quiet
kmemleak frequently reported a memory leak concerning the task_struct:
unreferenced object 0xffff8881305b8000 (size 16136):
comm "stress-ng", pid 614, jiffies 4294883961 (age 286.412s)
object hex dump (first 32 bytes):
02 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .@..............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
debug hex dump (first 16 bytes):
53 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 S...............
backtrace:
[<00000000046b6790>] dup_task_struct+0x30/0x540
[<00000000c5ca0f0b>] copy_process+0x3d9/0x50e0
[<00000000ced59777>] kernel_clone+0xb0/0x770
[<00000000a50befdc>] __do_sys_clone+0xb6/0xf0
[<000000001dbf2008>] do_syscall_64+0x5d/0xf0
[<00000000552900ff>] entry_SYSCALL_64_after_hwframe+0x6e/0x76
The issue occurs in start_dl_timer(), which increments the task_struct
reference count and sets a timer. The timer callback, dl_task_timer,
is supposed to decrement the reference count upon expiration. However,
if enqueue_task_dl() is called before the timer expires and cancels it,
the reference count is not decremented, leading to the leak.
This patch fixes the reference leak by ensuring the task_struct
reference count is properly decremented when the timer is canceled.
Fixes: feff2e65efd8 ("sched/deadline: Unthrottle PI boosted threads while enqueuing")
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Juri Lelli <juri.lelli@redhat.com>
Link: https://lore.kernel.org/r/20240620125618.11419-1-wander@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/deadline.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 62a7c4ed86753..83204e5b780e4 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1689,8 +1689,12 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
* The replenish timer needs to be canceled. No
* problem if it fires concurrently: boosted threads
* are ignored in dl_task_timer().
+ *
+ * If the timer callback was running (hrtimer_try_to_cancel == -1),
+ * it will eventually call put_task_struct().
*/
- hrtimer_try_to_cancel(&p->dl.dl_timer);
+ if (hrtimer_try_to_cancel(&p->dl.dl_timer) == 1)
+ put_task_struct(p);
p->dl.dl_throttled = 0;
}
} else if (!dl_prio(p->normal_prio)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0630/1887] f2fs: fix to shrink read extent node in batches
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (628 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0629/1887] sched/deadline: Fix task_struct reference leak Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0631/1887] drm/amdgpu: fix double free err_addr pointer warnings Greg Kroah-Hartman
` (368 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiuhong Wang, Zhiguo Niu, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 3fc5d5a182f6a1f8bd4dc775feb54c369dd2c343 ]
We use rwlock to protect core structure data of extent tree during
its shrink, however, if there is a huge number of extent nodes in
extent tree, during shrink of extent tree, it may hold rwlock for
a very long time, which may trigger kernel hang issue.
This patch fixes to shrink read extent node in batches, so that,
critical region of the rwlock can be shrunk to avoid its extreme
long time hold.
Reported-by: Xiuhong Wang <xiuhong.wang@unisoc.com>
Closes: https://lore.kernel.org/linux-f2fs-devel/20241112110627.1314632-1-xiuhong.wang@unisoc.com/
Signed-off-by: Xiuhong Wang <xiuhong.wang@unisoc.com>
Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/extent_cache.c | 67 ++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 28 deletions(-)
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index e66c5d0a04dff..0b35892e9eb6c 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -403,21 +403,22 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode,
}
static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
- struct extent_tree *et)
+ struct extent_tree *et, unsigned int nr_shrink)
{
struct rb_node *node, *next;
struct extent_node *en;
- unsigned int count = atomic_read(&et->node_cnt);
+ unsigned int count;
node = rb_first_cached(&et->root);
- while (node) {
+
+ for (count = 0; node && count < nr_shrink; count++) {
next = rb_next(node);
en = rb_entry(node, struct extent_node, rb_node);
__release_extent_node(sbi, et, en);
node = next;
}
- return count - atomic_read(&et->node_cnt);
+ return count;
}
static void __drop_largest_extent(struct extent_tree *et,
@@ -611,6 +612,28 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
return en;
}
+static unsigned int __destroy_extent_node(struct inode *inode,
+ enum extent_type type)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct extent_tree *et = F2FS_I(inode)->extent_tree[type];
+ unsigned int nr_shrink = READ_EXTENT_CACHE_SHRINK_NUMBER;
+ unsigned int node_cnt = 0;
+
+ if (!et || !atomic_read(&et->node_cnt))
+ return 0;
+
+ while (atomic_read(&et->node_cnt)) {
+ write_lock(&et->lock);
+ node_cnt += __free_extent_tree(sbi, et, nr_shrink);
+ write_unlock(&et->lock);
+ }
+
+ f2fs_bug_on(sbi, atomic_read(&et->node_cnt));
+
+ return node_cnt;
+}
+
static void __update_extent_tree_range(struct inode *inode,
struct extent_info *tei, enum extent_type type)
{
@@ -740,9 +763,6 @@ static void __update_extent_tree_range(struct inode *inode,
}
}
- if (is_inode_flag_set(inode, FI_NO_EXTENT))
- __free_extent_tree(sbi, et);
-
if (et->largest_updated) {
et->largest_updated = false;
updated = true;
@@ -750,6 +770,9 @@ static void __update_extent_tree_range(struct inode *inode,
write_unlock(&et->lock);
+ if (is_inode_flag_set(inode, FI_NO_EXTENT))
+ __destroy_extent_node(inode, EX_READ);
+
if (updated)
f2fs_mark_inode_dirty_sync(inode, true);
}
@@ -835,10 +858,14 @@ static unsigned int __shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink
list_for_each_entry_safe(et, next, &eti->zombie_list, list) {
if (atomic_read(&et->node_cnt)) {
write_lock(&et->lock);
- node_cnt += __free_extent_tree(sbi, et);
+ node_cnt += __free_extent_tree(sbi, et,
+ nr_shrink - node_cnt - tree_cnt);
write_unlock(&et->lock);
}
- f2fs_bug_on(sbi, atomic_read(&et->node_cnt));
+
+ if (atomic_read(&et->node_cnt))
+ goto unlock_out;
+
list_del_init(&et->list);
radix_tree_delete(&eti->extent_tree_root, et->ino);
kmem_cache_free(extent_tree_slab, et);
@@ -929,23 +956,6 @@ unsigned int f2fs_shrink_read_extent_tree(struct f2fs_sb_info *sbi, int nr_shrin
return __shrink_extent_tree(sbi, nr_shrink, EX_READ);
}
-static unsigned int __destroy_extent_node(struct inode *inode,
- enum extent_type type)
-{
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
- struct extent_tree *et = F2FS_I(inode)->extent_tree[type];
- unsigned int node_cnt = 0;
-
- if (!et || !atomic_read(&et->node_cnt))
- return 0;
-
- write_lock(&et->lock);
- node_cnt = __free_extent_tree(sbi, et);
- write_unlock(&et->lock);
-
- return node_cnt;
-}
-
void f2fs_destroy_extent_node(struct inode *inode)
{
__destroy_extent_node(inode, EX_READ);
@@ -953,7 +963,6 @@ void f2fs_destroy_extent_node(struct inode *inode)
static void __drop_extent_tree(struct inode *inode, enum extent_type type)
{
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct extent_tree *et = F2FS_I(inode)->extent_tree[type];
bool updated = false;
@@ -961,7 +970,6 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type)
return;
write_lock(&et->lock);
- __free_extent_tree(sbi, et);
if (type == EX_READ) {
set_inode_flag(inode, FI_NO_EXTENT);
if (et->largest.len) {
@@ -970,6 +978,9 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type)
}
}
write_unlock(&et->lock);
+
+ __destroy_extent_node(inode, type);
+
if (updated)
f2fs_mark_inode_dirty_sync(inode, true);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0631/1887] drm/amdgpu: fix double free err_addr pointer warnings
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (629 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0630/1887] f2fs: fix to shrink read extent node in batches Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0632/1887] leds: an30259a: Use devm_mutex_init() for mutex initialization Greg Kroah-Hartman
` (367 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bob Zhou, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bob Zhou <bob.zhou@amd.com>
[ Upstream commit 506c245f3f1cd989cb89811a7f06e04ff8813a0d ]
In amdgpu_umc_bad_page_polling_timeout, the amdgpu_umc_handle_bad_pages
will be run many times so that double free err_addr in some special case.
So set the err_addr to NULL to avoid the warnings.
Signed-off-by: Bob Zhou <bob.zhou@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index aad3c8b4c8102..da40be587f1e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -109,6 +109,7 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
}
kfree(err_data->err_addr);
+ err_data->err_addr = NULL;
return AMDGPU_RAS_SUCCESS;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0632/1887] leds: an30259a: Use devm_mutex_init() for mutex initialization
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (630 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0631/1887] drm/amdgpu: fix double free err_addr pointer warnings Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0633/1887] ice: Fix improper extts handling Greg Kroah-Hartman
` (366 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, George Stark, Andy Shevchenko,
Lee Jones, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Stark <gnstark@salutedevices.com>
[ Upstream commit c382e2e3eccb6b7ca8c7aff5092c1668428e7de6 ]
In this driver LEDs are registered using devm_led_classdev_register()
so they are automatically unregistered after module's remove() is done.
led_classdev_unregister() calls module's led_set_brightness() to turn off
the LEDs and that callback uses mutex which was destroyed already
in module's remove() so use devm API instead.
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20240411161032.609544-9-gnstark@salutedevices.com
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/leds/leds-an30259a.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c
index e072ee5409f7e..374011e3121e3 100644
--- a/drivers/leds/leds-an30259a.c
+++ b/drivers/leds/leds-an30259a.c
@@ -296,7 +296,10 @@ static int an30259a_probe(struct i2c_client *client)
if (err < 0)
return err;
- mutex_init(&chip->mutex);
+ err = devm_mutex_init(&client->dev, &chip->mutex);
+ if (err)
+ return err;
+
chip->client = client;
i2c_set_clientdata(client, chip);
@@ -330,17 +333,9 @@ static int an30259a_probe(struct i2c_client *client)
return 0;
exit:
- mutex_destroy(&chip->mutex);
return err;
}
-static void an30259a_remove(struct i2c_client *client)
-{
- struct an30259a *chip = i2c_get_clientdata(client);
-
- mutex_destroy(&chip->mutex);
-}
-
static const struct of_device_id an30259a_match_table[] = {
{ .compatible = "panasonic,an30259a", },
{ /* sentinel */ },
@@ -360,7 +355,6 @@ static struct i2c_driver an30259a_driver = {
.of_match_table = of_match_ptr(an30259a_match_table),
},
.probe_new = an30259a_probe,
- .remove = an30259a_remove,
.id_table = an30259a_id,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0633/1887] ice: Fix improper extts handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (631 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0632/1887] leds: an30259a: Use devm_mutex_init() for mutex initialization Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0634/1887] s390/pkey: Wipe copies of protected- and secure-keys Greg Kroah-Hartman
` (365 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Przemek Kitszel, Jacob Keller,
Milena Olech, Karol Kolacinski, Simon Horman, Tony Nguyen,
Jakub Kicinski, Sasha Levin, Pucha Himasekhar Reddy
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milena Olech <milena.olech@intel.com>
[ Upstream commit 00d3b4f54582d4e4a02cda5886bb336eeab268cc ]
Extts events are disabled and enabled by the application ts2phc.
However, in case where the driver is removed when the application is
running, a specific extts event remains enabled and can cause a kernel
crash.
As a side effect, when the driver is reloaded and application is started
again, remaining extts event for the channel from a previous run will
keep firing and the message "extts on unexpected channel" might be
printed to the user.
To avoid that, extts events shall be disabled when PTP is released.
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20240702171459.2606611-2-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 66 +++++++++++++++++-------
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 +++
2 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 06c5a165e0668..0fa32ca5a9255 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -1513,27 +1513,24 @@ void ice_ptp_extts_event(struct ice_pf *pf)
/**
* ice_ptp_cfg_extts - Configure EXTTS pin and channel
* @pf: Board private structure
- * @ena: true to enable; false to disable
* @chan: GPIO channel (0-3)
- * @gpio_pin: GPIO pin
- * @extts_flags: request flags from the ptp_extts_request.flags
+ * @config: desired EXTTS configuration.
+ * @store: If set to true, the values will be stored
+ *
+ * Configure an external timestamp event on the requested channel.
*/
-static int
-ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
- unsigned int extts_flags)
+static void ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan,
+ struct ice_extts_channel *config, bool store)
{
u32 func, aux_reg, gpio_reg, irq_reg;
struct ice_hw *hw = &pf->hw;
u8 tmr_idx;
- if (chan > (unsigned int)pf->ptp.info.n_ext_ts)
- return -EINVAL;
-
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
irq_reg = rd32(hw, PFINT_OICR_ENA);
- if (ena) {
+ if (config->ena) {
/* Enable the interrupt */
irq_reg |= PFINT_OICR_TSYN_EVNT_M;
aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M;
@@ -1542,9 +1539,9 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
#define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1)
/* set event level to requested edge */
- if (extts_flags & PTP_FALLING_EDGE)
+ if (config->flags & PTP_FALLING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE;
- if (extts_flags & PTP_RISING_EDGE)
+ if (config->flags & PTP_RISING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE;
/* Write GPIO CTL reg.
@@ -1566,9 +1563,30 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
wr32(hw, PFINT_OICR_ENA, irq_reg);
wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg);
- wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg);
+ wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg);
- return 0;
+ if (store)
+ memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));
+}
+
+/**
+ * ice_ptp_disable_all_extts - Disable all EXTTS channels
+ * @pf: Board private structure
+ */
+static void ice_ptp_disable_all_extts(struct ice_pf *pf)
+{
+ struct ice_extts_channel extts_cfg = {};
+ int i;
+
+ for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
+ if (pf->ptp.extts_channels[i].ena) {
+ extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin;
+ extts_cfg.ena = false;
+ ice_ptp_cfg_extts(pf, i, &extts_cfg, false);
+ }
+ }
+
+ synchronize_irq(pf->msix_entries[pf->oicr_idx].vector);
}
/**
@@ -1725,7 +1743,6 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
struct ptp_clock_request *rq, int on)
{
struct ice_pf *pf = ptp_info_to_pf(info);
- struct ice_perout_channel clk_cfg = {0};
bool sma_pres = false;
unsigned int chan;
u32 gpio_pin;
@@ -1736,6 +1753,9 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
+ {
+ struct ice_perout_channel clk_cfg = {};
+
chan = rq->perout.index;
if (sma_pres) {
if (chan == ice_pin_desc_e810t[SMA1].chan)
@@ -1763,7 +1783,11 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
break;
+ }
case PTP_CLK_REQ_EXTTS:
+ {
+ struct ice_extts_channel extts_cfg = {};
+
chan = rq->extts.index;
if (sma_pres) {
if (chan < ice_pin_desc_e810t[SMA2].chan)
@@ -1779,9 +1803,13 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
gpio_pin = chan;
}
- err = ice_ptp_cfg_extts(pf, !!on, chan, gpio_pin,
- rq->extts.flags);
- break;
+ extts_cfg.flags = rq->extts.flags;
+ extts_cfg.gpio_pin = gpio_pin;
+ extts_cfg.ena = !!on;
+
+ ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
+ return 0;
+ }
default:
return -EOPNOTSUPP;
}
@@ -2711,6 +2739,8 @@ void ice_ptp_release(struct ice_pf *pf)
clear_bit(ICE_FLAG_PTP, pf->flags);
+ ice_ptp_disable_all_extts(pf);
+
kthread_cancel_delayed_work_sync(&pf->ptp.work);
ice_ptp_port_phy_stop(&pf->ptp.port);
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
index e689c05bb001f..146df66bef6d8 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
@@ -33,6 +33,12 @@ struct ice_perout_channel {
u64 start_time;
};
+struct ice_extts_channel {
+ bool ena;
+ u32 gpio_pin;
+ u32 flags;
+};
+
/* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp
* is stored in a buffer of registers. Depending on the specific hardware,
* this buffer might be shared across multiple PHY ports.
@@ -165,6 +171,7 @@ struct ice_ptp_port {
* @ext_ts_irq: the external timestamp IRQ in use
* @kworker: kwork thread for handling periodic work
* @perout_channels: periodic output data
+ * @extts_channels: channels for external timestamps
* @info: structure defining PTP hardware capabilities
* @clock: pointer to registered PTP clock device
* @tstamp_config: hardware timestamping configuration
@@ -185,6 +192,7 @@ struct ice_ptp {
u8 ext_ts_irq;
struct kthread_worker *kworker;
struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX];
+ struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX];
struct ptp_clock_info info;
struct ptp_clock *clock;
struct hwtstamp_config tstamp_config;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0634/1887] s390/pkey: Wipe copies of protected- and secure-keys
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (632 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0633/1887] ice: Fix improper extts handling Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0635/1887] s390/pkey: Wipe copies of clear-key structures on failure Greg Kroah-Hartman
` (364 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Ingo Franzki,
Heiko Carstens, Holger Dengler, Alexander Gordeev, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Holger Dengler <dengler@linux.ibm.com>
[ Upstream commit f2ebdadd85af4f4d0cae1e5d009c70eccc78c207 ]
Although the clear-key of neither protected- nor secure-keys is
accessible, this key material should only be visible to the calling
process. So wipe all copies of protected- or secure-keys from stack,
even in case of an error.
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/crypto/pkey_api.c | 80 ++++++++++++++++------------------
1 file changed, 37 insertions(+), 43 deletions(-)
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 6a94f4965a2d5..f1686f172fbf5 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -1173,10 +1173,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
rc = cca_genseckey(kgs.cardnr, kgs.domain,
kgs.keytype, kgs.seckey.seckey);
DEBUG_DBG("%s cca_genseckey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(ugs, &kgs, sizeof(kgs)))
- return -EFAULT;
+ if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
+ rc = -EFAULT;
+ memzero_explicit(&kgs, sizeof(kgs));
break;
}
case PKEY_CLR2SECK: {
@@ -1205,10 +1204,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
ksp.seckey.seckey, ksp.protkey.protkey,
&ksp.protkey.len, &ksp.protkey.type);
DEBUG_DBG("%s cca_sec2protkey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(usp, &ksp, sizeof(ksp)))
- return -EFAULT;
+ if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
+ rc = -EFAULT;
+ memzero_explicit(&ksp, sizeof(ksp));
break;
}
case PKEY_CLR2PROTK: {
@@ -1250,10 +1248,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_skey2pkey(ksp.seckey.seckey, &ksp.protkey);
DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(usp, &ksp, sizeof(ksp)))
- return -EFAULT;
+ if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
+ rc = -EFAULT;
+ memzero_explicit(&ksp, sizeof(ksp));
break;
}
case PKEY_VERIFYKEY: {
@@ -1265,10 +1262,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain,
&kvk.keysize, &kvk.attributes);
DEBUG_DBG("%s pkey_verifykey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(uvk, &kvk, sizeof(kvk)))
- return -EFAULT;
+ if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
+ rc = -EFAULT;
+ memzero_explicit(&kvk, sizeof(kvk));
break;
}
case PKEY_GENPROTK: {
@@ -1279,10 +1275,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_genprotkey(kgp.keytype, &kgp.protkey);
DEBUG_DBG("%s pkey_genprotkey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(ugp, &kgp, sizeof(kgp)))
- return -EFAULT;
+ if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
+ rc = -EFAULT;
+ memzero_explicit(&kgp, sizeof(kgp));
break;
}
case PKEY_VERIFYPROTK: {
@@ -1293,6 +1288,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
rc = pkey_verifyprotkey(&kvp.protkey);
DEBUG_DBG("%s pkey_verifyprotkey()=%d\n", __func__, rc);
+ memzero_explicit(&kvp, sizeof(kvp));
break;
}
case PKEY_KBLOB2PROTK: {
@@ -1309,10 +1305,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc);
memzero_explicit(kkey, ktp.keylen);
kfree(kkey);
- if (rc)
- break;
- if (copy_to_user(utp, &ktp, sizeof(ktp)))
- return -EFAULT;
+ if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
+ rc = -EFAULT;
+ memzero_explicit(&ktp, sizeof(ktp));
break;
}
case PKEY_GENSECK2: {
@@ -1338,23 +1333,23 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
DEBUG_DBG("%s pkey_genseckey2()=%d\n", __func__, rc);
kfree(apqns);
if (rc) {
- kfree(kkey);
+ kfree_sensitive(kkey);
break;
}
if (kgs.key) {
if (kgs.keylen < klen) {
- kfree(kkey);
+ kfree_sensitive(kkey);
return -EINVAL;
}
if (copy_to_user(kgs.key, kkey, klen)) {
- kfree(kkey);
+ kfree_sensitive(kkey);
return -EFAULT;
}
}
kgs.keylen = klen;
if (copy_to_user(ugs, &kgs, sizeof(kgs)))
rc = -EFAULT;
- kfree(kkey);
+ kfree_sensitive(kkey);
break;
}
case PKEY_CLR2SECK2: {
@@ -1380,16 +1375,16 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
DEBUG_DBG("%s pkey_clr2seckey2()=%d\n", __func__, rc);
kfree(apqns);
if (rc) {
- kfree(kkey);
+ kfree_sensitive(kkey);
break;
}
if (kcs.key) {
if (kcs.keylen < klen) {
- kfree(kkey);
+ kfree_sensitive(kkey);
return -EINVAL;
}
if (copy_to_user(kcs.key, kkey, klen)) {
- kfree(kkey);
+ kfree_sensitive(kkey);
return -EFAULT;
}
}
@@ -1397,7 +1392,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
if (copy_to_user(ucs, &kcs, sizeof(kcs)))
rc = -EFAULT;
memzero_explicit(&kcs, sizeof(kcs));
- kfree(kkey);
+ kfree_sensitive(kkey);
break;
}
case PKEY_VERIFYKEY2: {
@@ -1414,7 +1409,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
&kvk.cardnr, &kvk.domain,
&kvk.type, &kvk.size, &kvk.flags);
DEBUG_DBG("%s pkey_verifykey2()=%d\n", __func__, rc);
- kfree(kkey);
+ kfree_sensitive(kkey);
if (rc)
break;
if (copy_to_user(uvk, &kvk, sizeof(kvk)))
@@ -1443,10 +1438,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
kfree(apqns);
memzero_explicit(kkey, ktp.keylen);
kfree(kkey);
- if (rc)
- break;
- if (copy_to_user(utp, &ktp, sizeof(ktp)))
- return -EFAULT;
+ if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
+ rc = -EFAULT;
+ memzero_explicit(&ktp, sizeof(ktp));
break;
}
case PKEY_APQNS4K: {
@@ -1474,7 +1468,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
rc = pkey_apqns4key(kkey, kak.keylen, kak.flags,
apqns, &nr_apqns);
DEBUG_DBG("%s pkey_apqns4key()=%d\n", __func__, rc);
- kfree(kkey);
+ kfree_sensitive(kkey);
if (rc && rc != -ENOSPC) {
kfree(apqns);
break;
@@ -1560,7 +1554,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
protkey = kmalloc(protkeylen, GFP_KERNEL);
if (!protkey) {
kfree(apqns);
- kfree(kkey);
+ kfree_sensitive(kkey);
return -ENOMEM;
}
rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, kkey,
@@ -1571,20 +1565,20 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
memzero_explicit(kkey, ktp.keylen);
kfree(kkey);
if (rc) {
- kfree(protkey);
+ kfree_sensitive(protkey);
break;
}
if (ktp.pkey && ktp.pkeylen) {
if (protkeylen > ktp.pkeylen) {
- kfree(protkey);
+ kfree_sensitive(protkey);
return -EINVAL;
}
if (copy_to_user(ktp.pkey, protkey, protkeylen)) {
- kfree(protkey);
+ kfree_sensitive(protkey);
return -EFAULT;
}
}
- kfree(protkey);
+ kfree_sensitive(protkey);
ktp.pkeylen = protkeylen;
if (copy_to_user(utp, &ktp, sizeof(ktp)))
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0635/1887] s390/pkey: Wipe copies of clear-key structures on failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (633 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0634/1887] s390/pkey: Wipe copies of protected- and secure-keys Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0636/1887] s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings Greg Kroah-Hartman
` (363 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Ingo Franzki,
Heiko Carstens, Holger Dengler, Alexander Gordeev, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Holger Dengler <dengler@linux.ibm.com>
[ Upstream commit d65d76a44ffe74c73298ada25b0f578680576073 ]
Wipe all sensitive data from stack for all IOCTLs, which convert a
clear-key into a protected- or secure-key.
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/crypto/pkey_api.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index f1686f172fbf5..96fcaa0b6ff90 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -1187,9 +1187,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype,
kcs.clrkey.clrkey, kcs.seckey.seckey);
DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(ucs, &kcs, sizeof(kcs)))
+ if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
rc = -EFAULT;
memzero_explicit(&kcs, sizeof(kcs));
break;
@@ -1218,9 +1216,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
rc = pkey_clr2protkey(kcp.keytype,
&kcp.clrkey, &kcp.protkey);
DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc);
- if (rc)
- break;
- if (copy_to_user(ucp, &kcp, sizeof(kcp)))
+ if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
rc = -EFAULT;
memzero_explicit(&kcp, sizeof(kcp));
break;
@@ -1362,11 +1358,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
if (copy_from_user(&kcs, ucs, sizeof(kcs)))
return -EFAULT;
apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
- if (IS_ERR(apqns))
+ if (IS_ERR(apqns)) {
+ memzero_explicit(&kcs, sizeof(kcs));
return PTR_ERR(apqns);
+ }
kkey = kzalloc(klen, GFP_KERNEL);
if (!kkey) {
kfree(apqns);
+ memzero_explicit(&kcs, sizeof(kcs));
return -ENOMEM;
}
rc = pkey_clr2seckey2(apqns, kcs.apqn_entries,
@@ -1376,15 +1375,18 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
kfree(apqns);
if (rc) {
kfree_sensitive(kkey);
+ memzero_explicit(&kcs, sizeof(kcs));
break;
}
if (kcs.key) {
if (kcs.keylen < klen) {
kfree_sensitive(kkey);
+ memzero_explicit(&kcs, sizeof(kcs));
return -EINVAL;
}
if (copy_to_user(kcs.key, kkey, klen)) {
kfree_sensitive(kkey);
+ memzero_explicit(&kcs, sizeof(kcs));
return -EFAULT;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0636/1887] s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (634 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0635/1887] s390/pkey: Wipe copies of clear-key structures on failure Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0637/1887] filemap: add helper mapping_max_folio_size() Greg Kroah-Hartman
` (362 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jules Irenge, Holger Dengler,
Heiko Carstens, Alexander Gordeev, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jules Irenge <jbi.octave@gmail.com>
[ Upstream commit 22e6824622e8a8889df0f8fc4ed5aea0e702a694 ]
Replace memzero_explicit() and kfree() with kfree_sensitive() to fix
warnings reported by Coccinelle:
WARNING opportunity for kfree_sensitive/kvfree_sensitive (line 1506)
WARNING opportunity for kfree_sensitive/kvfree_sensitive (line 1643)
WARNING opportunity for kfree_sensitive/kvfree_sensitive (line 1770)
Signed-off-by: Jules Irenge <jbi.octave@gmail.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Link: https://lore.kernel.org/r/ZjqZkNi_JUJu73Rg@octinomon.home
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/crypto/pkey_api.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 96fcaa0b6ff90..2e7a56073cc00 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -1299,8 +1299,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return PTR_ERR(kkey);
rc = pkey_keyblob2pkey(kkey, ktp.keylen, &ktp.protkey);
DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc);
- memzero_explicit(kkey, ktp.keylen);
- kfree(kkey);
+ kfree_sensitive(kkey);
if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
rc = -EFAULT;
memzero_explicit(&ktp, sizeof(ktp));
@@ -1438,8 +1437,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
kkey, ktp.keylen, &ktp.protkey);
DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n", __func__, rc);
kfree(apqns);
- memzero_explicit(kkey, ktp.keylen);
- kfree(kkey);
+ kfree_sensitive(kkey);
if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
rc = -EFAULT;
memzero_explicit(&ktp, sizeof(ktp));
@@ -1564,8 +1562,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
protkey, &protkeylen);
DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n", __func__, rc);
kfree(apqns);
- memzero_explicit(kkey, ktp.keylen);
- kfree(kkey);
+ kfree_sensitive(kkey);
if (rc) {
kfree_sensitive(protkey);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0637/1887] filemap: add helper mapping_max_folio_size()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (635 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0636/1887] s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0638/1887] mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray Greg Kroah-Hartman
` (361 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Xu Yang,
Ritesh Harjani (IBM), Christoph Hellwig, Matthew Wilcox (Oracle),
Christian Brauner, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <xu.yang_2@nxp.com>
[ Upstream commit 79c137454815ba5554caa8eeb4ad5c94e96e45ce ]
Add mapping_max_folio_size() to get the maximum folio size for this
pagecache mapping.
Fixes: 5d8edfb900d5 ("iomap: Copy larger chunks from userspace")
Cc: stable@vger.kernel.org
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://lore.kernel.org/r/20240521114939.2541461-1-xu.yang_2@nxp.com
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 099d90642a71 ("mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/pagemap.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index dfaa099018671..a307e63cdf737 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -325,6 +325,19 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
m->gfp_mask = mask;
}
+/*
+ * There are some parts of the kernel which assume that PMD entries
+ * are exactly HPAGE_PMD_ORDER. Those should be fixed, but until then,
+ * limit the maximum allocation order to PMD size. I'm not aware of any
+ * assumptions about maximum order if THP are disabled, but 8 seems like
+ * a good order (that's 1MB if you're using 4kB pages)
+ */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER
+#else
+#define MAX_PAGECACHE_ORDER 8
+#endif
+
/**
* mapping_set_large_folios() - Indicate the file supports large folios.
* @mapping: The file.
@@ -351,6 +364,14 @@ static inline bool mapping_large_folio_support(struct address_space *mapping)
test_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags);
}
+/* Return the maximum folio size for this pagecache mapping, in bytes. */
+static inline size_t mapping_max_folio_size(struct address_space *mapping)
+{
+ if (mapping_large_folio_support(mapping))
+ return PAGE_SIZE << MAX_PAGECACHE_ORDER;
+ return PAGE_SIZE;
+}
+
static inline int filemap_nr_thps(struct address_space *mapping)
{
#ifdef CONFIG_READ_ONLY_THP_FOR_FS
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0638/1887] mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (636 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0637/1887] filemap: add helper mapping_max_folio_size() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0639/1887] spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer Greg Kroah-Hartman
` (360 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gavin Shan, David Hildenbrand,
Darrick J. Wong, Don Dutile, Hugh Dickins, Linus Torvalds,
Matthew Wilcox (Oracle), Ryan Roberts, William Kucharski,
Zhenyu Zhang, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gavin Shan <gshan@redhat.com>
[ Upstream commit 099d90642a711caae377f53309abfe27e8724a8b ]
Patch series "mm/filemap: Limit page cache size to that supported by
xarray", v2.
Currently, xarray can't support arbitrary page cache size. More details
can be found from the WARN_ON() statement in xas_split_alloc(). In our
test whose code is attached below, we hit the WARN_ON() on ARM64 system
where the base page size is 64KB and huge page size is 512MB. The issue
was reported long time ago and some discussions on it can be found here
[1].
[1] https://www.spinics.net/lists/linux-xfs/msg75404.html
In order to fix the issue, we need to adjust MAX_PAGECACHE_ORDER to one
supported by xarray and avoid PMD-sized page cache if needed. The code
changes are suggested by David Hildenbrand.
PATCH[1] adjusts MAX_PAGECACHE_ORDER to that supported by xarray
PATCH[2-3] avoids PMD-sized page cache in the synchronous readahead path
PATCH[4] avoids PMD-sized page cache for shmem files if needed
Test program
============
# cat test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#define TEST_XFS_FILENAME "/tmp/data"
#define TEST_SHMEM_FILENAME "/dev/shm/data"
#define TEST_MEM_SIZE 0x20000000
int main(int argc, char **argv)
{
const char *filename;
int fd = 0;
void *buf = (void *)-1, *p;
int pgsize = getpagesize();
int ret;
if (pgsize != 0x10000) {
fprintf(stderr, "64KB base page size is required\n");
return -EPERM;
}
system("echo force > /sys/kernel/mm/transparent_hugepage/shmem_enabled");
system("rm -fr /tmp/data");
system("rm -fr /dev/shm/data");
system("echo 1 > /proc/sys/vm/drop_caches");
/* Open xfs or shmem file */
filename = TEST_XFS_FILENAME;
if (argc > 1 && !strcmp(argv[1], "shmem"))
filename = TEST_SHMEM_FILENAME;
fd = open(filename, O_CREAT | O_RDWR | O_TRUNC);
if (fd < 0) {
fprintf(stderr, "Unable to open <%s>\n", filename);
return -EIO;
}
/* Extend file size */
ret = ftruncate(fd, TEST_MEM_SIZE);
if (ret) {
fprintf(stderr, "Error %d to ftruncate()\n", ret);
goto cleanup;
}
/* Create VMA */
buf = mmap(NULL, TEST_MEM_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == (void *)-1) {
fprintf(stderr, "Unable to mmap <%s>\n", filename);
goto cleanup;
}
fprintf(stdout, "mapped buffer at 0x%p\n", buf);
ret = madvise(buf, TEST_MEM_SIZE, MADV_HUGEPAGE);
if (ret) {
fprintf(stderr, "Unable to madvise(MADV_HUGEPAGE)\n");
goto cleanup;
}
/* Populate VMA */
ret = madvise(buf, TEST_MEM_SIZE, MADV_POPULATE_WRITE);
if (ret) {
fprintf(stderr, "Error %d to madvise(MADV_POPULATE_WRITE)\n", ret);
goto cleanup;
}
/* Punch the file to enforce xarray split */
ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
TEST_MEM_SIZE - pgsize, pgsize);
if (ret)
fprintf(stderr, "Error %d to fallocate()\n", ret);
cleanup:
if (buf != (void *)-1)
munmap(buf, TEST_MEM_SIZE);
if (fd > 0)
close(fd);
return 0;
}
# gcc test.c -o test
# cat /proc/1/smaps | grep KernelPageSize | head -n 1
KernelPageSize: 64 kB
# ./test shmem
:
------------[ cut here ]------------
WARNING: CPU: 17 PID: 5253 at lib/xarray.c:1025 xas_split_alloc+0xf8/0x128
Modules linked in: nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib \
nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct \
nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 \
ip_set nf_tables rfkill nfnetlink vfat fat virtio_balloon \
drm fuse xfs libcrc32c crct10dif_ce ghash_ce sha2_ce sha256_arm64 \
virtio_net sha1_ce net_failover failover virtio_console virtio_blk \
dimlib virtio_mmio
CPU: 17 PID: 5253 Comm: test Kdump: loaded Tainted: G W 6.10.0-rc5-gavin+ #12
Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20240524-1.el9 05/24/2024
pstate: 83400005 (Nzcv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
pc : xas_split_alloc+0xf8/0x128
lr : split_huge_page_to_list_to_order+0x1c4/0x720
sp : ffff80008a92f5b0
x29: ffff80008a92f5b0 x28: ffff80008a92f610 x27: ffff80008a92f728
x26: 0000000000000cc0 x25: 000000000000000d x24: ffff0000cf00c858
x23: ffff80008a92f610 x22: ffffffdfc0600000 x21: 0000000000000000
x20: 0000000000000000 x19: ffffffdfc0600000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000018000000000 x15: 3374004000000000
x14: 0000e00000000000 x13: 0000000000002000 x12: 0000000000000020
x11: 3374000000000000 x10: 3374e1c0ffff6000 x9 : ffffb463a84c681c
x8 : 0000000000000003 x7 : 0000000000000000 x6 : ffff00011c976ce0
x5 : ffffb463aa47e378 x4 : 0000000000000000 x3 : 0000000000000cc0
x2 : 000000000000000d x1 : 000000000000000c x0 : 0000000000000000
Call trace:
xas_split_alloc+0xf8/0x128
split_huge_page_to_list_to_order+0x1c4/0x720
truncate_inode_partial_folio+0xdc/0x160
shmem_undo_range+0x2bc/0x6a8
shmem_fallocate+0x134/0x430
vfs_fallocate+0x124/0x2e8
ksys_fallocate+0x4c/0xa0
__arm64_sys_fallocate+0x24/0x38
invoke_syscall.constprop.0+0x7c/0xd8
do_el0_svc+0xb4/0xd0
el0_svc+0x44/0x1d8
el0t_64_sync_handler+0x134/0x150
el0t_64_sync+0x17c/0x180
This patch (of 4):
The largest page cache order can be HPAGE_PMD_ORDER (13) on ARM64 with
64KB base page size. The xarray entry with this order can't be split as
the following error messages indicate.
------------[ cut here ]------------
WARNING: CPU: 35 PID: 7484 at lib/xarray.c:1025 xas_split_alloc+0xf8/0x128
Modules linked in: nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib \
nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct \
nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 \
ip_set rfkill nf_tables nfnetlink vfat fat virtio_balloon drm \
fuse xfs libcrc32c crct10dif_ce ghash_ce sha2_ce sha256_arm64 \
sha1_ce virtio_net net_failover virtio_console virtio_blk failover \
dimlib virtio_mmio
CPU: 35 PID: 7484 Comm: test Kdump: loaded Tainted: G W 6.10.0-rc5-gavin+ #9
Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20240524-1.el9 05/24/2024
pstate: 83400005 (Nzcv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
pc : xas_split_alloc+0xf8/0x128
lr : split_huge_page_to_list_to_order+0x1c4/0x720
sp : ffff800087a4f6c0
x29: ffff800087a4f6c0 x28: ffff800087a4f720 x27: 000000001fffffff
x26: 0000000000000c40 x25: 000000000000000d x24: ffff00010625b858
x23: ffff800087a4f720 x22: ffffffdfc0780000 x21: 0000000000000000
x20: 0000000000000000 x19: ffffffdfc0780000 x18: 000000001ff40000
x17: 00000000ffffffff x16: 0000018000000000 x15: 51ec004000000000
x14: 0000e00000000000 x13: 0000000000002000 x12: 0000000000000020
x11: 51ec000000000000 x10: 51ece1c0ffff8000 x9 : ffffbeb961a44d28
x8 : 0000000000000003 x7 : ffffffdfc0456420 x6 : ffff0000e1aa6eb8
x5 : 20bf08b4fe778fca x4 : ffffffdfc0456420 x3 : 0000000000000c40
x2 : 000000000000000d x1 : 000000000000000c x0 : 0000000000000000
Call trace:
xas_split_alloc+0xf8/0x128
split_huge_page_to_list_to_order+0x1c4/0x720
truncate_inode_partial_folio+0xdc/0x160
truncate_inode_pages_range+0x1b4/0x4a8
truncate_pagecache_range+0x84/0xa0
xfs_flush_unmap_range+0x70/0x90 [xfs]
xfs_file_fallocate+0xfc/0x4d8 [xfs]
vfs_fallocate+0x124/0x2e8
ksys_fallocate+0x4c/0xa0
__arm64_sys_fallocate+0x24/0x38
invoke_syscall.constprop.0+0x7c/0xd8
do_el0_svc+0xb4/0xd0
el0_svc+0x44/0x1d8
el0t_64_sync_handler+0x134/0x150
el0t_64_sync+0x17c/0x180
Fix it by decreasing MAX_PAGECACHE_ORDER to the largest supported order
by xarray. For this specific case, MAX_PAGECACHE_ORDER is dropped from
13 to 11 when CONFIG_BASE_SMALL is disabled.
Link: https://lkml.kernel.org/r/20240627003953.1262512-1-gshan@redhat.com
Link: https://lkml.kernel.org/r/20240627003953.1262512-2-gshan@redhat.com
Fixes: 793917d997df ("mm/readahead: Add large folio readahead")
Signed-off-by: Gavin Shan <gshan@redhat.com>
Suggested-by: David Hildenbrand <david@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: Don Dutile <ddutile@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: Zhenyu Zhang <zhenyzha@redhat.com>
Cc: <stable@vger.kernel.org> [5.18+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/pagemap.h | 11 +++++++++--
mm/readahead.c | 13 -------------
2 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index a307e63cdf737..a40afc0aea3e2 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -333,11 +333,18 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
* a good order (that's 1MB if you're using 4kB pages)
*/
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER
+#define PREFERRED_MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER
#else
-#define MAX_PAGECACHE_ORDER 8
+#define PREFERRED_MAX_PAGECACHE_ORDER 8
#endif
+/*
+ * xas_split_alloc() does not support arbitrary orders. This implies no
+ * 512MB THP on ARM64 with 64KB base page size.
+ */
+#define MAX_XAS_ORDER (XA_CHUNK_SHIFT * 2 - 1)
+#define MAX_PAGECACHE_ORDER min(MAX_XAS_ORDER, PREFERRED_MAX_PAGECACHE_ORDER)
+
/**
* mapping_set_large_folios() - Indicate the file supports large folios.
* @mapping: The file.
diff --git a/mm/readahead.c b/mm/readahead.c
index e0bef7c0d7afe..2ad297cfae7d9 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -462,19 +462,6 @@ static int try_context_readahead(struct address_space *mapping,
return 1;
}
-/*
- * There are some parts of the kernel which assume that PMD entries
- * are exactly HPAGE_PMD_ORDER. Those should be fixed, but until then,
- * limit the maximum allocation order to PMD size. I'm not aware of any
- * assumptions about maximum order if THP are disabled, but 8 seems like
- * a good order (that's 1MB if you're using 4kB pages)
- */
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER
-#else
-#define MAX_PAGECACHE_ORDER 8
-#endif
-
static inline int ra_alloc_folio(struct readahead_control *ractl, pgoff_t index,
pgoff_t mark, unsigned int order, gfp_t gfp)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0639/1887] spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (637 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0638/1887] mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0640/1887] PCI: endpoint: pci-epf-test: Make use of cached epc_features in pci_epf_test_core_init() Greg Kroah-Hartman
` (359 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Steve Wilkins, Conor Dooley,
Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Wilkins <steve.wilkins@raymarine.com>
[ Upstream commit 9cf71eb0faef4bff01df4264841b8465382d7927 ]
While transmitting with rx_len == 0, the RX FIFO is not going to be
emptied in the interrupt handler. A subsequent transfer could then
read crap from the previous transfer out of the RX FIFO into the
start RX buffer. The core provides a register that will empty the RX and
TX FIFOs, so do that before each transfer.
Fixes: 9ac8d17694b6 ("spi: add support for microchip fpga spi controllers")
Signed-off-by: Steve Wilkins <steve.wilkins@raymarine.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://patch.msgid.link/20240715-flammable-provoke-459226d08e70@wendy
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-microchip-core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/spi/spi-microchip-core.c b/drivers/spi/spi-microchip-core.c
index bfad0fe743ad7..acc05f5a929e6 100644
--- a/drivers/spi/spi-microchip-core.c
+++ b/drivers/spi/spi-microchip-core.c
@@ -91,6 +91,8 @@
#define REG_CONTROL2 (0x28)
#define REG_COMMAND (0x2c)
#define COMMAND_CLRFRAMECNT BIT(4)
+#define COMMAND_TXFIFORST BIT(3)
+#define COMMAND_RXFIFORST BIT(2)
#define REG_PKTSIZE (0x30)
#define REG_CMD_SIZE (0x34)
#define REG_HWSTATUS (0x38)
@@ -489,6 +491,8 @@ static int mchp_corespi_transfer_one(struct spi_controller *host,
mchp_corespi_set_xfer_size(spi, (spi->tx_len > FIFO_DEPTH)
? FIFO_DEPTH : spi->tx_len);
+ mchp_corespi_write(spi, REG_COMMAND, COMMAND_RXFIFORST | COMMAND_TXFIFORST);
+
while (spi->tx_len)
mchp_corespi_write_fifo(spi);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0640/1887] PCI: endpoint: pci-epf-test: Make use of cached epc_features in pci_epf_test_core_init()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (638 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0639/1887] spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0641/1887] soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove Greg Kroah-Hartman
` (358 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Manivannan Sadhasivam,
Krzysztof Wilczyński, Bjorn Helgaas, Frank Li, Niklas Cassel,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
[ Upstream commit 5a5095a8bd1bd349cce1c879e5e44407a34dda8a ]
Instead of getting the epc_features from pci_epc_get_features() API, use
the cached pci_epf_test::epc_features value to avoid the NULL check. Since
the NULL check is already performed in pci_epf_test_bind(), having one more
check in pci_epf_test_core_init() is redundant and it is not possible to
hit the NULL pointer dereference.
Also with commit a01e7214bef9 ("PCI: endpoint: Remove "core_init_notifier"
flag"), 'epc_features' got dereferenced without the NULL check, leading to
the following false positive Smatch warning:
drivers/pci/endpoint/functions/pci-epf-test.c:784 pci_epf_test_core_init() error: we previously assumed 'epc_features' could be null (see line 747)
Thus, remove the redundant NULL check and also use the epc_features::
{msix_capable/msi_capable} flags directly to avoid local variables.
[kwilczynski: commit log]
Fixes: 5e50ee27d4a5 ("PCI: pci-epf-test: Add support to defer core initialization")
Closes: https://lore.kernel.org/linux-pci/024b5826-7180-4076-ae08-57d2584cca3f@moroto.mountain
Link: https://lore.kernel.org/linux-pci/20240418-pci-epf-test-fix-v2-1-eacd54831444@linaro.org
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 3fe2187cdd0ba..fb47ce721e095 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -782,19 +782,11 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
{
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
struct pci_epf_header *header = epf->header;
- const struct pci_epc_features *epc_features;
+ const struct pci_epc_features *epc_features = epf_test->epc_features;
struct pci_epc *epc = epf->epc;
struct device *dev = &epf->dev;
- bool msix_capable = false;
- bool msi_capable = true;
int ret;
- epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
- if (epc_features) {
- msix_capable = epc_features->msix_capable;
- msi_capable = epc_features->msi_capable;
- }
-
if (epf->vfunc_no <= 1) {
ret = pci_epc_write_header(epc, epf->func_no, epf->vfunc_no, header);
if (ret) {
@@ -807,7 +799,7 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
if (ret)
return ret;
- if (msi_capable) {
+ if (epc_features->msi_capable) {
ret = pci_epc_set_msi(epc, epf->func_no, epf->vfunc_no,
epf->msi_interrupts);
if (ret) {
@@ -816,7 +808,7 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
}
}
- if (msix_capable) {
+ if (epc_features->msix_capable) {
ret = pci_epc_set_msix(epc, epf->func_no, epf->vfunc_no,
epf->msix_interrupts,
epf_test->test_reg_bar,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0641/1887] soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (639 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0640/1887] PCI: endpoint: pci-epf-test: Make use of cached epc_features in pci_epf_test_core_init() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0642/1887] drm/amd/display: Fix null pointer deref in dcn20_resource.c Greg Kroah-Hartman
` (357 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sibi Sankar, Konrad Dybcio,
Bjorn Andersson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sibi Sankar <quic_sibis@quicinc.com>
[ Upstream commit 24086640ab39396eb1a92d1cb1cd2f31b2677c52 ]
The following warning is seen during bwmon_remove due to refcount
imbalance, fix this by releasing the OPPs after use.
Logs:
WARNING: at drivers/opp/core.c:1640 _opp_table_kref_release+0x150/0x158
Hardware name: Qualcomm Technologies, Inc. X1E80100 CRD (DT)
...
Call trace:
_opp_table_kref_release+0x150/0x158
dev_pm_opp_remove_table+0x100/0x1b4
devm_pm_opp_of_table_release+0x10/0x1c
devm_action_release+0x14/0x20
devres_release_all+0xa4/0x104
device_unbind_cleanup+0x18/0x60
device_release_driver_internal+0x1ec/0x228
driver_detach+0x50/0x98
bus_remove_driver+0x6c/0xbc
driver_unregister+0x30/0x60
platform_driver_unregister+0x14/0x20
bwmon_driver_exit+0x18/0x524 [icc_bwmon]
__arm64_sys_delete_module+0x184/0x264
invoke_syscall+0x48/0x118
el0_svc_common.constprop.0+0xc8/0xe8
do_el0_svc+0x20/0x2c
el0_svc+0x34/0xdc
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
--[ end trace 0000000000000000 ]---
Fixes: 0276f69f13e2 ("soc: qcom: icc-bwmon: Set default thresholds dynamically")
Fixes: b9c2ae6cac40 ("soc: qcom: icc-bwmon: Add bandwidth monitoring driver")
Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20240613164506.982068-1-quic_sibis@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/qcom/icc-bwmon.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c
index 7829549993c92..2e0a45cd6921f 100644
--- a/drivers/soc/qcom/icc-bwmon.c
+++ b/drivers/soc/qcom/icc-bwmon.c
@@ -604,11 +604,13 @@ static int bwmon_probe(struct platform_device *pdev)
opp = dev_pm_opp_find_bw_floor(dev, &bwmon->max_bw_kbps, 0);
if (IS_ERR(opp))
return dev_err_probe(dev, PTR_ERR(opp), "failed to find max peak bandwidth\n");
+ dev_pm_opp_put(opp);
bwmon->min_bw_kbps = 0;
opp = dev_pm_opp_find_bw_ceil(dev, &bwmon->min_bw_kbps, 0);
if (IS_ERR(opp))
return dev_err_probe(dev, PTR_ERR(opp), "failed to find min peak bandwidth\n");
+ dev_pm_opp_put(opp);
bwmon->dev = dev;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0642/1887] drm/amd/display: Fix null pointer deref in dcn20_resource.c
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (640 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0641/1887] soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0643/1887] nvme: apple: fix device reference counting Greg Kroah-Hartman
` (356 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aurabindo Pillai, Rodrigo Siqueira,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurabindo Pillai <aurabindo.pillai@amd.com>
[ Upstream commit ecbf60782662f0a388493685b85a645a0ba1613c ]
Fixes a hang thats triggered when MPV is run on a DCN401 dGPU:
mpv --hwdec=vaapi --vo=gpu --hwdec-codecs=all
and then enabling fullscreen playback (double click on the video)
The following calltrace will be seen:
[ 181.843989] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 181.843997] #PF: supervisor instruction fetch in kernel mode
[ 181.844003] #PF: error_code(0x0010) - not-present page
[ 181.844009] PGD 0 P4D 0
[ 181.844020] Oops: 0010 [#1] PREEMPT SMP NOPTI
[ 181.844028] CPU: 6 PID: 1892 Comm: gnome-shell Tainted: G W OE 6.5.0-41-generic #41~22.04.2-Ubuntu
[ 181.844038] Hardware name: System manufacturer System Product Name/CROSSHAIR VI HERO, BIOS 6302 10/23/2018
[ 181.844044] RIP: 0010:0x0
[ 181.844079] Code: Unable to access opcode bytes at 0xffffffffffffffd6.
[ 181.844084] RSP: 0018:ffffb593c2b8f7b0 EFLAGS: 00010246
[ 181.844093] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000004
[ 181.844099] RDX: ffffb593c2b8f804 RSI: ffffb593c2b8f7e0 RDI: ffff9e3c8e758400
[ 181.844105] RBP: ffffb593c2b8f7b8 R08: ffffb593c2b8f9c8 R09: ffffb593c2b8f96c
[ 181.844110] R10: 0000000000000000 R11: 0000000000000000 R12: ffffb593c2b8f9c8
[ 181.844115] R13: 0000000000000001 R14: ffff9e3c88000000 R15: 0000000000000005
[ 181.844121] FS: 00007c6e323bb5c0(0000) GS:ffff9e3f85f80000(0000) knlGS:0000000000000000
[ 181.844128] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 181.844134] CR2: ffffffffffffffd6 CR3: 0000000140fbe000 CR4: 00000000003506e0
[ 181.844141] Call Trace:
[ 181.844146] <TASK>
[ 181.844153] ? show_regs+0x6d/0x80
[ 181.844167] ? __die+0x24/0x80
[ 181.844179] ? page_fault_oops+0x99/0x1b0
[ 181.844192] ? do_user_addr_fault+0x31d/0x6b0
[ 181.844204] ? exc_page_fault+0x83/0x1b0
[ 181.844216] ? asm_exc_page_fault+0x27/0x30
[ 181.844237] dcn20_get_dcc_compression_cap+0x23/0x30 [amdgpu]
[ 181.845115] amdgpu_dm_plane_validate_dcc.constprop.0+0xe5/0x180 [amdgpu]
[ 181.845985] amdgpu_dm_plane_fill_plane_buffer_attributes+0x300/0x580 [amdgpu]
[ 181.846848] fill_dc_plane_info_and_addr+0x258/0x350 [amdgpu]
[ 181.847734] fill_dc_plane_attributes+0x162/0x350 [amdgpu]
[ 181.848748] dm_update_plane_state.constprop.0+0x4e3/0x6b0 [amdgpu]
[ 181.849791] ? dm_update_plane_state.constprop.0+0x4e3/0x6b0 [amdgpu]
[ 181.850840] amdgpu_dm_atomic_check+0xdfe/0x1760 [amdgpu]
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 8224b9bf01d1b..2a567c4fd80b6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2173,10 +2173,11 @@ bool dcn20_get_dcc_compression_cap(const struct dc *dc,
const struct dc_dcc_surface_param *input,
struct dc_surface_dcc_cap *output)
{
- return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
- dc->res_pool->hubbub,
- input,
- output);
+ if (dc->res_pool->hubbub->funcs->get_dcc_compression_cap)
+ return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
+ dc->res_pool->hubbub, input, output);
+
+ return false;
}
static void dcn20_destroy_resource_pool(struct resource_pool **pool)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0643/1887] nvme: apple: fix device reference counting
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (641 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0642/1887] drm/amd/display: Fix null pointer deref in dcn20_resource.c Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0644/1887] f2fs: fix to cover read extent cache access with lock Greg Kroah-Hartman
` (355 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig,
Chaitanya Kulkarni, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <kbusch@kernel.org>
[ Upstream commit b9ecbfa45516182cd062fecd286db7907ba84210 ]
Drivers must call nvme_uninit_ctrl after a successful nvme_init_ctrl.
Split the allocation side out to make the error handling boundary easier
to navigate. The apple driver had been doing this wrong, leaking the
controller device memory on a tagset failure.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/apple.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
index 994cf755de093..4822248a624ad 100644
--- a/drivers/nvme/host/apple.c
+++ b/drivers/nvme/host/apple.c
@@ -1387,7 +1387,7 @@ static void devm_apple_nvme_mempool_destroy(void *data)
mempool_destroy(data);
}
-static int apple_nvme_probe(struct platform_device *pdev)
+static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct apple_nvme *anv;
@@ -1395,7 +1395,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
if (!anv)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
anv->dev = get_device(dev);
anv->adminq.is_adminq = true;
@@ -1515,10 +1515,26 @@ static int apple_nvme_probe(struct platform_device *pdev)
goto put_dev;
}
+ return anv;
+put_dev:
+ put_device(anv->dev);
+ return ERR_PTR(ret);
+}
+
+static int apple_nvme_probe(struct platform_device *pdev)
+{
+ struct apple_nvme *anv;
+ int ret;
+
+ anv = apple_nvme_alloc(pdev);
+ if (IS_ERR(anv))
+ return PTR_ERR(anv);
+
anv->ctrl.admin_q = blk_mq_init_queue(&anv->admin_tagset);
if (IS_ERR(anv->ctrl.admin_q)) {
ret = -ENOMEM;
- goto put_dev;
+ anv->ctrl.admin_q = NULL;
+ goto out_uninit_ctrl;
}
if (!blk_get_queue(anv->ctrl.admin_q)) {
@@ -1527,7 +1543,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
blk_put_queue(anv->ctrl.admin_q);
anv->ctrl.admin_q = NULL;
ret = -ENODEV;
- goto put_dev;
+ goto out_uninit_ctrl;
}
nvme_reset_ctrl(&anv->ctrl);
@@ -1535,8 +1551,9 @@ static int apple_nvme_probe(struct platform_device *pdev)
return 0;
-put_dev:
- put_device(anv->dev);
+out_uninit_ctrl:
+ nvme_uninit_ctrl(&anv->ctrl);
+ nvme_put_ctrl(&anv->ctrl);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0644/1887] f2fs: fix to cover read extent cache access with lock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (642 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0643/1887] nvme: apple: fix device reference counting Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0645/1887] f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC Greg Kroah-Hartman
` (354 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+74ebe2104433e9dc610d, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit d7409b05a64f212735f0d33f5f1602051a886eab ]
syzbot reports a f2fs bug as below:
BUG: KASAN: slab-use-after-free in sanity_check_extent_cache+0x370/0x410 fs/f2fs/extent_cache.c:46
Read of size 4 at addr ffff8880739ab220 by task syz-executor200/5097
CPU: 0 PID: 5097 Comm: syz-executor200 Not tainted 6.9.0-rc6-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
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
sanity_check_extent_cache+0x370/0x410 fs/f2fs/extent_cache.c:46
do_read_inode fs/f2fs/inode.c:509 [inline]
f2fs_iget+0x33e1/0x46e0 fs/f2fs/inode.c:560
f2fs_nfs_get_inode+0x74/0x100 fs/f2fs/super.c:3237
generic_fh_to_dentry+0x9f/0xf0 fs/libfs.c:1413
exportfs_decode_fh_raw+0x152/0x5f0 fs/exportfs/expfs.c:444
exportfs_decode_fh+0x3c/0x80 fs/exportfs/expfs.c:584
do_handle_to_path fs/fhandle.c:155 [inline]
handle_to_path fs/fhandle.c:210 [inline]
do_handle_open+0x495/0x650 fs/fhandle.c:226
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
We missed to cover sanity_check_extent_cache() w/ extent cache lock,
so, below race case may happen, result in use after free issue.
- f2fs_iget
- do_read_inode
- f2fs_init_read_extent_tree
: add largest extent entry in to cache
- shrink
- f2fs_shrink_read_extent_tree
- __shrink_extent_tree
- __detach_extent_node
: drop largest extent entry
- sanity_check_extent_cache
: access et->largest w/o lock
let's refactor sanity_check_extent_cache() to avoid extent cache access
and call it before f2fs_init_read_extent_tree() to fix this issue.
Reported-by: syzbot+74ebe2104433e9dc610d@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/00000000000009beea061740a531@google.com
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/extent_cache.c | 44 ++++++++++++++++++++----------------------
fs/f2fs/f2fs.h | 2 +-
fs/f2fs/inode.c | 8 ++++----
3 files changed, 26 insertions(+), 28 deletions(-)
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index 0b35892e9eb6c..f84493c7b072c 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -15,26 +15,24 @@
#include "node.h"
#include <trace/events/f2fs.h>
-bool sanity_check_extent_cache(struct inode *inode)
+bool sanity_check_extent_cache(struct inode *inode, struct page *ipage)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
- struct f2fs_inode_info *fi = F2FS_I(inode);
- struct extent_info *ei;
+ struct f2fs_extent *i_ext = &F2FS_INODE(ipage)->i_ext;
+ struct extent_info ei;
- if (!fi->extent_tree[EX_READ])
- return true;
+ get_read_extent_info(&ei, i_ext);
- ei = &fi->extent_tree[EX_READ]->largest;
+ if (!ei.len)
+ return true;
- if (ei->len &&
- (!f2fs_is_valid_blkaddr(sbi, ei->blk,
- DATA_GENERIC_ENHANCE) ||
- !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
- DATA_GENERIC_ENHANCE))) {
+ if (!f2fs_is_valid_blkaddr(sbi, ei.blk, DATA_GENERIC_ENHANCE) ||
+ !f2fs_is_valid_blkaddr(sbi, ei.blk + ei.len - 1,
+ DATA_GENERIC_ENHANCE)) {
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix",
__func__, inode->i_ino,
- ei->blk, ei->fofs, ei->len);
+ ei.blk, ei.fofs, ei.len);
return false;
}
return true;
@@ -442,24 +440,22 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage)
if (!__may_extent_tree(inode, EX_READ)) {
/* drop largest read extent */
- if (i_ext && i_ext->len) {
+ if (i_ext->len) {
f2fs_wait_on_page_writeback(ipage, NODE, true, true);
i_ext->len = 0;
set_page_dirty(ipage);
}
- goto out;
+ set_inode_flag(inode, FI_NO_EXTENT);
+ return;
}
et = __grab_extent_tree(inode, EX_READ);
- if (!i_ext || !i_ext->len)
- goto out;
-
get_read_extent_info(&ei, i_ext);
write_lock(&et->lock);
- if (atomic_read(&et->node_cnt))
- goto unlock_out;
+ if (atomic_read(&et->node_cnt) || !ei.len)
+ goto skip;
en = __attach_extent_node(sbi, et, &ei, NULL,
&et->root.rb_root.rb_node, true);
@@ -471,11 +467,13 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage)
list_add_tail(&en->list, &eti->extent_list);
spin_unlock(&eti->extent_lock);
}
-unlock_out:
+skip:
+ /* Let's drop, if checkpoint got corrupted. */
+ if (f2fs_cp_error(sbi)) {
+ et->largest.len = 0;
+ et->largest_updated = true;
+ }
write_unlock(&et->lock);
-out:
- if (!F2FS_I(inode)->extent_tree[EX_READ])
- set_inode_flag(inode, FI_NO_EXTENT);
}
void f2fs_init_extent_tree(struct inode *inode)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f18e380967678..6d22c18f948d3 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4164,7 +4164,7 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
/*
* extent_cache.c
*/
-bool sanity_check_extent_cache(struct inode *inode);
+bool sanity_check_extent_cache(struct inode *inode, struct page *ipage);
struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
struct rb_entry *cached_re, unsigned int ofs);
struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 1715663e26a8d..e97aa6a8ac53b 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -455,15 +455,15 @@ static int do_read_inode(struct inode *inode)
init_idisk_time(inode);
- /* Need all the flag bits */
- f2fs_init_read_extent_tree(inode, node_page);
-
- if (!sanity_check_extent_cache(inode)) {
+ if (!sanity_check_extent_cache(inode, node_page)) {
f2fs_put_page(node_page, 1);
f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
return -EFSCORRUPTED;
}
+ /* Need all the flag bits */
+ f2fs_init_read_extent_tree(inode, node_page);
+
f2fs_put_page(node_page, 1);
stat_inc_inline_xattr(inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0645/1887] f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (643 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0644/1887] f2fs: fix to cover read extent cache access with lock Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0646/1887] btrfs: do not BUG_ON() when freeing tree block after error Greg Kroah-Hartman
` (353 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+848062ba19c8782ca5c8, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit fc01008c92f40015aeeced94750855a7111b6929 ]
syzbot reports a f2fs bug as below:
------------[ cut here ]------------
kernel BUG at fs/f2fs/inline.c:258!
CPU: 1 PID: 34 Comm: kworker/u8:2 Not tainted 6.9.0-rc6-syzkaller-00012-g9e4bc4bcae01 #0
RIP: 0010:f2fs_write_inline_data+0x781/0x790 fs/f2fs/inline.c:258
Call Trace:
f2fs_write_single_data_page+0xb65/0x1d60 fs/f2fs/data.c:2834
f2fs_write_cache_pages fs/f2fs/data.c:3133 [inline]
__f2fs_write_data_pages fs/f2fs/data.c:3288 [inline]
f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3315
do_writepages+0x35b/0x870 mm/page-writeback.c:2612
__writeback_single_inode+0x165/0x10b0 fs/fs-writeback.c:1650
writeback_sb_inodes+0x905/0x1260 fs/fs-writeback.c:1941
wb_writeback+0x457/0xce0 fs/fs-writeback.c:2117
wb_do_writeback fs/fs-writeback.c:2264 [inline]
wb_workfn+0x410/0x1090 fs/fs-writeback.c:2304
process_one_work kernel/workqueue.c:3254 [inline]
process_scheduled_works+0xa12/0x17c0 kernel/workqueue.c:3335
worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
kthread+0x2f2/0x390 kernel/kthread.c:388
ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
The root cause is: inline_data inode can be fuzzed, so that there may
be valid blkaddr in its direct node, once f2fs triggers background GC
to migrate the block, it will hit f2fs_bug_on() during dirty page
writeback.
Let's add sanity check on F2FS_INLINE_DATA flag in inode during GC,
so that, it can forbid migrating inline_data inode's data block for
fixing.
Reported-by: syzbot+848062ba19c8782ca5c8@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000d103ce06174d7ec3@google.com
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/gc.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index abb8f3c37b782..216171e020710 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1567,6 +1567,16 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
continue;
}
+ if (f2fs_has_inline_data(inode)) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_err(sbi,
+ "inode %lx has both inline_data flag and "
+ "data block, nid=%u, ofs_in_node=%u",
+ inode->i_ino, dni.nid, ofs_in_node);
+ iput(inode);
+ continue;
+ }
+
err = f2fs_gc_pinned_control(inode, gc_type, segno);
if (err == -EAGAIN) {
iput(inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0646/1887] btrfs: do not BUG_ON() when freeing tree block after error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (644 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0645/1887] f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0647/1887] pktgen: use cpus_read_lock() in pg_net_init() Greg Kroah-Hartman
` (352 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+a306f914b4d01b3958fe,
Qu Wenruo, Filipe Manana, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit bb3868033a4cccff7be57e9145f2117cbdc91c11 ]
When freeing a tree block, at btrfs_free_tree_block(), if we fail to
create a delayed reference we don't deal with the error and just do a
BUG_ON(). The error most likely to happen is -ENOMEM, and we have a
comment mentioning that only -ENOMEM can happen, but that is not true,
because in case qgroups are enabled any error returned from
btrfs_qgroup_trace_extent_post() (can be -EUCLEAN or anything returned
from btrfs_search_slot() for example) can be propagated back to
btrfs_free_tree_block().
So stop doing a BUG_ON() and return the error to the callers and make
them abort the transaction to prevent leaking space. Syzbot was
triggering this, likely due to memory allocation failure injection.
Reported-by: syzbot+a306f914b4d01b3958fe@syzkaller.appspotmail.com
Link: https://lore.kernel.org/linux-btrfs/000000000000fcba1e05e998263c@google.com/
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ctree.c | 65 ++++++++++++++++++++++++++++----------
fs/btrfs/ctree.h | 8 ++---
fs/btrfs/extent-tree.c | 22 +++++++------
fs/btrfs/free-space-tree.c | 10 ++++--
fs/btrfs/ioctl.c | 6 +++-
fs/btrfs/qgroup.c | 6 ++--
6 files changed, 82 insertions(+), 35 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 36f54f0f21d83..9e611f45b4b3c 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -502,10 +502,16 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
atomic_inc(&cow->refs);
rcu_assign_pointer(root->node, cow);
- btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
- parent_start, last_ref);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+ parent_start, last_ref);
free_extent_buffer(buf);
add_root_to_dirty_list(root);
+ if (ret < 0) {
+ btrfs_tree_unlock(cow);
+ free_extent_buffer(cow);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
} else {
WARN_ON(trans->transid != btrfs_header_generation(parent));
btrfs_tree_mod_log_insert_key(parent, parent_slot,
@@ -524,8 +530,14 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
return ret;
}
}
- btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
- parent_start, last_ref);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
+ parent_start, last_ref);
+ if (ret < 0) {
+ btrfs_tree_unlock(cow);
+ free_extent_buffer(cow);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
}
trace_btrfs_cow_block(root, buf, cow);
@@ -999,9 +1011,13 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
free_extent_buffer(mid);
root_sub_used(root, mid->len);
- btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
/* once for the root ptr */
free_extent_buffer_stale(mid);
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
+ goto enospc;
+ }
return 0;
}
if (btrfs_header_nritems(mid) >
@@ -1058,10 +1074,14 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_tree_unlock(right);
del_ptr(root, path, level + 1, pslot + 1);
root_sub_used(root, right->len);
- btrfs_free_tree_block(trans, btrfs_root_id(root), right,
- 0, 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root),
+ right, 0, 1);
free_extent_buffer_stale(right);
right = NULL;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
+ goto enospc;
+ }
} else {
struct btrfs_disk_key right_key;
btrfs_node_key(right, &right_key, 0);
@@ -1107,9 +1127,15 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_tree_unlock(mid);
del_ptr(root, path, level + 1, pslot);
root_sub_used(root, mid->len);
- btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1);
free_extent_buffer_stale(mid);
mid = NULL;
+ if (ret < 0) {
+ path->locks[level] = 0;
+ path->nodes[level] = NULL;
+ btrfs_abort_transaction(trans, ret);
+ goto enospc;
+ }
} else {
/* update the parent key to reflect our changes */
struct btrfs_disk_key mid_key;
@@ -4314,11 +4340,13 @@ static void del_ptr(struct btrfs_root *root, struct btrfs_path *path,
* The path must have already been setup for deleting the leaf, including
* all the proper balancing. path->nodes[1] must be locked.
*/
-static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct btrfs_path *path,
- struct extent_buffer *leaf)
+static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ struct extent_buffer *leaf)
{
+ int ret;
+
WARN_ON(btrfs_header_generation(leaf) != trans->transid);
del_ptr(root, path, 1, path->slots[1]);
@@ -4331,8 +4359,12 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans,
root_sub_used(root, leaf->len);
atomic_inc(&leaf->refs);
- btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1);
free_extent_buffer_stale(leaf);
+ if (ret < 0)
+ btrfs_abort_transaction(trans, ret);
+
+ return ret;
}
/*
* delete the item at the leaf level in path. If that empties
@@ -4387,7 +4419,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
btrfs_set_header_level(leaf, 0);
} else {
btrfs_clean_tree_block(leaf);
- btrfs_del_leaf(trans, root, path, leaf);
+ ret = btrfs_del_leaf(trans, root, path, leaf);
+ if (ret < 0)
+ return ret;
}
} else {
int used = leaf_space_used(leaf, 0, nritems);
@@ -4448,9 +4482,8 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if (btrfs_header_nritems(leaf) == 0) {
path->slots[1] = slot;
- btrfs_del_leaf(trans, root, path, leaf);
+ ret = btrfs_del_leaf(trans, root, path, leaf);
free_extent_buffer(leaf);
- ret = 0;
} else {
/* if we're still in the path, make sure
* we're dirty. Otherwise, one of the
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 16795e91aee29..90a6b36f8baf4 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2888,10 +2888,10 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
int level, u64 hint,
u64 empty_size,
enum btrfs_lock_nesting nest);
-void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
- u64 root_id,
- struct extent_buffer *buf,
- u64 parent, int last_ref);
+int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ u64 root_id,
+ struct extent_buffer *buf,
+ u64 parent, int last_ref);
int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 owner,
u64 offset, u64 ram_bytes,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 9a3c304d76b40..a09ac37f7cf48 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3280,10 +3280,10 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
return 0;
}
-void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
- u64 root_id,
- struct extent_buffer *buf,
- u64 parent, int last_ref)
+int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ u64 root_id,
+ struct extent_buffer *buf,
+ u64 parent, int last_ref)
{
struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_ref generic_ref = { 0 };
@@ -3297,7 +3297,8 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
if (root_id != BTRFS_TREE_LOG_OBJECTID) {
btrfs_ref_tree_mod(fs_info, &generic_ref);
ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
- BUG_ON(ret); /* -ENOMEM */
+ if (ret < 0)
+ return ret;
}
if (last_ref && btrfs_header_generation(buf) == trans->transid) {
@@ -3361,6 +3362,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
*/
clear_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags);
}
+ return 0;
}
/* Can return -ENOMEM */
@@ -5533,7 +5535,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
struct walk_control *wc)
{
struct btrfs_fs_info *fs_info = root->fs_info;
- int ret;
+ int ret = 0;
int level = wc->level;
struct extent_buffer *eb = path->nodes[level];
u64 parent = 0;
@@ -5628,12 +5630,14 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
goto owner_mismatch;
}
- btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
- wc->refs[level] == 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
+ wc->refs[level] == 1);
+ if (ret < 0)
+ btrfs_abort_transaction(trans, ret);
out:
wc->refs[level] = 0;
wc->flags[level] = 0;
- return 0;
+ return ret;
owner_mismatch:
btrfs_err_rl(fs_info, "unexpected tree owner, have %llu expect %llu",
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 9e966e8876f58..8c6b21531cf51 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1292,10 +1292,14 @@ int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info)
btrfs_tree_lock(free_space_root->node);
btrfs_clean_tree_block(free_space_root->node);
btrfs_tree_unlock(free_space_root->node);
- btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
- free_space_root->node, 0, 1);
-
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
+ free_space_root->node, 0, 1);
btrfs_put_root(free_space_root);
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
+ btrfs_end_transaction(trans);
+ return ret;
+ }
return btrfs_commit_transaction(trans);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index e278da90888e1..bc1f605e55a20 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -696,6 +696,8 @@ static noinline int create_subvol(struct user_namespace *mnt_userns,
ret = btrfs_insert_root(trans, fs_info->tree_root, &key,
root_item);
if (ret) {
+ int ret2;
+
/*
* Since we don't abort the transaction in this case, free the
* tree block so that we don't leak space and leave the
@@ -706,7 +708,9 @@ static noinline int create_subvol(struct user_namespace *mnt_userns,
btrfs_tree_lock(leaf);
btrfs_clean_tree_block(leaf);
btrfs_tree_unlock(leaf);
- btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
+ ret2 = btrfs_free_tree_block(trans, objectid, leaf, 0, 1);
+ if (ret2 < 0)
+ btrfs_abort_transaction(trans, ret2);
free_extent_buffer(leaf);
goto out;
}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index e80d73ad08103..e927111567fa2 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1325,9 +1325,11 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
btrfs_tree_lock(quota_root->node);
btrfs_clean_tree_block(quota_root->node);
btrfs_tree_unlock(quota_root->node);
- btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
- quota_root->node, 0, 1);
+ ret = btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
+ quota_root->node, 0, 1);
+ if (ret < 0)
+ btrfs_abort_transaction(trans, ret);
out:
btrfs_put_root(quota_root);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0647/1887] pktgen: use cpus_read_lock() in pg_net_init()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (645 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0646/1887] btrfs: do not BUG_ON() when freeing tree block after error Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0648/1887] drm/amd/display: Check index for aux_rd_interval before using Greg Kroah-Hartman
` (351 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 979b581e4c69257acab1af415ddad6b2d78a2fa5 ]
I have seen the WARN_ON(smp_processor_id() != cpu) firing
in pktgen_thread_worker() during tests.
We must use cpus_read_lock()/cpus_read_unlock()
around the for_each_online_cpu(cpu) loop.
While we are at it use WARN_ON_ONCE() to avoid a possible syslog flood.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20240821175339.1191779-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/pktgen.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 23ec71a882906..9756e9f9be645 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -114,6 +114,7 @@
#include <linux/sys.h>
#include <linux/types.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -3615,7 +3616,7 @@ static int pktgen_thread_worker(void *arg)
struct pktgen_dev *pkt_dev = NULL;
int cpu = t->cpu;
- WARN_ON(smp_processor_id() != cpu);
+ WARN_ON_ONCE(smp_processor_id() != cpu);
init_waitqueue_head(&t->queue);
complete(&t->start_done);
@@ -3951,6 +3952,7 @@ static int __net_init pg_net_init(struct net *net)
goto remove;
}
+ cpus_read_lock();
for_each_online_cpu(cpu) {
int err;
@@ -3959,6 +3961,7 @@ static int __net_init pg_net_init(struct net *net)
pr_warn("Cannot create thread for cpu %d (%d)\n",
cpu, err);
}
+ cpus_read_unlock();
if (list_empty(&pn->pktgen_threads)) {
pr_err("Initialization failed for all threads\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0648/1887] drm/amd/display: Check index for aux_rd_interval before using
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (646 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0647/1887] pktgen: use cpus_read_lock() in pg_net_init() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0649/1887] drm/amd/display: Ensure array index tg_inst wont be -1 Greg Kroah-Hartman
` (350 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Tom Chung,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit 9ba2ea6337b4f159aecb177555a6a81da92d302e ]
aux_rd_interval has size of 7 and should be checked.
This fixes 3 OVERRUN and 1 INTEGER_OVERFLOW issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 1d3d9a82c4637..717e36172a718 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1676,10 +1676,10 @@ static enum dc_status configure_lttpr_mode_non_transparent(
/* Driver does not need to train the first hop. Skip DPCD read and clear
* AUX_RD_INTERVAL for DPTX-to-DPIA hop.
*/
- if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && repeater_cnt > 0 && repeater_cnt < MAX_REPEATER_CNT)
link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0;
- for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
+ for (repeater_id = repeater_cnt; repeater_id > 0 && repeater_id < MAX_REPEATER_CNT; repeater_id--) {
aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
core_link_read_dpcd(
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0649/1887] drm/amd/display: Ensure array index tg_inst wont be -1
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (647 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0648/1887] drm/amd/display: Check index for aux_rd_interval before using Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0650/1887] ice: protect XDP configuration with a mutex Greg Kroah-Hartman
` (349 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harry Wentland, Tom Chung, Alex Hung,
Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit 687fe329f18ab0ab0496b20ed2cb003d4879d931 ]
[WHY & HOW]
tg_inst will be a negative if timing_generator_count equals 0, which
should be checked before used.
This fixes 2 OVERRUN issues reported by Coverity.
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 876b70157faa3..5adae27fb460d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -2115,7 +2115,7 @@ static int acquire_first_free_pipe(
pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
pipe_ctx->pipe_idx = i;
- if (i >= pool->timing_generator_count) {
+ if (i >= pool->timing_generator_count && pool->timing_generator_count != 0) {
int tg_inst = pool->timing_generator_count - 1;
pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0650/1887] ice: protect XDP configuration with a mutex
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (648 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0649/1887] drm/amd/display: Ensure array index tg_inst wont be -1 Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0651/1887] userfaultfd: fix checks for huge PMDs Greg Kroah-Hartman
` (348 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wojciech Drewek, Jacob Keller,
Chandan Kumar Rout, Larysa Zaremba, Maciej Fijalkowski,
Tony Nguyen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <larysa.zaremba@intel.com>
[ Upstream commit 2504b8405768a57a71e660dbfd5abd59f679a03f ]
The main threat to data consistency in ice_xdp() is a possible asynchronous
PF reset. It can be triggered by a user or by TX timeout handler.
XDP setup and PF reset code access the same resources in the following
sections:
* ice_vsi_close() in ice_prepare_for_reset() - already rtnl-locked
* ice_vsi_rebuild() for the PF VSI - not protected
* ice_vsi_open() - already rtnl-locked
With an unfortunate timing, such accesses can result in a crash such as the
one below:
[ +1.999878] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 14
[ +2.002992] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 18
[Mar15 18:17] ice 0000:b1:00.0 ens801f0np0: NETDEV WATCHDOG: CPU: 38: transmit queue 14 timed out 80692736 ms
[ +0.000093] ice 0000:b1:00.0 ens801f0np0: tx_timeout: VSI_num: 6, Q 14, NTC: 0x0, HW_HEAD: 0x0, NTU: 0x0, INT: 0x4000001
[ +0.000012] ice 0000:b1:00.0 ens801f0np0: tx_timeout recovery level 1, txqueue 14
[ +0.394718] ice 0000:b1:00.0: PTP reset successful
[ +0.006184] BUG: kernel NULL pointer dereference, address: 0000000000000098
[ +0.000045] #PF: supervisor read access in kernel mode
[ +0.000023] #PF: error_code(0x0000) - not-present page
[ +0.000023] PGD 0 P4D 0
[ +0.000018] Oops: 0000 [#1] PREEMPT SMP NOPTI
[ +0.000023] CPU: 38 PID: 7540 Comm: kworker/38:1 Not tainted 6.8.0-rc7 #1
[ +0.000031] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0014.082620210524 08/26/2021
[ +0.000036] Workqueue: ice ice_service_task [ice]
[ +0.000183] RIP: 0010:ice_clean_tx_ring+0xa/0xd0 [ice]
[...]
[ +0.000013] Call Trace:
[ +0.000016] <TASK>
[ +0.000014] ? __die+0x1f/0x70
[ +0.000029] ? page_fault_oops+0x171/0x4f0
[ +0.000029] ? schedule+0x3b/0xd0
[ +0.000027] ? exc_page_fault+0x7b/0x180
[ +0.000022] ? asm_exc_page_fault+0x22/0x30
[ +0.000031] ? ice_clean_tx_ring+0xa/0xd0 [ice]
[ +0.000194] ice_free_tx_ring+0xe/0x60 [ice]
[ +0.000186] ice_destroy_xdp_rings+0x157/0x310 [ice]
[ +0.000151] ice_vsi_decfg+0x53/0xe0 [ice]
[ +0.000180] ice_vsi_rebuild+0x239/0x540 [ice]
[ +0.000186] ice_vsi_rebuild_by_type+0x76/0x180 [ice]
[ +0.000145] ice_rebuild+0x18c/0x840 [ice]
[ +0.000145] ? delay_tsc+0x4a/0xc0
[ +0.000022] ? delay_tsc+0x92/0xc0
[ +0.000020] ice_do_reset+0x140/0x180 [ice]
[ +0.000886] ice_service_task+0x404/0x1030 [ice]
[ +0.000824] process_one_work+0x171/0x340
[ +0.000685] worker_thread+0x277/0x3a0
[ +0.000675] ? preempt_count_add+0x6a/0xa0
[ +0.000677] ? _raw_spin_lock_irqsave+0x23/0x50
[ +0.000679] ? __pfx_worker_thread+0x10/0x10
[ +0.000653] kthread+0xf0/0x120
[ +0.000635] ? __pfx_kthread+0x10/0x10
[ +0.000616] ret_from_fork+0x2d/0x50
[ +0.000612] ? __pfx_kthread+0x10/0x10
[ +0.000604] ret_from_fork_asm+0x1b/0x30
[ +0.000604] </TASK>
The previous way of handling this through returning -EBUSY is not viable,
particularly when destroying AF_XDP socket, because the kernel proceeds
with removal anyway.
There is plenty of code between those calls and there is no need to create
a large critical section that covers all of them, same as there is no need
to protect ice_vsi_rebuild() with rtnl_lock().
Add xdp_state_lock mutex to protect ice_vsi_rebuild() and ice_xdp().
Leaving unprotected sections in between would result in two states that
have to be considered:
1. when the VSI is closed, but not yet rebuild
2. when VSI is already rebuild, but not yet open
The latter case is actually already handled through !netif_running() case,
we just need to adjust flag checking a little. The former one is not as
trivial, because between ice_vsi_close() and ice_vsi_rebuild(), a lot of
hardware interaction happens, this can make adding/deleting rings exit
with an error. Luckily, VSI rebuild is pending and can apply new
configuration for us in a managed fashion.
Therefore, add an additional VSI state flag ICE_VSI_REBUILD_PENDING to
indicate that ice_xdp() can just hot-swap the program.
Also, as ice_vsi_rebuild() flow is touched in this patch, make it more
consistent by deconfiguring VSI when coalesce allocation fails.
Fixes: 2d4238f55697 ("ice: Add support for AF_XDP")
Fixes: efc2214b6047 ("ice: Add support for XDP")
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com>
Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice.h | 2 ++
drivers/net/ethernet/intel/ice/ice_lib.c | 18 ++++++++++++++++--
drivers/net/ethernet/intel/ice/ice_main.c | 20 +++++++++++++++-----
drivers/net/ethernet/intel/ice/ice_xsk.c | 3 ++-
4 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 1fe9cccf18d2f..874d6133cb177 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -302,6 +302,7 @@ enum ice_vsi_state {
ICE_VSI_UMAC_FLTR_CHANGED,
ICE_VSI_MMAC_FLTR_CHANGED,
ICE_VSI_PROMISC_CHANGED,
+ ICE_VSI_REBUILD_PENDING,
ICE_VSI_STATE_NBITS /* must be last */
};
@@ -390,6 +391,7 @@ struct ice_vsi {
struct ice_tx_ring **xdp_rings; /* XDP ring array */
u16 num_xdp_txq; /* Used XDP queues */
u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */
+ struct mutex xdp_state_lock;
struct net_device **target_netdevs;
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 347c6c23bfc1c..441e8a6c26a13 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -365,6 +365,7 @@ int ice_vsi_clear(struct ice_vsi *vsi)
pf->next_vsi = vsi->idx;
ice_vsi_free_arrays(vsi);
+ mutex_destroy(&vsi->xdp_state_lock);
mutex_unlock(&pf->sw_mutex);
devm_kfree(dev, vsi);
@@ -540,6 +541,8 @@ ice_vsi_alloc(struct ice_pf *pf, enum ice_vsi_type vsi_type,
if (vsi->type == ICE_VSI_CTRL && vf)
vf->ctrl_vsi_idx = vsi->idx;
+
+ mutex_init(&vsi->xdp_state_lock);
goto unlock_pf;
err_rings:
@@ -3204,10 +3207,14 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
ice_vsi_init_vlan_ops(vsi);
+ mutex_lock(&vsi->xdp_state_lock);
+
coalesce = kcalloc(vsi->num_q_vectors,
sizeof(struct ice_coalesce_stored), GFP_KERNEL);
- if (!coalesce)
+ if (!coalesce) {
+ mutex_unlock(&vsi->xdp_state_lock);
return -ENOMEM;
+ }
prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
@@ -3230,7 +3237,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
vsi->base_vector = 0;
}
- if (ice_is_xdp_ena_vsi(vsi))
+ if (vsi->xdp_rings)
/* return value check can be skipped here, it always returns
* 0 if reset is in progress
*/
@@ -3358,24 +3365,31 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
ret = -EIO;
goto err_vectors;
} else {
+ mutex_unlock(&vsi->xdp_state_lock);
return ice_schedule_reset(pf, ICE_RESET_PFR);
}
}
ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors);
+ clear_bit(ICE_VSI_REBUILD_PENDING, vsi->state);
kfree(coalesce);
+ mutex_unlock(&vsi->xdp_state_lock);
return 0;
err_vectors:
ice_vsi_free_q_vectors(vsi);
err_rings:
+ mutex_unlock(&vsi->xdp_state_lock);
if (vsi->netdev) {
vsi->current_netdev_flags = 0;
unregister_netdev(vsi->netdev);
free_netdev(vsi->netdev);
vsi->netdev = NULL;
}
+ goto err_clear;
err_vsi:
+ mutex_unlock(&vsi->xdp_state_lock);
+err_clear:
ice_vsi_clear(vsi);
set_bit(ICE_RESET_FAILED, pf->state);
kfree(coalesce);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index e923b64f2a668..75fede7d31749 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -620,6 +620,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
/* clear SW filtering DB */
ice_clear_hw_tbls(hw);
/* disable the VSIs and their queues that are not already DOWN */
+ set_bit(ICE_VSI_REBUILD_PENDING, ice_get_main_vsi(pf)->state);
ice_pf_dis_all_vsi(pf, false);
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
@@ -2770,6 +2771,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
mutex_unlock(&pf->avail_q_mutex);
devm_kfree(dev, vsi->xdp_rings);
+ vsi->xdp_rings = NULL;
return -ENOMEM;
}
@@ -2919,7 +2921,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
}
/* hot swap progs and avoid toggling link */
- if (ice_is_xdp_ena_vsi(vsi) == !!prog) {
+ if (ice_is_xdp_ena_vsi(vsi) == !!prog ||
+ test_bit(ICE_VSI_REBUILD_PENDING, vsi->state)) {
ice_vsi_assign_bpf_prog(vsi, prog);
return 0;
}
@@ -2991,21 +2994,28 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
struct ice_netdev_priv *np = netdev_priv(dev);
struct ice_vsi *vsi = np->vsi;
+ int ret;
if (vsi->type != ICE_VSI_PF) {
NL_SET_ERR_MSG_MOD(xdp->extack, "XDP can be loaded only on PF VSI");
return -EINVAL;
}
+ mutex_lock(&vsi->xdp_state_lock);
+
switch (xdp->command) {
case XDP_SETUP_PROG:
- return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
+ ret = ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
+ break;
case XDP_SETUP_XSK_POOL:
- return ice_xsk_pool_setup(vsi, xdp->xsk.pool,
- xdp->xsk.queue_id);
+ ret = ice_xsk_pool_setup(vsi, xdp->xsk.pool, xdp->xsk.queue_id);
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
+
+ mutex_unlock(&vsi->xdp_state_lock);
+ return ret;
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c
index 2677d7c86a6d7..98d827db84848 100644
--- a/drivers/net/ethernet/intel/ice/ice_xsk.c
+++ b/drivers/net/ethernet/intel/ice/ice_xsk.c
@@ -388,7 +388,8 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
goto failure;
}
- if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi);
+ if_running = !test_bit(ICE_VSI_DOWN, vsi->state) &&
+ ice_is_xdp_ena_vsi(vsi);
if (if_running) {
struct ice_rx_ring *rx_ring = vsi->rx_rings[qid];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0651/1887] userfaultfd: fix checks for huge PMDs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (649 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0650/1887] ice: protect XDP configuration with a mutex Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0652/1887] drm/amd/display: Use kcalloc() instead of kzalloc() Greg Kroah-Hartman
` (347 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jann Horn, David Hildenbrand,
Andrea Arcangeli, Hugh Dickins, Pavel Emelyanov, Qi Zheng,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <jannh@google.com>
[ Upstream commit 71c186efc1b2cf1aeabfeff3b9bd5ac4c5ac14d8 ]
Patch series "userfaultfd: fix races around pmd_trans_huge() check", v2.
The pmd_trans_huge() code in mfill_atomic() is wrong in three different
ways depending on kernel version:
1. The pmd_trans_huge() check is racy and can lead to a BUG_ON() (if you hit
the right two race windows) - I've tested this in a kernel build with
some extra mdelay() calls. See the commit message for a description
of the race scenario.
On older kernels (before 6.5), I think the same bug can even
theoretically lead to accessing transhuge page contents as a page table
if you hit the right 5 narrow race windows (I haven't tested this case).
2. As pointed out by Qi Zheng, pmd_trans_huge() is not sufficient for
detecting PMDs that don't point to page tables.
On older kernels (before 6.5), you'd just have to win a single fairly
wide race to hit this.
I've tested this on 6.1 stable by racing migration (with a mdelay()
patched into try_to_migrate()) against UFFDIO_ZEROPAGE - on my x86
VM, that causes a kernel oops in ptlock_ptr().
3. On newer kernels (>=6.5), for shmem mappings, khugepaged is allowed
to yank page tables out from under us (though I haven't tested that),
so I think the BUG_ON() checks in mfill_atomic() are just wrong.
I decided to write two separate fixes for these (one fix for bugs 1+2, one
fix for bug 3), so that the first fix can be backported to kernels
affected by bugs 1+2.
This patch (of 2):
This fixes two issues.
I discovered that the following race can occur:
mfill_atomic other thread
============ ============
<zap PMD>
pmdp_get_lockless() [reads none pmd]
<bail if trans_huge>
<if none:>
<pagefault creates transhuge zeropage>
__pte_alloc [no-op]
<zap PMD>
<bail if pmd_trans_huge(*dst_pmd)>
BUG_ON(pmd_none(*dst_pmd))
I have experimentally verified this in a kernel with extra mdelay() calls;
the BUG_ON(pmd_none(*dst_pmd)) triggers.
On kernels newer than commit 0d940a9b270b ("mm/pgtable: allow
pte_offset_map[_lock]() to fail"), this can't lead to anything worse than
a BUG_ON(), since the page table access helpers are actually designed to
deal with page tables concurrently disappearing; but on older kernels
(<=6.4), I think we could probably theoretically race past the two
BUG_ON() checks and end up treating a hugepage as a page table.
The second issue is that, as Qi Zheng pointed out, there are other types
of huge PMDs that pmd_trans_huge() can't catch: devmap PMDs and swap PMDs
(in particular, migration PMDs).
On <=6.4, this is worse than the first issue: If mfill_atomic() runs on a
PMD that contains a migration entry (which just requires winning a single,
fairly wide race), it will pass the PMD to pte_offset_map_lock(), which
assumes that the PMD points to a page table.
Breakage follows: First, the kernel tries to take the PTE lock (which will
crash or maybe worse if there is no "struct page" for the address bits in
the migration entry PMD - I think at least on X86 there usually is no
corresponding "struct page" thanks to the PTE inversion mitigation, amd64
looks different).
If that didn't crash, the kernel would next try to write a PTE into what
it wrongly thinks is a page table.
As part of fixing these issues, get rid of the check for pmd_trans_huge()
before __pte_alloc() - that's redundant, we're going to have to check for
that after the __pte_alloc() anyway.
Backport note: pmdp_get_lockless() is pmd_read_atomic() in older kernels.
Link: https://lkml.kernel.org/r/20240813-uffd-thp-flip-fix-v2-0-5efa61078a41@google.com
Link: https://lkml.kernel.org/r/20240813-uffd-thp-flip-fix-v2-1-5efa61078a41@google.com
Fixes: c1a4de99fada ("userfaultfd: mcopy_atomic|mfill_zeropage: UFFDIO_COPY|UFFDIO_ZEROPAGE preparation")
Signed-off-by: Jann Horn <jannh@google.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/userfaultfd.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 992a0a16846f7..998c7075c62a5 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -642,21 +642,23 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm,
}
dst_pmdval = pmd_read_atomic(dst_pmd);
- /*
- * If the dst_pmd is mapped as THP don't
- * override it and just be strict.
- */
- if (unlikely(pmd_trans_huge(dst_pmdval))) {
- err = -EEXIST;
- break;
- }
if (unlikely(pmd_none(dst_pmdval)) &&
unlikely(__pte_alloc(dst_mm, dst_pmd))) {
err = -ENOMEM;
break;
}
- /* If an huge pmd materialized from under us fail */
- if (unlikely(pmd_trans_huge(*dst_pmd))) {
+ dst_pmdval = pmd_read_atomic(dst_pmd);
+ /*
+ * If the dst_pmd is THP don't override it and just be strict.
+ * (This includes the case where the PMD used to be THP and
+ * changed back to none after __pte_alloc().)
+ */
+ if (unlikely(!pmd_present(dst_pmdval) || pmd_trans_huge(dst_pmdval) ||
+ pmd_devmap(dst_pmdval))) {
+ err = -EEXIST;
+ break;
+ }
+ if (unlikely(pmd_bad(dst_pmdval))) {
err = -EFAULT;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0652/1887] drm/amd/display: Use kcalloc() instead of kzalloc()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (650 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0651/1887] userfaultfd: fix checks for huge PMDs Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0653/1887] drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range Greg Kroah-Hartman
` (346 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Lenko Donchev,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lenko Donchev <lenko.donchev@gmail.com>
[ Upstream commit f634ee1737e7b856bd4c3f040af867007d1cb7b8 ]
We are trying to get rid of all multiplications from allocation
functions to prevent integer overflows. Here the multiplication is
obviously safe, but using kcalloc() is more appropriate and improves
readability. This patch has no effect on runtime behavior.
Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments
Link: https://github.com/KSPP/linux/issues/162
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Lenko Donchev <lenko.donchev@gmail.com>
Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 5524fa301ba6 ("drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
index aefca9756dbe8..5ec6f079b08c4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
@@ -161,7 +161,7 @@ static void dpcd_extend_address_range(
if (new_addr_range.start != in_address || new_addr_range.end != end_address) {
*out_address = new_addr_range.start;
*out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end);
- *out_data = kzalloc(*out_size * sizeof(**out_data), GFP_KERNEL);
+ *out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0653/1887] drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (651 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0652/1887] drm/amd/display: Use kcalloc() instead of kzalloc() Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0654/1887] drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box Greg Kroah-Hartman
` (345 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Hung, Rodrigo Siqueira,
Tom Chung, Hersen Wu, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hersen Wu <hersenxs.wu@amd.com>
[ Upstream commit 5524fa301ba649f8cf00848f91468e0ba7e4f24c ]
[Why & How]
ASSERT if return NULL from kcalloc.
Reviewed-by: Alex Hung <alex.hung@amd.com>
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
index 5ec6f079b08c4..f3838286c1725 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
@@ -162,6 +162,7 @@ static void dpcd_extend_address_range(
*out_address = new_addr_range.start;
*out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end);
*out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL);
+ ASSERT(*out_data);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0654/1887] drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (652 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0653/1887] drm/amd/display: Add missing NULL pointer check within dpcd_extend_address_range Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0655/1887] wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change Greg Kroah-Hartman
` (344 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Hung, Tom Chung, Hersen Wu,
Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hersen Wu <hersenxs.wu@amd.com>
[ Upstream commit 188fd1616ec43033cedbe343b6579e9921e2d898 ]
[Why]
Coverity reports OVERRUN warning. soc.num_states could
be 40. But array range of bw_params->clk_table.entries is 8.
[How]
Assert if soc.num_states greater than 8.
Reviewed-by: Alex Hung <alex.hung@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c | 10 ++++++++++
drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c | 10 ++++++++++
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 10 ++++++++++
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c | 10 ++++++++++
4 files changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
index e2bcd205aa936..8da97a96b1ceb 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
@@ -304,6 +304,16 @@ void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
+ * MAX_NUM_DPM_LVL is 8.
+ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
+ * DC__VOLTAGE_STATES is 40.
+ */
+ if (num_states > MAX_NUM_DPM_LVL) {
+ ASSERT(0);
+ return;
+ }
+
dcn3_02_soc.num_states = num_states;
for (i = 0; i < dcn3_02_soc.num_states; i++) {
dcn3_02_soc.clock_limits[i].state = i;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
index 3eb3a021ab7d7..c283780ad0621 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
@@ -299,6 +299,16 @@ void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
+ * MAX_NUM_DPM_LVL is 8.
+ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
+ * DC__VOLTAGE_STATES is 40.
+ */
+ if (num_states > MAX_NUM_DPM_LVL) {
+ ASSERT(0);
+ return;
+ }
+
dcn3_03_soc.num_states = num_states;
for (i = 0; i < dcn3_03_soc.num_states; i++) {
dcn3_03_soc.clock_limits[i].state = i;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 9d8917f72d184..12bc611de4493 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -2508,6 +2508,16 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
+ * MAX_NUM_DPM_LVL is 8.
+ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
+ * DC__VOLTAGE_STATES is 40.
+ */
+ if (num_states > MAX_NUM_DPM_LVL) {
+ ASSERT(0);
+ return;
+ }
+
dcn3_2_soc.num_states = num_states;
for (i = 0; i < dcn3_2_soc.num_states; i++) {
dcn3_2_soc.clock_limits[i].state = i;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
index 383a409a3f54c..2c7d58ac6008e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
@@ -652,6 +652,16 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
}
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
+ * MAX_NUM_DPM_LVL is 8.
+ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
+ * DC__VOLTAGE_STATES is 40.
+ */
+ if (num_states > MAX_NUM_DPM_LVL) {
+ ASSERT(0);
+ return;
+ }
+
dcn3_21_soc.num_states = num_states;
for (i = 0; i < dcn3_21_soc.num_states; i++) {
dcn3_21_soc.clock_limits[i].state = i;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0655/1887] wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (653 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0654/1887] drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0656/1887] pinmux: Use sequential access to access desc->pinmux data Greg Kroah-Hartman
` (343 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bert Karwatzki, Felix Fietkau,
Kalle Valo, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bert Karwatzki <spasswolf@web.de>
[ Upstream commit 479ffee68d59c599f8aed8fa2dcc8e13e7bd13c3 ]
When disabling wifi mt7921_ipv6_addr_change() is called as a notifier.
At this point mvif->phy is already NULL so we cannot use it here.
Signed-off-by: Bert Karwatzki <spasswolf@web.de>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20240812104542.80760-1-spasswolf@web.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7921/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index fd91d2c537603..6c59ad33d3205 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -1436,7 +1436,7 @@ static void mt7921_ipv6_addr_change(struct ieee80211_hw *hw,
struct inet6_dev *idev)
{
struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct mt7921_dev *dev = mvif->phy->dev;
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
struct inet6_ifaddr *ifa;
struct in6_addr ns_addrs[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
struct sk_buff *skb;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0656/1887] pinmux: Use sequential access to access desc->pinmux data
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (654 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0655/1887] wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0657/1887] crypto: stm32/cryp - call finalize with bh disabled Greg Kroah-Hartman
` (342 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mukesh Ojha, Linus Walleij,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <quic_mojha@quicinc.com>
[ Upstream commit 5a3e85c3c397c781393ea5fb2f45b1f60f8a4e6e ]
When two client of the same gpio call pinctrl_select_state() for the
same functionality, we are seeing NULL pointer issue while accessing
desc->mux_owner.
Let's say two processes A, B executing in pin_request() for the same pin
and process A updates the desc->mux_usecount but not yet updated the
desc->mux_owner while process B see the desc->mux_usecount which got
updated by A path and further executes strcmp and while accessing
desc->mux_owner it crashes with NULL pointer.
Serialize the access to mux related setting with a mutex lock.
cpu0 (process A) cpu1(process B)
pinctrl_select_state() { pinctrl_select_state() {
pin_request() { pin_request() {
...
....
} else {
desc->mux_usecount++;
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
if (desc->mux_usecount > 1)
return 0;
desc->mux_owner = owner;
} }
Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
Link: https://lore.kernel.org/20241014192930.1539673-1-quic_mojha@quicinc.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pinctrl/core.c | 3 +
drivers/pinctrl/core.h | 1 +
drivers/pinctrl/pinmux.c | 173 ++++++++++++++++++++++-----------------
3 files changed, 100 insertions(+), 77 deletions(-)
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 03bfdcbc3325d..1c3dcb270ea07 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -221,6 +221,9 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
/* Set owner */
pindesc->pctldev = pctldev;
+#ifdef CONFIG_PINMUX
+ mutex_init(&pindesc->mux_lock);
+#endif
/* Copy basic pin info */
if (pin->name) {
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 840103c40c14a..f5e4ca19c17b2 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -167,6 +167,7 @@ struct pin_desc {
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
+ struct mutex mux_lock;
#endif
};
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 0cbf698d16db5..782d7d4204ad1 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "pinmux core: " fmt
#include <linux/ctype.h>
+#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -90,6 +91,7 @@ bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin)
if (!desc || !ops)
return true;
+ guard(mutex)(&desc->mux_lock);
if (ops->strict && desc->mux_usecount)
return false;
@@ -124,29 +126,31 @@ static int pin_request(struct pinctrl_dev *pctldev,
dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n",
pin, desc->name, owner);
- if ((!gpio_range || ops->strict) &&
- desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
- dev_err(pctldev->dev,
- "pin %s already requested by %s; cannot claim for %s\n",
- desc->name, desc->mux_owner, owner);
- goto out;
- }
+ scoped_guard(mutex, &desc->mux_lock) {
+ if ((!gpio_range || ops->strict) &&
+ desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
+ dev_err(pctldev->dev,
+ "pin %s already requested by %s; cannot claim for %s\n",
+ desc->name, desc->mux_owner, owner);
+ goto out;
+ }
- if ((gpio_range || ops->strict) && desc->gpio_owner) {
- dev_err(pctldev->dev,
- "pin %s already requested by %s; cannot claim for %s\n",
- desc->name, desc->gpio_owner, owner);
- goto out;
- }
+ if ((gpio_range || ops->strict) && desc->gpio_owner) {
+ dev_err(pctldev->dev,
+ "pin %s already requested by %s; cannot claim for %s\n",
+ desc->name, desc->gpio_owner, owner);
+ goto out;
+ }
- if (gpio_range) {
- desc->gpio_owner = owner;
- } else {
- desc->mux_usecount++;
- if (desc->mux_usecount > 1)
- return 0;
+ if (gpio_range) {
+ desc->gpio_owner = owner;
+ } else {
+ desc->mux_usecount++;
+ if (desc->mux_usecount > 1)
+ return 0;
- desc->mux_owner = owner;
+ desc->mux_owner = owner;
+ }
}
/* Let each pin increase references to this module */
@@ -177,12 +181,14 @@ static int pin_request(struct pinctrl_dev *pctldev,
out_free_pin:
if (status) {
- if (gpio_range) {
- desc->gpio_owner = NULL;
- } else {
- desc->mux_usecount--;
- if (!desc->mux_usecount)
- desc->mux_owner = NULL;
+ scoped_guard(mutex, &desc->mux_lock) {
+ if (gpio_range) {
+ desc->gpio_owner = NULL;
+ } else {
+ desc->mux_usecount--;
+ if (!desc->mux_usecount)
+ desc->mux_owner = NULL;
+ }
}
}
out:
@@ -218,15 +224,17 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
return NULL;
}
- if (!gpio_range) {
- /*
- * A pin should not be freed more times than allocated.
- */
- if (WARN_ON(!desc->mux_usecount))
- return NULL;
- desc->mux_usecount--;
- if (desc->mux_usecount)
- return NULL;
+ scoped_guard(mutex, &desc->mux_lock) {
+ if (!gpio_range) {
+ /*
+ * A pin should not be freed more times than allocated.
+ */
+ if (WARN_ON(!desc->mux_usecount))
+ return NULL;
+ desc->mux_usecount--;
+ if (desc->mux_usecount)
+ return NULL;
+ }
}
/*
@@ -238,13 +246,15 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
else if (ops->free)
ops->free(pctldev, pin);
- if (gpio_range) {
- owner = desc->gpio_owner;
- desc->gpio_owner = NULL;
- } else {
- owner = desc->mux_owner;
- desc->mux_owner = NULL;
- desc->mux_setting = NULL;
+ scoped_guard(mutex, &desc->mux_lock) {
+ if (gpio_range) {
+ owner = desc->gpio_owner;
+ desc->gpio_owner = NULL;
+ } else {
+ owner = desc->mux_owner;
+ desc->mux_owner = NULL;
+ desc->mux_setting = NULL;
+ }
}
module_put(pctldev->owner);
@@ -458,7 +468,8 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
- desc->mux_setting = &(setting->data.mux);
+ scoped_guard(mutex, &desc->mux_lock)
+ desc->mux_setting = &(setting->data.mux);
}
ret = ops->set_mux(pctldev, setting->data.mux.func,
@@ -472,8 +483,10 @@ int pinmux_enable_setting(const struct pinctrl_setting *setting)
err_set_mux:
for (i = 0; i < num_pins; i++) {
desc = pin_desc_get(pctldev, pins[i]);
- if (desc)
- desc->mux_setting = NULL;
+ if (desc) {
+ scoped_guard(mutex, &desc->mux_lock)
+ desc->mux_setting = NULL;
+ }
}
err_pin_request:
/* On error release all taken pins */
@@ -492,6 +505,7 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
unsigned num_pins = 0;
int i;
struct pin_desc *desc;
+ bool is_equal;
if (pctlops->get_group_pins)
ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
@@ -517,7 +531,10 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
pins[i]);
continue;
}
- if (desc->mux_setting == &(setting->data.mux)) {
+ scoped_guard(mutex, &desc->mux_lock)
+ is_equal = (desc->mux_setting == &(setting->data.mux));
+
+ if (is_equal) {
pin_free(pctldev, pins[i], NULL);
} else {
const char *gname;
@@ -609,40 +626,42 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
- if (desc->mux_owner &&
- !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
- is_hog = true;
-
- if (pmxops->strict) {
- if (desc->mux_owner)
- seq_printf(s, "pin %d (%s): device %s%s",
- pin, desc->name, desc->mux_owner,
+ scoped_guard(mutex, &desc->mux_lock) {
+ if (desc->mux_owner &&
+ !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
+ is_hog = true;
+
+ if (pmxops->strict) {
+ if (desc->mux_owner)
+ seq_printf(s, "pin %d (%s): device %s%s",
+ pin, desc->name, desc->mux_owner,
+ is_hog ? " (HOG)" : "");
+ else if (desc->gpio_owner)
+ seq_printf(s, "pin %d (%s): GPIO %s",
+ pin, desc->name, desc->gpio_owner);
+ else
+ seq_printf(s, "pin %d (%s): UNCLAIMED",
+ pin, desc->name);
+ } else {
+ /* For non-strict controllers */
+ seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
+ desc->mux_owner ? desc->mux_owner
+ : "(MUX UNCLAIMED)",
+ desc->gpio_owner ? desc->gpio_owner
+ : "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
- else if (desc->gpio_owner)
- seq_printf(s, "pin %d (%s): GPIO %s",
- pin, desc->name, desc->gpio_owner);
+ }
+
+ /* If mux: print function+group claiming the pin */
+ if (desc->mux_setting)
+ seq_printf(s, " function %s group %s\n",
+ pmxops->get_function_name(pctldev,
+ desc->mux_setting->func),
+ pctlops->get_group_name(pctldev,
+ desc->mux_setting->group));
else
- seq_printf(s, "pin %d (%s): UNCLAIMED",
- pin, desc->name);
- } else {
- /* For non-strict controllers */
- seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name,
- desc->mux_owner ? desc->mux_owner
- : "(MUX UNCLAIMED)",
- desc->gpio_owner ? desc->gpio_owner
- : "(GPIO UNCLAIMED)",
- is_hog ? " (HOG)" : "");
+ seq_putc(s, '\n');
}
-
- /* If mux: print function+group claiming the pin */
- if (desc->mux_setting)
- seq_printf(s, " function %s group %s\n",
- pmxops->get_function_name(pctldev,
- desc->mux_setting->func),
- pctlops->get_group_name(pctldev,
- desc->mux_setting->group));
- else
- seq_putc(s, '\n');
}
mutex_unlock(&pctldev->mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0657/1887] crypto: stm32/cryp - call finalize with bh disabled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (655 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0656/1887] pinmux: Use sequential access to access desc->pinmux data Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0658/1887] drm/amd/display: Refactor ABM feature Greg Kroah-Hartman
` (341 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maxime Méré, Herbert Xu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Méré <maxime.mere@foss.st.com>
[ Upstream commit 56ddb9aa3b324c2d9645b5a7343e46010cf3f6ce ]
The finalize operation in interrupt mode produce a produces a spinlock
recursion warning. The reason is the fact that BH must be disabled
during this process.
Signed-off-by: Maxime Méré <maxime.mere@foss.st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/crypto/stm32/stm32-cryp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
index 59ef541123ae6..9e7e4bdd1ac5f 100644
--- a/drivers/crypto/stm32/stm32-cryp.c
+++ b/drivers/crypto/stm32/stm32-cryp.c
@@ -4,6 +4,7 @@
* Author: Fabien Dessenne <fabien.dessenne@st.com>
*/
+#include <linux/bottom_half.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -249,7 +250,7 @@ static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp)
{
u32 status;
- return readl_relaxed_poll_timeout(cryp->regs + CRYP_SR, status,
+ return readl_relaxed_poll_timeout_atomic(cryp->regs + CRYP_SR, status,
status & SR_OFNE, 10, 100000);
}
@@ -1538,8 +1539,11 @@ static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg)
it_mask &= ~IMSCR_OUT;
stm32_cryp_write(cryp, CRYP_IMSCR, it_mask);
- if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out)
+ if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) {
+ local_bh_disable();
stm32_cryp_finish_req(cryp, 0);
+ local_bh_enable();
+ }
return IRQ_HANDLED;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0658/1887] drm/amd/display: Refactor ABM feature
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (656 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0657/1887] crypto: stm32/cryp - call finalize with bh disabled Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0659/1887] drm/amd/display: Avoid overflow from uint32_t to uint8_t Greg Kroah-Hartman
` (340 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Leon Huang,
Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Huang <Leon.Huang1@amd.com>
[ Upstream commit b8fe56375f78835db47565d91ea9d21767fe3c08 ]
[Why]
Refactor ABM feature and implement inbox command for DMUB.
[How]
Implement the ioctl to send inbox command to DMUB.
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Leon Huang <Leon.Huang1@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: d6b54900c564 ("drm/amd/display: Avoid overflow from uint32_t to uint8_t")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dce/Makefile | 2 +-
drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 264 +++++++---------
.../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 286 ++++++++++++++++++
.../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.h | 46 +++
drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 6 +
5 files changed, 442 insertions(+), 162 deletions(-)
create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
create mode 100644 drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.h
diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile
index 0d7db132a20fe..01490c9ba9587 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile
@@ -29,7 +29,7 @@
DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
-dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dce_panel_cntl.o \
+dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dmub_abm_lcd.o dce_panel_cntl.o \
dmub_hw_lock_mgr.o dmub_outbox.o
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
index fb0dec4ed3a6c..30bc598811875 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c
@@ -24,212 +24,151 @@
*/
#include "dmub_abm.h"
-#include "dce_abm.h"
+#include "dmub_abm_lcd.h"
#include "dc.h"
-#include "dc_dmub_srv.h"
-#include "dmub/dmub_srv.h"
#include "core_types.h"
-#include "dm_services.h"
-#include "reg_helper.h"
-#include "fixed31_32.h"
-
-#include "atom.h"
#define TO_DMUB_ABM(abm)\
container_of(abm, struct dce_abm, base)
-#define REG(reg) \
- (dce_abm->regs->reg)
+#define ABM_FEATURE_NO_SUPPORT 0
+#define ABM_LCD_SUPPORT 1
-#undef FN
-#define FN(reg_name, field_name) \
- dce_abm->abm_shift->field_name, dce_abm->abm_mask->field_name
+static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst)
+{
+ struct dc_context *dc = abm->ctx;
+ struct dc_link *edp_links[MAX_NUM_EDP];
+ int i;
+ int edp_num;
+ unsigned int ret = ABM_FEATURE_NO_SUPPORT;
-#define CTX \
- dce_abm->base.ctx
+ get_edp_links(dc->dc, edp_links, &edp_num);
-#define DISABLE_ABM_IMMEDIATELY 255
+ for (i = 0; i < edp_num; i++) {
+ if (panel_inst == i)
+ break;
+ }
+ if (i < edp_num) {
+ ret = ABM_LCD_SUPPORT;
+ }
+ return ret;
+}
-static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
+static void dmub_abm_init_ex(struct abm *abm, uint32_t backlight)
{
- union dmub_rb_cmd cmd;
- uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0;
- uint32_t edp_id_count = dc->dc_edp_id_count;
- int i;
- uint8_t panel_mask = 0;
-
- for (i = 0; i < edp_id_count; i++)
- panel_mask |= 0x01 << i;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.abm_set_pwm_frac.header.type = DMUB_CMD__ABM;
- cmd.abm_set_pwm_frac.header.sub_type = DMUB_CMD__ABM_SET_PWM_FRAC;
- cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm;
- cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
- cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.panel_mask = panel_mask;
- cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data);
-
- dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
- dc_dmub_srv_cmd_execute(dc->dmub_srv);
- dc_dmub_srv_wait_idle(dc->dmub_srv);
+ dmub_abm_init(abm, backlight);
}
-static void dmub_abm_init(struct abm *abm, uint32_t backlight)
+static unsigned int dmub_abm_get_current_backlight_ex(struct abm *abm)
{
- struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
-
- REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x3);
- REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x1);
- REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x3);
- REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x1);
- REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x1);
-
- REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
- ABM1_HG_NUM_OF_BINS_SEL, 0,
- ABM1_HG_VMAX_SEL, 1,
- ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
-
- REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
- ABM1_IPCSC_COEFF_SEL_R, 2,
- ABM1_IPCSC_COEFF_SEL_G, 4,
- ABM1_IPCSC_COEFF_SEL_B, 2);
+ return dmub_abm_get_current_backlight(abm);
+}
- REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
- BL1_PWM_CURRENT_ABM_LEVEL, backlight);
+static unsigned int dmub_abm_get_target_backlight_ex(struct abm *abm)
+{
+ return dmub_abm_get_target_backlight(abm);
+}
- REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
- BL1_PWM_TARGET_ABM_LEVEL, backlight);
+static bool dmub_abm_set_level_ex(struct abm *abm, uint32_t level)
+{
+ bool ret = false;
+ unsigned int feature_support, i;
+ uint8_t panel_mask0 = 0;
- REG_UPDATE(BL1_PWM_USER_LEVEL,
- BL1_PWM_USER_LEVEL, backlight);
+ for (i = 0; i < MAX_NUM_EDP; i++) {
+ feature_support = abm_feature_support(abm, i);
- REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
- ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
- ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
+ if (feature_support == ABM_LCD_SUPPORT)
+ panel_mask0 |= (0x01 << i);
+ }
- REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
- ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
- ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
- ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
+ if (panel_mask0)
+ ret = dmub_abm_set_level(abm, level, panel_mask0);
- dmub_abm_enable_fractional_pwm(abm->ctx);
+ return ret;
}
-static unsigned int dmub_abm_get_current_backlight(struct abm *abm)
+static bool dmub_abm_init_config_ex(struct abm *abm,
+ const char *src,
+ unsigned int bytes,
+ unsigned int inst)
{
- struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
- unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
+ unsigned int feature_support;
- /* return backlight in hardware format which is unsigned 17 bits, with
- * 1 bit integer and 16 bit fractional
- */
- return backlight;
-}
+ feature_support = abm_feature_support(abm, inst);
-static unsigned int dmub_abm_get_target_backlight(struct abm *abm)
-{
- struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
- unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL);
+ if (feature_support == ABM_LCD_SUPPORT)
+ dmub_abm_init_config(abm, src, bytes, inst);
- /* return backlight in hardware format which is unsigned 17 bits, with
- * 1 bit integer and 16 bit fractional
- */
- return backlight;
+ return true;
}
-static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
+static bool dmub_abm_set_pause_ex(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst)
{
- union dmub_rb_cmd cmd;
- struct dc_context *dc = abm->ctx;
- struct dc_link *edp_links[MAX_NUM_EDP];
- int i;
- int edp_num;
- uint8_t panel_mask = 0;
+ bool ret = false;
+ unsigned int feature_support;
- get_edp_links(dc->dc, edp_links, &edp_num);
-
- for (i = 0; i < edp_num; i++) {
- if (edp_links[i]->link_status.link_active)
- panel_mask |= (0x01 << i);
- }
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.abm_set_level.header.type = DMUB_CMD__ABM;
- cmd.abm_set_level.header.sub_type = DMUB_CMD__ABM_SET_LEVEL;
- cmd.abm_set_level.abm_set_level_data.level = level;
- cmd.abm_set_level.abm_set_level_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
- cmd.abm_set_level.abm_set_level_data.panel_mask = panel_mask;
- cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data);
+ feature_support = abm_feature_support(abm, panel_inst);
- dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
- dc_dmub_srv_cmd_execute(dc->dmub_srv);
- dc_dmub_srv_wait_idle(dc->dmub_srv);
+ if (feature_support == ABM_LCD_SUPPORT)
+ ret = dmub_abm_set_pause(abm, pause, panel_inst, stream_inst);
- return true;
+ return ret;
}
-static bool dmub_abm_init_config(struct abm *abm,
- const char *src,
- unsigned int bytes,
- unsigned int inst)
+static bool dmub_abm_set_pipe_ex(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst)
{
- union dmub_rb_cmd cmd;
- struct dc_context *dc = abm->ctx;
- uint8_t panel_mask = 0x01 << inst;
+ bool ret = false;
+ unsigned int feature_support;
- // TODO: Optimize by only reading back final 4 bytes
- dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
+ feature_support = abm_feature_support(abm, panel_inst);
- // Copy iramtable into cw7
- memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
+ if (feature_support == ABM_LCD_SUPPORT)
+ ret = dmub_abm_set_pipe(abm, otg_inst, option, panel_inst);
- memset(&cmd, 0, sizeof(cmd));
- // Fw will copy from cw7 to fw_state
- cmd.abm_init_config.header.type = DMUB_CMD__ABM;
- cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG;
- cmd.abm_init_config.abm_init_config_data.src.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
- cmd.abm_init_config.abm_init_config_data.bytes = bytes;
- cmd.abm_init_config.abm_init_config_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
- cmd.abm_init_config.abm_init_config_data.panel_mask = panel_mask;
+ return ret;
+}
- cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
+static bool dmub_abm_set_event_ex(struct abm *abm, unsigned int full_screen, unsigned int video_mode,
+ unsigned int hdr_mode, unsigned int panel_inst)
+{
+ bool ret = false;
+ unsigned int feature_support;
- dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
- dc_dmub_srv_cmd_execute(dc->dmub_srv);
- dc_dmub_srv_wait_idle(dc->dmub_srv);
+ feature_support = abm_feature_support(abm, panel_inst);
- return true;
+ return ret;
}
-static bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst)
+static bool dmub_abm_set_backlight_level_pwm_ex(struct abm *abm,
+ unsigned int backlight_pwm_u16_16,
+ unsigned int frame_ramp,
+ unsigned int controller_id,
+ unsigned int panel_inst)
{
- union dmub_rb_cmd cmd;
- struct dc_context *dc = abm->ctx;
- uint8_t panel_mask = 0x01 << panel_inst;
+ bool ret = false;
+ unsigned int feature_support;
- memset(&cmd, 0, sizeof(cmd));
- cmd.abm_pause.header.type = DMUB_CMD__ABM;
- cmd.abm_pause.header.sub_type = DMUB_CMD__ABM_PAUSE;
- cmd.abm_pause.abm_pause_data.enable = pause;
- cmd.abm_pause.abm_pause_data.panel_mask = panel_mask;
- cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_pause_data);
+ feature_support = abm_feature_support(abm, panel_inst);
- dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
- dc_dmub_srv_cmd_execute(dc->dmub_srv);
- dc_dmub_srv_wait_idle(dc->dmub_srv);
+ if (feature_support == ABM_LCD_SUPPORT)
+ ret = dmub_abm_set_backlight_level(abm, backlight_pwm_u16_16, frame_ramp, panel_inst);
- return true;
+ return ret;
}
static const struct abm_funcs abm_funcs = {
- .abm_init = dmub_abm_init,
- .set_abm_level = dmub_abm_set_level,
- .get_current_backlight = dmub_abm_get_current_backlight,
- .get_target_backlight = dmub_abm_get_target_backlight,
- .init_abm_config = dmub_abm_init_config,
- .set_abm_pause = dmub_abm_set_pause,
+ .abm_init = dmub_abm_init_ex,
+ .set_abm_level = dmub_abm_set_level_ex,
+ .get_current_backlight = dmub_abm_get_current_backlight_ex,
+ .get_target_backlight = dmub_abm_get_target_backlight_ex,
+ .init_abm_config = dmub_abm_init_config_ex,
+ .set_abm_pause = dmub_abm_set_pause_ex,
+ .set_pipe_ex = dmub_abm_set_pipe_ex,
+ .set_abm_event = dmub_abm_set_event_ex,
+ .set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm_ex,
};
static void dmub_abm_construct(
@@ -256,16 +195,19 @@ struct abm *dmub_abm_create(
const struct dce_abm_shift *abm_shift,
const struct dce_abm_mask *abm_mask)
{
- struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL);
+ if (ctx->dc->caps.dmcub_support) {
+ struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL);
- if (abm_dce == NULL) {
- BREAK_TO_DEBUGGER();
- return NULL;
- }
+ if (abm_dce == NULL) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
- dmub_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
+ dmub_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
- return &abm_dce->base;
+ return &abm_dce->base;
+ }
+ return NULL;
}
void dmub_abm_destroy(struct abm **abm)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
new file mode 100644
index 0000000000000..4055d271ac57f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dmub_abm.h"
+#include "dce_abm.h"
+#include "dc.h"
+#include "dc_dmub_srv.h"
+#include "dmub/dmub_srv.h"
+#include "core_types.h"
+#include "dm_services.h"
+#include "reg_helper.h"
+#include "fixed31_32.h"
+
+#ifdef _WIN32
+#include "atombios.h"
+#else
+#include "atom.h"
+#endif
+
+#define TO_DMUB_ABM(abm)\
+ container_of(abm, struct dce_abm, base)
+
+#define REG(reg) \
+ (dce_abm->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+ dce_abm->abm_shift->field_name, dce_abm->abm_mask->field_name
+
+#define CTX \
+ dce_abm->base.ctx
+
+#define DISABLE_ABM_IMMEDIATELY 255
+
+
+
+static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
+{
+ union dmub_rb_cmd cmd;
+ uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0;
+ uint32_t edp_id_count = dc->dc_edp_id_count;
+ int i;
+ uint8_t panel_mask = 0;
+
+ for (i = 0; i < edp_id_count; i++)
+ panel_mask |= 0x01 << i;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_set_pwm_frac.header.type = DMUB_CMD__ABM;
+ cmd.abm_set_pwm_frac.header.sub_type = DMUB_CMD__ABM_SET_PWM_FRAC;
+ cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm;
+ cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+ cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.panel_mask = panel_mask;
+ cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+
+void dmub_abm_init(struct abm *abm, uint32_t backlight)
+{
+ struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+
+ REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x3);
+ REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x1);
+ REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x3);
+ REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x1);
+ REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x1);
+
+ REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
+ ABM1_HG_NUM_OF_BINS_SEL, 0,
+ ABM1_HG_VMAX_SEL, 1,
+ ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
+
+ REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
+ ABM1_IPCSC_COEFF_SEL_R, 2,
+ ABM1_IPCSC_COEFF_SEL_G, 4,
+ ABM1_IPCSC_COEFF_SEL_B, 2);
+
+ REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
+ BL1_PWM_CURRENT_ABM_LEVEL, backlight);
+
+ REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
+ BL1_PWM_TARGET_ABM_LEVEL, backlight);
+
+ REG_UPDATE(BL1_PWM_USER_LEVEL,
+ BL1_PWM_USER_LEVEL, backlight);
+
+ REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
+ ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
+ ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
+
+ REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
+ ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
+ ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
+ ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
+
+ dmub_abm_enable_fractional_pwm(abm->ctx);
+}
+
+unsigned int dmub_abm_get_current_backlight(struct abm *abm)
+{
+ struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+ unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL);
+
+ /* return backlight in hardware format which is unsigned 17 bits, with
+ * 1 bit integer and 16 bit fractional
+ */
+ return backlight;
+}
+
+unsigned int dmub_abm_get_target_backlight(struct abm *abm)
+{
+ struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
+ unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL);
+
+ /* return backlight in hardware format which is unsigned 17 bits, with
+ * 1 bit integer and 16 bit fractional
+ */
+ return backlight;
+}
+
+bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_set_level.header.type = DMUB_CMD__ABM;
+ cmd.abm_set_level.header.sub_type = DMUB_CMD__ABM_SET_LEVEL;
+ cmd.abm_set_level.abm_set_level_data.level = level;
+ cmd.abm_set_level.abm_set_level_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+ cmd.abm_set_level.abm_set_level_data.panel_mask = panel_mask;
+ cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+ return true;
+}
+
+#ifndef TRIM_AMBIENT_GAMMA
+void dmub_abm_set_ambient_level(struct abm *abm, unsigned int ambient_lux, uint8_t panel_mask)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+
+ if (ambient_lux > 0xFFFF)
+ ambient_lux = 0xFFFF;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_set_ambient_level.header.type = DMUB_CMD__ABM;
+ cmd.abm_set_ambient_level.header.sub_type = DMUB_CMD__ABM_SET_AMBIENT_LEVEL;
+ cmd.abm_set_ambient_level.abm_set_ambient_level_data.ambient_lux = ambient_lux;
+ cmd.abm_set_ambient_level.abm_set_ambient_level_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+ cmd.abm_set_ambient_level.abm_set_ambient_level_data.panel_mask = panel_mask;
+ cmd.abm_set_ambient_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_ambient_level_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+#endif
+
+void dmub_abm_init_config(struct abm *abm,
+ const char *src,
+ unsigned int bytes,
+ unsigned int inst)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+ uint8_t panel_mask = 0x01 << inst;
+
+ // TODO: Optimize by only reading back final 4 bytes
+ dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
+
+ // Copy iramtable into cw7
+ memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
+
+ memset(&cmd, 0, sizeof(cmd));
+ // Fw will copy from cw7 to fw_state
+ cmd.abm_init_config.header.type = DMUB_CMD__ABM;
+ cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG;
+ cmd.abm_init_config.abm_init_config_data.src.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
+ cmd.abm_init_config.abm_init_config_data.bytes = bytes;
+ cmd.abm_init_config.abm_init_config_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+ cmd.abm_init_config.abm_init_config_data.panel_mask = panel_mask;
+
+ cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+}
+
+bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+ uint8_t panel_mask = 0x01 << panel_inst;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_pause.header.type = DMUB_CMD__ABM;
+ cmd.abm_pause.header.sub_type = DMUB_CMD__ABM_PAUSE;
+ cmd.abm_pause.abm_pause_data.enable = pause;
+ cmd.abm_pause.abm_pause_data.panel_mask = panel_mask;
+ cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_pause_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+ return true;
+}
+
+bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+ uint32_t ramping_boundary = 0xFFFF;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
+ cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE;
+ cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst;
+ cmd.abm_set_pipe.abm_set_pipe_data.set_pipe_option = option;
+ cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst;
+ cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
+ cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+ return true;
+}
+
+bool dmub_abm_set_backlight_level(struct abm *abm,
+ unsigned int backlight_pwm_u16_16,
+ unsigned int frame_ramp,
+ unsigned int panel_inst)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = abm->ctx;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.abm_set_backlight.header.type = DMUB_CMD__ABM;
+ cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT;
+ cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp;
+ cmd.abm_set_backlight.abm_set_backlight_data.backlight_user_level = backlight_pwm_u16_16;
+ cmd.abm_set_backlight.abm_set_backlight_data.version = DMUB_CMD_ABM_CONTROL_VERSION_1;
+ cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst);
+ cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+
+ return true;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.h
new file mode 100644
index 0000000000000..00b4e268768ef
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DMUB_ABM_LCD_H__
+#define __DMUB_ABM_LCD_H__
+
+#include "abm.h"
+
+void dmub_abm_init(struct abm *abm, uint32_t backlight);
+bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask);
+unsigned int dmub_abm_get_current_backlight(struct abm *abm);
+unsigned int dmub_abm_get_target_backlight(struct abm *abm);
+void dmub_abm_init_config(struct abm *abm,
+ const char *src,
+ unsigned int bytes,
+ unsigned int inst);
+
+bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst);
+bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst);
+bool dmub_abm_set_backlight_level(struct abm *abm,
+ unsigned int backlight_pwm_u16_16,
+ unsigned int frame_ramp,
+ unsigned int panel_inst);
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
index ecb4191b6e64f..db5cf9acafe6d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h
@@ -55,6 +55,12 @@ struct abm_funcs {
unsigned int bytes,
unsigned int inst);
bool (*set_abm_pause)(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst);
+ bool (*set_pipe_ex)(struct abm *abm,
+ unsigned int otg_inst,
+ unsigned int option,
+ unsigned int panel_inst);
+ bool (*set_abm_event)(struct abm *abm, unsigned int full_screen, unsigned int video_mode,
+ unsigned int hdr_mode, unsigned int panel_inst);
};
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0659/1887] drm/amd/display: Avoid overflow from uint32_t to uint8_t
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (657 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0658/1887] drm/amd/display: Refactor ABM feature Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0660/1887] spi: hisi-kunpeng: Convert to platform remove callback returning void Greg Kroah-Hartman
` (339 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Zaeem Mohamed,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit d6b54900c564e35989cf6813e4071504fa0a90e0 ]
[WHAT & HOW]
dmub_rb_cmd's ramping_boundary has size of uint8_t and it is assigned
0xFFFF. Fix it by changing it to uint8_t with value of 0xFF.
This fixes 2 INTEGER_OVERFLOW issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Acked-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 2 +-
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
index 4055d271ac57f..19a97da77df88 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
@@ -242,7 +242,7 @@ bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t option, uint
{
union dmub_rb_cmd cmd;
struct dc_context *dc = abm->ctx;
- uint32_t ramping_boundary = 0xFFFF;
+ uint8_t ramping_boundary = 0xFF;
memset(&cmd, 0, sizeof(cmd));
cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
index 5910cde0408d0..10c63c47097a5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
@@ -141,7 +141,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t optio
{
union dmub_rb_cmd cmd;
struct dc_context *dc = abm->ctx;
- uint32_t ramping_boundary = 0xFFFF;
+ uint8_t ramping_boundary = 0xFF;
memset(&cmd, 0, sizeof(cmd));
cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0660/1887] spi: hisi-kunpeng: Convert to platform remove callback returning void
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (658 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0659/1887] drm/amd/display: Avoid overflow from uint32_t to uint8_t Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0661/1887] spi: hisi-kunpeng: switch to use modern name Greg Kroah-Hartman
` (338 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit e77ccdfe0145211b5a20ab62950894aea881bbb3 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is (mostly) ignored
and this typically results in resource leaks. To improve here there is a
quest to make the remove callback return void. In the first step of this
quest all drivers are converted to .remove_new() which already returns
void.
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20230303172041.2103336-31-u.kleine-koenig@pengutronix.de
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 5127c42c77de ("spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-hisi-kunpeng.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index 06c8893243b7d..2cfc820c8adcc 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -531,15 +531,13 @@ static int hisi_spi_probe(struct platform_device *pdev)
return 0;
}
-static int hisi_spi_remove(struct platform_device *pdev)
+static void hisi_spi_remove(struct platform_device *pdev)
{
struct spi_controller *master = platform_get_drvdata(pdev);
struct hisi_spi *hs = spi_controller_get_devdata(master);
debugfs_remove_recursive(hs->debugfs);
spi_unregister_controller(master);
-
- return 0;
}
static const struct acpi_device_id hisi_spi_acpi_match[] = {
@@ -550,7 +548,7 @@ MODULE_DEVICE_TABLE(acpi, hisi_spi_acpi_match);
static struct platform_driver hisi_spi_driver = {
.probe = hisi_spi_probe,
- .remove = hisi_spi_remove,
+ .remove_new = hisi_spi_remove,
.driver = {
.name = "hisi-kunpeng-spi",
.acpi_match_table = hisi_spi_acpi_match,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0661/1887] spi: hisi-kunpeng: switch to use modern name
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (659 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0660/1887] spi: hisi-kunpeng: Convert to platform remove callback returning void Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0662/1887] spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware Greg Kroah-Hartman
` (337 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yang Yingliang, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <yangyingliang@huawei.com>
[ Upstream commit 9f5890466e93a7392c618e50de53cdd3a0dd1fd5 ]
Change legacy name master to modern name host.
No functional changed.
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Link: https://lore.kernel.org/r/20230728093221.3312026-21-yangyingliang@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 5127c42c77de ("spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-hisi-kunpeng.c | 84 +++++++++++++++++-----------------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index 2cfc820c8adcc..d5cb4bb709748 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -162,10 +162,10 @@ static int hisi_spi_debugfs_init(struct hisi_spi *hs)
{
char name[32];
- struct spi_controller *master;
+ struct spi_controller *host;
- master = container_of(hs->dev, struct spi_controller, dev);
- snprintf(name, 32, "hisi_spi%d", master->bus_num);
+ host = container_of(hs->dev, struct spi_controller, dev);
+ snprintf(name, 32, "hisi_spi%d", host->bus_num);
hs->debugfs = debugfs_create_dir(name, NULL);
if (!hs->debugfs)
return -ENOMEM;
@@ -299,18 +299,18 @@ static void __hisi_calc_div_reg(struct hisi_chip_data *chip)
chip->div_post = (chip->clk_div / chip->div_pre) - 1;
}
-static u32 hisi_calc_effective_speed(struct spi_controller *master,
+static u32 hisi_calc_effective_speed(struct spi_controller *host,
struct hisi_chip_data *chip, u32 speed_hz)
{
u32 effective_speed;
/* Note clock divider doesn't support odd numbers */
- chip->clk_div = DIV_ROUND_UP(master->max_speed_hz, speed_hz) + 1;
+ chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1;
chip->clk_div &= 0xfffe;
if (chip->clk_div > CLK_DIV_MAX)
chip->clk_div = CLK_DIV_MAX;
- effective_speed = master->max_speed_hz / chip->clk_div;
+ effective_speed = host->max_speed_hz / chip->clk_div;
if (chip->speed_hz != effective_speed) {
__hisi_calc_div_reg(chip);
chip->speed_hz = effective_speed;
@@ -344,20 +344,20 @@ static void hisi_spi_hw_init(struct hisi_spi *hs)
static irqreturn_t hisi_spi_irq(int irq, void *dev_id)
{
- struct spi_controller *master = dev_id;
- struct hisi_spi *hs = spi_controller_get_devdata(master);
+ struct spi_controller *host = dev_id;
+ struct hisi_spi *hs = spi_controller_get_devdata(host);
u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK;
if (!irq_status)
return IRQ_NONE;
- if (!master->cur_msg)
+ if (!host->cur_msg)
return IRQ_HANDLED;
/* Error handling */
if (irq_status & ISR_RXOF) {
dev_err(hs->dev, "interrupt_transfer: fifo overflow\n");
- master->cur_msg->status = -EIO;
+ host->cur_msg->status = -EIO;
goto finalize_transfer;
}
@@ -377,20 +377,20 @@ static irqreturn_t hisi_spi_irq(int irq, void *dev_id)
finalize_transfer:
hisi_spi_disable(hs);
- spi_finalize_current_transfer(master);
+ spi_finalize_current_transfer(host);
return IRQ_HANDLED;
}
-static int hisi_spi_transfer_one(struct spi_controller *master,
+static int hisi_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi, struct spi_transfer *transfer)
{
- struct hisi_spi *hs = spi_controller_get_devdata(master);
+ struct hisi_spi *hs = spi_controller_get_devdata(host);
struct hisi_chip_data *chip = spi_get_ctldata(spi);
u32 cr = chip->cr;
/* Update per transfer options for speed and bpw */
transfer->effective_speed_hz =
- hisi_calc_effective_speed(master, chip, transfer->speed_hz);
+ hisi_calc_effective_speed(host, chip, transfer->speed_hz);
cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre);
cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post);
cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1);
@@ -417,10 +417,10 @@ static int hisi_spi_transfer_one(struct spi_controller *master,
return 1;
}
-static void hisi_spi_handle_err(struct spi_controller *master,
+static void hisi_spi_handle_err(struct spi_controller *host,
struct spi_message *msg)
{
- struct hisi_spi *hs = spi_controller_get_devdata(master);
+ struct hisi_spi *hs = spi_controller_get_devdata(host);
hisi_spi_disable(hs);
@@ -460,7 +460,7 @@ static void hisi_spi_cleanup(struct spi_device *spi)
static int hisi_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct spi_controller *master;
+ struct spi_controller *host;
struct hisi_spi *hs;
int ret, irq;
@@ -468,13 +468,13 @@ static int hisi_spi_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- master = devm_spi_alloc_master(dev, sizeof(*hs));
- if (!master)
+ host = devm_spi_alloc_host(dev, sizeof(*hs));
+ if (!host)
return -ENOMEM;
- platform_set_drvdata(pdev, master);
+ platform_set_drvdata(pdev, host);
- hs = spi_controller_get_devdata(master);
+ hs = spi_controller_get_devdata(host);
hs->dev = dev;
hs->irq = irq;
@@ -482,9 +482,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
if (IS_ERR(hs->regs))
return PTR_ERR(hs->regs);
- /* Specify maximum SPI clocking speed (master only) by firmware */
+ /* Specify maximum SPI clocking speed (host only) by firmware */
ret = device_property_read_u32(dev, "spi-max-frequency",
- &master->max_speed_hz);
+ &host->max_speed_hz);
if (ret) {
dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n",
ret);
@@ -492,32 +492,32 @@ static int hisi_spi_probe(struct platform_device *pdev)
}
ret = device_property_read_u16(dev, "num-cs",
- &master->num_chipselect);
+ &host->num_chipselect);
if (ret)
- master->num_chipselect = DEFAULT_NUM_CS;
-
- master->use_gpio_descriptors = true;
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- master->bus_num = pdev->id;
- master->setup = hisi_spi_setup;
- master->cleanup = hisi_spi_cleanup;
- master->transfer_one = hisi_spi_transfer_one;
- master->handle_err = hisi_spi_handle_err;
- master->dev.fwnode = dev->fwnode;
+ host->num_chipselect = DEFAULT_NUM_CS;
+
+ host->use_gpio_descriptors = true;
+ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+ host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+ host->bus_num = pdev->id;
+ host->setup = hisi_spi_setup;
+ host->cleanup = hisi_spi_cleanup;
+ host->transfer_one = hisi_spi_transfer_one;
+ host->handle_err = hisi_spi_handle_err;
+ host->dev.fwnode = dev->fwnode;
hisi_spi_hw_init(hs);
ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev),
- master);
+ host);
if (ret < 0) {
dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret);
return ret;
}
- ret = spi_register_controller(master);
+ ret = spi_register_controller(host);
if (ret) {
- dev_err(dev, "failed to register spi master, ret=%d\n", ret);
+ dev_err(dev, "failed to register spi host, ret=%d\n", ret);
return ret;
}
@@ -526,18 +526,18 @@ static int hisi_spi_probe(struct platform_device *pdev)
dev_info(dev, "hw version:0x%x max-freq:%u kHz\n",
readl(hs->regs + HISI_SPI_VERSION),
- master->max_speed_hz / 1000);
+ host->max_speed_hz / 1000);
return 0;
}
static void hisi_spi_remove(struct platform_device *pdev)
{
- struct spi_controller *master = platform_get_drvdata(pdev);
- struct hisi_spi *hs = spi_controller_get_devdata(master);
+ struct spi_controller *host = platform_get_drvdata(pdev);
+ struct hisi_spi *hs = spi_controller_get_devdata(host);
debugfs_remove_recursive(hs->debugfs);
- spi_unregister_controller(master);
+ spi_unregister_controller(host);
}
static const struct acpi_device_id hisi_spi_acpi_match[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0662/1887] spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (660 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0661/1887] spi: hisi-kunpeng: switch to use modern name Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:45 ` [PATCH 6.1 0663/1887] media: mediatek: vcodec: Fix H264 stateless decoder smatch warning Greg Kroah-Hartman
` (336 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Devyn Liu, Jay Fang, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devyn Liu <liudingyuan@huawei.com>
[ Upstream commit 5127c42c77de18651aa9e8e0a3ced190103b449c ]
If the value of max_speed_hz is 0, it may cause a division by zero
error in hisi_calc_effective_speed().
The value of max_speed_hz is provided by firmware.
Firmware is generally considered as a trusted domain. However, as
division by zero errors can cause system failure, for defense measure,
the value of max_speed is validated here. So 0 is regarded as invalid
and an error code is returned.
Signed-off-by: Devyn Liu <liudingyuan@huawei.com>
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
Link: https://patch.msgid.link/20240730032040.3156393-3-liudingyuan@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-hisi-kunpeng.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index d5cb4bb709748..562e23d66d13d 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -491,6 +491,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
return -EINVAL;
}
+ if (host->max_speed_hz == 0)
+ return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n");
+
ret = device_property_read_u16(dev, "num-cs",
&host->num_chipselect);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0663/1887] media: mediatek: vcodec: Fix H264 stateless decoder smatch warning
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (661 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0662/1887] spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware Greg Kroah-Hartman
@ 2026-10-28 16:45 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0664/1887] bpf: Prevent tailcall infinite loop caused by freplace Greg Kroah-Hartman
` (335 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yunfei Dong,
AngeloGioacchino Del Regno, Sebastian Fricke, Hans Verkuil,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunfei Dong <yunfei.dong@mediatek.com>
[ Upstream commit 7878d3a385efab560dce793b595447867fb163f2 ]
Fix a smatch static checker warning on vdec_h264_req_if.c.
Which leads to a kernel crash when fb is NULL.
Fixes: 06fa5f757dc5 ("media: mtk-vcodec: vdec: support stateless H.264 decoding")
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../platform/mediatek/vcodec/vdec/vdec_h264_req_if.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
index 4bc05ab5afea0..d6fa1e249dc70 100644
--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
@@ -352,11 +352,16 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
return vpu_dec_reset(vpu);
fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+ if (!fb) {
+ mtk_vcodec_err(inst, "fb buffer is NULL");
+ return -ENOMEM;
+ }
+
src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
- y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
- c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+ y_fb_dma = fb->base_y.dma_addr;
+ c_fb_dma = fb->base_c.dma_addr;
mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
inst->num_nalu, y_fb_dma, c_fb_dma, fb);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0664/1887] bpf: Prevent tailcall infinite loop caused by freplace
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (662 preceding siblings ...)
2026-10-28 16:45 ` [PATCH 6.1 0663/1887] media: mediatek: vcodec: Fix H264 stateless decoder smatch warning Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0665/1887] nvme-rdma: unquiesce admin_q before destroy it Greg Kroah-Hartman
` (334 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eduard Zingerman, Leon Hwang,
Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Hwang <leon.hwang@linux.dev>
[ Upstream commit d6083f040d5d8f8d748462c77e90547097df936e ]
There is a potential infinite loop issue that can occur when using a
combination of tail calls and freplace.
In an upcoming selftest, the attach target for entry_freplace of
tailcall_freplace.c is subprog_tc of tc_bpf2bpf.c, while the tail call in
entry_freplace leads to entry_tc. This results in an infinite loop:
entry_tc -> subprog_tc -> entry_freplace --tailcall-> entry_tc.
The problem arises because the tail_call_cnt in entry_freplace resets to
zero each time entry_freplace is executed, causing the tail call mechanism
to never terminate, eventually leading to a kernel panic.
To fix this issue, the solution is twofold:
1. Prevent updating a program extended by an freplace program to a
prog_array map.
2. Prevent extending a program that is already part of a prog_array map
with an freplace program.
This ensures that:
* If a program or its subprogram has been extended by an freplace program,
it can no longer be updated to a prog_array map.
* If a program has been added to a prog_array map, neither it nor its
subprograms can be extended by an freplace program.
Moreover, an extension program should not be tailcalled. As such, return
-EINVAL if the program has a type of BPF_PROG_TYPE_EXT when adding it to a
prog_array map.
Additionally, fix a minor code style issue by replacing eight spaces with a
tab for proper formatting.
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
Link: https://lore.kernel.org/r/20241015150207.70264-2-leon.hwang@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf.h | 17 +++++++++++----
kernel/bpf/arraymap.c | 26 +++++++++++++++++++++--
kernel/bpf/core.c | 1 +
kernel/bpf/syscall.c | 7 +++---
kernel/bpf/trampoline.c | 47 ++++++++++++++++++++++++++++++++++-------
5 files changed, 81 insertions(+), 17 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 085bb4e420ef3..4f09079ecaebd 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1014,8 +1014,12 @@ static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
}
#ifdef CONFIG_BPF_JIT
-int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
-int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
+int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog);
+int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog);
struct bpf_trampoline *bpf_trampoline_get(u64 key,
struct bpf_attach_target_info *tgt_info);
void bpf_trampoline_put(struct bpf_trampoline *tr);
@@ -1096,12 +1100,14 @@ void bpf_jit_uncharge_modmem(u32 size);
bool bpf_prog_has_trampoline(const struct bpf_prog *prog);
#else
static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
- struct bpf_trampoline *tr)
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
return -ENOTSUPP;
}
static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
- struct bpf_trampoline *tr)
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
return -ENOTSUPP;
}
@@ -1198,6 +1204,9 @@ struct bpf_prog_aux {
bool sleepable;
bool tail_call_reachable;
bool xdp_has_frags;
+ bool is_extended; /* true if extended by freplace program */
+ u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
+ struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
const struct btf_type *attach_func_proto;
/* function name for valid attach_btf_id */
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 50b9bf57a4e3e..220df952aeabe 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -889,22 +889,44 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map,
struct file *map_file, int fd)
{
struct bpf_prog *prog = bpf_prog_get(fd);
+ bool is_extended;
if (IS_ERR(prog))
return prog;
- if (!bpf_prog_map_compatible(map, prog)) {
+ if (prog->type == BPF_PROG_TYPE_EXT ||
+ !bpf_prog_map_compatible(map, prog)) {
bpf_prog_put(prog);
return ERR_PTR(-EINVAL);
}
+ mutex_lock(&prog->aux->ext_mutex);
+ is_extended = prog->aux->is_extended;
+ if (!is_extended)
+ prog->aux->prog_array_member_cnt++;
+ mutex_unlock(&prog->aux->ext_mutex);
+ if (is_extended) {
+ /* Extended prog can not be tail callee. It's to prevent a
+ * potential infinite loop like:
+ * tail callee prog entry -> tail callee prog subprog ->
+ * freplace prog entry --tailcall-> tail callee prog entry.
+ */
+ bpf_prog_put(prog);
+ return ERR_PTR(-EBUSY);
+ }
+
return prog;
}
static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer)
{
+ struct bpf_prog *prog = ptr;
+
+ mutex_lock(&prog->aux->ext_mutex);
+ prog->aux->prog_array_member_cnt--;
+ mutex_unlock(&prog->aux->ext_mutex);
/* bpf_prog is freed after one RCU or tasks trace grace period */
- bpf_prog_put(ptr);
+ bpf_prog_put(prog);
}
static u32 prog_fd_array_sys_lookup_elem(void *ptr)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 4ea21434bf78e..a9e7b17af4808 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -117,6 +117,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode);
mutex_init(&fp->aux->used_maps_mutex);
+ mutex_init(&fp->aux->ext_mutex);
mutex_init(&fp->aux->dst_mutex);
return fp;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index e997f7594c975..e32d9b9de0dcb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2980,7 +2980,8 @@ static void bpf_tracing_link_release(struct bpf_link *link)
container_of(link, struct bpf_tracing_link, link.link);
WARN_ON_ONCE(bpf_trampoline_unlink_prog(&tr_link->link,
- tr_link->trampoline));
+ tr_link->trampoline,
+ tr_link->tgt_prog));
bpf_trampoline_put(tr_link->trampoline);
@@ -3108,7 +3109,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
* in prog->aux
*
* - if prog->aux->dst_trampoline is NULL, the program has already been
- * attached to a target and its initial target was cleared (below)
+ * attached to a target and its initial target was cleared (below)
*
* - if tgt_prog != NULL, the caller specified tgt_prog_fd +
* target_btf_id using the link_create API.
@@ -3178,7 +3179,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
if (err)
goto out_unlock;
- err = bpf_trampoline_link_prog(&link->link, tr);
+ err = bpf_trampoline_link_prog(&link->link, tr, tgt_prog);
if (err) {
bpf_link_cleanup(&link_primer);
link = NULL;
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 17763af54179b..930914f628c7a 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -539,7 +539,27 @@ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
}
}
-static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+static int bpf_freplace_check_tgt_prog(struct bpf_prog *tgt_prog)
+{
+ struct bpf_prog_aux *aux = tgt_prog->aux;
+
+ guard(mutex)(&aux->ext_mutex);
+ if (aux->prog_array_member_cnt)
+ /* Program extensions can not extend target prog when the target
+ * prog has been updated to any prog_array map as tail callee.
+ * It's to prevent a potential infinite loop like:
+ * tgt prog entry -> tgt prog subprog -> freplace prog entry
+ * --tailcall-> tgt prog entry.
+ */
+ return -EBUSY;
+
+ aux->is_extended = true;
+ return 0;
+}
+
+static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
enum bpf_tramp_prog_type kind;
struct bpf_tramp_link *link_exiting;
@@ -560,6 +580,9 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_tr
/* Cannot attach extension if fentry/fexit are in use. */
if (cnt)
return -EBUSY;
+ err = bpf_freplace_check_tgt_prog(tgt_prog);
+ if (err)
+ return err;
tr->extension_prog = link->link.prog;
return bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP, NULL,
link->link.prog->bpf_func);
@@ -586,17 +609,21 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_tr
return err;
}
-int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
int err;
mutex_lock(&tr->mutex);
- err = __bpf_trampoline_link_prog(link, tr);
+ err = __bpf_trampoline_link_prog(link, tr, tgt_prog);
mutex_unlock(&tr->mutex);
return err;
}
-static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
enum bpf_tramp_prog_type kind;
int err;
@@ -607,6 +634,8 @@ static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_
err = bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP,
tr->extension_prog->bpf_func, NULL);
tr->extension_prog = NULL;
+ guard(mutex)(&tgt_prog->aux->ext_mutex);
+ tgt_prog->aux->is_extended = false;
return err;
}
hlist_del_init(&link->tramp_hlist);
@@ -615,12 +644,14 @@ static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_
}
/* bpf_trampoline_unlink_prog() should never fail. */
-int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr,
+ struct bpf_prog *tgt_prog)
{
int err;
mutex_lock(&tr->mutex);
- err = __bpf_trampoline_unlink_prog(link, tr);
+ err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog);
mutex_unlock(&tr->mutex);
return err;
}
@@ -635,7 +666,7 @@ static void bpf_shim_tramp_link_release(struct bpf_link *link)
if (!shim_link->trampoline)
return;
- WARN_ON_ONCE(bpf_trampoline_unlink_prog(&shim_link->link, shim_link->trampoline));
+ WARN_ON_ONCE(bpf_trampoline_unlink_prog(&shim_link->link, shim_link->trampoline, NULL));
bpf_trampoline_put(shim_link->trampoline);
}
@@ -747,7 +778,7 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
goto err;
}
- err = __bpf_trampoline_link_prog(&shim_link->link, tr);
+ err = __bpf_trampoline_link_prog(&shim_link->link, tr, NULL);
if (err)
goto err;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0665/1887] nvme-rdma: unquiesce admin_q before destroy it
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (663 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0664/1887] bpf: Prevent tailcall infinite loop caused by freplace Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0666/1887] drm/amd/display: Check null pointer before try to access it Greg Kroah-Hartman
` (333 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yingfu.zhou, Chunguang.xu, Yue.zhao,
Christoph Hellwig, Hannes Reinecke, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunguang.xu <chunguang.xu@shopee.com>
[ Upstream commit 5858b687559809f05393af745cbadf06dee61295 ]
Kernel will hang on destroy admin_q while we create ctrl failed, such
as following calltrace:
PID: 23644 TASK: ff2d52b40f439fc0 CPU: 2 COMMAND: "nvme"
#0 [ff61d23de260fb78] __schedule at ffffffff8323bc15
#1 [ff61d23de260fc08] schedule at ffffffff8323c014
#2 [ff61d23de260fc28] blk_mq_freeze_queue_wait at ffffffff82a3dba1
#3 [ff61d23de260fc78] blk_freeze_queue at ffffffff82a4113a
#4 [ff61d23de260fc90] blk_cleanup_queue at ffffffff82a33006
#5 [ff61d23de260fcb0] nvme_rdma_destroy_admin_queue at ffffffffc12686ce
#6 [ff61d23de260fcc8] nvme_rdma_setup_ctrl at ffffffffc1268ced
#7 [ff61d23de260fd28] nvme_rdma_create_ctrl at ffffffffc126919b
#8 [ff61d23de260fd68] nvmf_dev_write at ffffffffc024f362
#9 [ff61d23de260fe38] vfs_write at ffffffff827d5f25
RIP: 00007fda7891d574 RSP: 00007ffe2ef06958 RFLAGS: 00000202
RAX: ffffffffffffffda RBX: 000055e8122a4d90 RCX: 00007fda7891d574
RDX: 000000000000012b RSI: 000055e8122a4d90 RDI: 0000000000000004
RBP: 00007ffe2ef079c0 R8: 000000000000012b R9: 000055e8122a4d90
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000004
R13: 000055e8122923c0 R14: 000000000000012b R15: 00007fda78a54500
ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b
This due to we have quiesced admi_q before cancel requests, but forgot
to unquiesce before destroy it, as a result we fail to drain the
pending requests, and hang on blk_mq_freeze_queue_wait() forever. Here
try to reuse nvme_rdma_teardown_admin_queue() to fix this issue and
simplify the code.
Fixes: 958dc1d32c80 ("nvme-rdma: add clean action for failed reconnection")
Reported-by: Yingfu.zhou <yingfu.zhou@shopee.com>
Signed-off-by: Chunguang.xu <chunguang.xu@shopee.com>
Signed-off-by: Yue.zhao <yue.zhao@shopee.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/rdma.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index ac76f1ac17090..77a4727d503d6 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1120,13 +1120,7 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new)
nvme_rdma_free_io_queues(ctrl);
}
destroy_admin:
- nvme_stop_admin_queue(&ctrl->ctrl);
- blk_sync_queue(ctrl->ctrl.admin_q);
- nvme_rdma_stop_queue(&ctrl->queues[0]);
- nvme_cancel_admin_tagset(&ctrl->ctrl);
- if (new)
- nvme_remove_admin_tag_set(&ctrl->ctrl);
- nvme_rdma_destroy_admin_queue(ctrl);
+ nvme_rdma_teardown_admin_queue(ctrl, new);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0666/1887] drm/amd/display: Check null pointer before try to access it
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (664 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0665/1887] nvme-rdma: unquiesce admin_q before destroy it Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0667/1887] drm/amd/display: Add null check for pipe_ctx->plane_state in dcn20_program_pipe Greg Kroah-Hartman
` (332 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Hung, Rodrigo Siqueira,
Tom Chung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
[ Upstream commit 1b686053c06ffb9f4524b288110cf2a831ff7a25 ]
[why & how]
Change the order of the pipe_ctx->plane_state check to ensure that
plane_state is not null before accessing it.
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index d252d10c81347..d1f49232efa87 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1696,13 +1696,13 @@ static void dcn20_program_pipe(
if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
- if (pipe_ctx->update_flags.bits.enable
- || pipe_ctx->plane_state->update_flags.bits.hdr_mult)
+ if ((pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult) ||
+ pipe_ctx->update_flags.bits.enable)
hws->funcs.set_hdr_multiplier(pipe_ctx);
- if (pipe_ctx->update_flags.bits.enable ||
- pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
- pipe_ctx->plane_state->update_flags.bits.gamma_change)
+ if ((pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change) ||
+ (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.gamma_change) ||
+ pipe_ctx->update_flags.bits.enable)
hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
/* dcn10_translate_regamma_to_hw_format takes 750us to finish
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0667/1887] drm/amd/display: Add null check for pipe_ctx->plane_state in dcn20_program_pipe
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (665 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0666/1887] drm/amd/display: Check null pointer before try to access it Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0668/1887] drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer Greg Kroah-Hartman
` (331 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Chung, Rodrigo Siqueira,
Roman Li, Alex Hung, Aurabindo Pillai, Harry Wentland,
Hamza Mahfooz, Srinivasan Shanmugam, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit 8e4ed3cf1642df0c4456443d865cff61a9598aa8 ]
This commit addresses a null pointer dereference issue in the
`dcn20_program_pipe` function. The issue could occur when
`pipe_ctx->plane_state` is null.
The fix adds a check to ensure `pipe_ctx->plane_state` is not null
before accessing. This prevents a null pointer dereference.
Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn20/dcn20_hwseq.c:1925 dcn20_program_pipe() error: we previously assumed 'pipe_ctx->plane_state' could be null (see line 1877)
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index d1f49232efa87..d0422e1c14fab 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1693,7 +1693,9 @@ static void dcn20_program_pipe(
dc->res_pool->hubbub->funcs->program_det_size(
dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->det_buffer_size_kb);
- if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
+ if (pipe_ctx->update_flags.raw ||
+ (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) ||
+ pipe_ctx->stream->update_flags.raw)
dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
if ((pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0668/1887] drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (666 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0667/1887] drm/amd/display: Add null check for pipe_ctx->plane_state in dcn20_program_pipe Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0669/1887] drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer Greg Kroah-Hartman
` (330 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Chung, Rodrigo Siqueira,
Roman Li, Alex Hung, Aurabindo Pillai, Harry Wentland,
Hamza Mahfooz, Srinivasan Shanmugam, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit ac2140449184a26eac99585b7f69814bd3ba8f2d ]
This commit addresses a potential null pointer dereference issue in the
`dcn32_acquire_idle_pipe_for_head_pipe_in_layer` function. The issue
could occur when `head_pipe` is null.
The fix adds a check to ensure `head_pipe` is not null before asserting
it. If `head_pipe` is null, the function returns NULL to prevent a
potential null pointer dereference.
Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn32/dcn32_resource.c:2690 dcn32_acquire_idle_pipe_for_head_pipe_in_layer() error: we previously assumed 'head_pipe' could be null (see line 2681)
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index 1b1534ffee9f1..591c3166a4687 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -2563,8 +2563,10 @@ struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(
struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;
int head_index;
- if (!head_pipe)
+ if (!head_pipe) {
ASSERT(0);
+ return NULL;
+ }
/*
* Modified from dcn20_acquire_idle_pipe_for_layer
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0669/1887] drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (667 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0668/1887] drm/amd/display: Add null check for head_pipe in dcn32_acquire_idle_pipe_for_head_pipe_in_layer Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0670/1887] drm/amd/display: Check null pointers before multiple uses Greg Kroah-Hartman
` (329 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Chung, Rodrigo Siqueira,
Roman Li, Alex Hung, Aurabindo Pillai, Harry Wentland,
Hamza Mahfooz, Srinivasan Shanmugam, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit f22f4754aaa47d8c59f166ba3042182859e5dff7 ]
This commit addresses a potential null pointer dereference issue in the
`dcn201_acquire_free_pipe_for_layer` function. The issue could occur
when `head_pipe` is null.
The fix adds a check to ensure `head_pipe` is not null before asserting
it. If `head_pipe` is null, the function returns NULL to prevent a
potential null pointer dereference.
Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn201/dcn201_resource.c:1016 dcn201_acquire_free_pipe_for_layer() error: we previously assumed 'head_pipe' could be null (see line 1010)
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
index 407d995bfa99b..fee527977c375 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
@@ -1009,8 +1009,10 @@ static struct pipe_ctx *dcn201_acquire_idle_pipe_for_layer(
struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe);
- if (!head_pipe)
+ if (!head_pipe) {
ASSERT(0);
+ return NULL;
+ }
if (!idle_pipe)
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0670/1887] drm/amd/display: Check null pointers before multiple uses
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (668 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0669/1887] drm/amd/display: Add null check for head_pipe in dcn201_acquire_free_pipe_for_layer Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0671/1887] drm/amd/display: Check null pointers before used Greg Kroah-Hartman
` (328 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Jerry Zuo,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit fdd5ecbbff751c3b9061d8ebb08e5c96119915b4 ]
[WHAT & HOW]
Poniters, such as stream_enc and dc->bw_vbios, are null checked previously
in the same function, so Coverity warns "implies that stream_enc and
dc->bw_vbios might be null". They are used multiple times in the
subsequent code and need to be checked.
This fixes 10 FORWARD_NULL issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 5 ++++-
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | 5 ++++-
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 +++
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 3 +++
drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c | 5 ++++-
5 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 717e36172a718..f87c6174b7040 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -6187,8 +6187,11 @@ bool dc_link_dp_set_test_pattern(
break;
}
+ if (!pipe_ctx->stream)
+ return false;
+
if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
- if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
+ if (should_use_dmub_lock(pipe_ctx->stream->link)) {
union dmub_hw_lock_flags hw_locks = { 0 };
struct dmub_hw_lock_inst_flags inst_flags = { 0 };
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index 19d7cfa53211b..1f1f66d857698 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -1065,7 +1065,10 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
struct dm_pp_clock_levels clks = {0};
int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
- if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
+ if (!dc->bw_vbios)
+ return;
+
+ if (dc->bw_vbios->memory_type == bw_def_hbm)
memory_type_multiplier = MEMORY_TYPE_HBM;
/*do system clock TODO PPLIB: after PPLIB implement,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index d0422e1c14fab..a554867ee1a93 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2139,6 +2139,9 @@ bool dcn20_wait_for_blank_complete(
{
int counter;
+ if (!opp)
+ return false;
+
for (counter = 0; counter < 1000; counter++) {
if (opp->funcs->dpg_is_blanked(opp))
break;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index 591c3166a4687..9f5425e6474fb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -1664,6 +1664,9 @@ static void dcn32_enable_phantom_plane(struct dc *dc,
else
phantom_plane = dc_create_plane_state(dc);
+ if (!phantom_plane)
+ break;
+
memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
sizeof(phantom_plane->scaling_quality));
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
index 4227adbc646a8..5ba7749ca52bb 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
@@ -56,7 +56,10 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
- if (stream_enc && stream_enc->funcs->disable_fifo)
+ if (!stream_enc)
+ return;
+
+ if (stream_enc->funcs->disable_fifo)
stream_enc->funcs->disable_fifo(stream_enc);
link_enc->funcs->connect_dig_be_to_fe(
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0671/1887] drm/amd/display: Check null pointers before used
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (669 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0670/1887] drm/amd/display: Check null pointers before multiple uses Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0672/1887] drm/amd/display: Check null pointers before using them Greg Kroah-Hartman
` (327 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Jerry Zuo,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit be1fb44389ca3038ad2430dac4234669bc177ee3 ]
[WHAT & HOW]
Poniters, such as dc->clk_mgr, are null checked previously in the same
function, so Coverity warns "implies that "dc->clk_mgr" might be null".
As a result, these pointers need to be checked when used again.
This fixes 10 FORWARD_NULL issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 2 +-
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +-
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 5 +++--
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 3 ++-
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 ++--
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 3 ++-
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 4 ++--
7 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
index bce53ab36f3e5..d50b9440210e4 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -218,7 +218,7 @@ void dce11_pplib_apply_display_requirements(
* , then change minimum memory clock based on real-time bandwidth
* limitation.
*/
- if ((dc->ctx->asic_id.chip_family == FAMILY_AI) &&
+ if (dc->bw_vbios && (dc->ctx->asic_id.chip_family == FAMILY_AI) &&
ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) {
pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz,
(uint32_t) div64_s64(
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index f87c6174b7040..fa0ae49fa22b0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -3330,7 +3330,7 @@ bool dp_verify_link_cap_with_retries(
memset(&link->verified_link_cap, 0,
sizeof(struct dc_link_settings));
- if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
+ if (link->link_enc && (!dc_link_detect_sink(link, &type) || type == dc_connection_none)) {
link->verified_link_cap = fail_safe_link_settings;
break;
} else if (dp_verify_link_cap(link, known_limit_link_setting,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index c542d2ab9160e..d2e71bf6b8f52 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -963,7 +963,7 @@ void dce110_edp_backlight_control(
{
struct dc_context *ctx = link->ctx;
struct bp_transmitter_control cntl = { 0 };
- uint8_t panel_instance;
+ uint8_t panel_instance = 0;
unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
unsigned int post_T7_delay = OLED_POST_T7_DELAY;
@@ -1016,7 +1016,8 @@ void dce110_edp_backlight_control(
*/
/* dc_service_sleep_in_milliseconds(50); */
/*edp 1.2*/
- panel_instance = link->panel_cntl->inst;
+ if (link->panel_cntl)
+ panel_instance = link->panel_cntl->inst;
if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
if (!link->dc->config.edp_no_power_sequencing)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index a142a00bc4326..3bedc96714ceb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -749,7 +749,8 @@ bool hubp1_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
- if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+ if (hubp &&
+ earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index b120aa67d26c1..e2e8823f1371f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1490,7 +1490,7 @@ void dcn10_init_hw(struct dc *dc)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
/* Align bw context with hw config when system resume. */
- if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
+ if (dc->clk_mgr && dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
}
@@ -1630,7 +1630,7 @@ void dcn10_init_hw(struct dc *dc)
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index aa252dc263267..4040ec51ac578 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -925,7 +925,8 @@ bool hubp2_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
- if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+ if (hubp &&
+ earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index d4ee533deff32..2ef1c227f1051 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -281,10 +281,10 @@ void dcn31_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
- if (dc->clk_mgr->funcs->notify_wm_ranges)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
- if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0672/1887] drm/amd/display: Check null pointers before using them
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (670 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0671/1887] drm/amd/display: Check null pointers before used Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0673/1887] drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags Greg Kroah-Hartman
` (326 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Jerry Zuo,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit 1ff12bcd7deaeed25efb5120433c6a45dd5504a8 ]
[WHAT & HOW]
These pointers are null checked previously in the same function,
indicating they might be null as reported by Coverity. As a result,
they need to be checked when used again.
This fixes 3 FORWARD_NULL issue reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 53ec5f3a8e6f3..14f2cfcba5f65 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8628,9 +8628,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption);
- hdcp_update_display(
- adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
- new_con_state->hdcp_content_type, enable_encryption);
+ if (aconnector->dc_link)
+ hdcp_update_display(
+ adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
+ new_con_state->hdcp_content_type, enable_encryption);
}
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0673/1887] drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (671 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0672/1887] drm/amd/display: Check null pointers before using them Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0674/1887] l2tp: prevent possible tunnel refcount underflow Greg Kroah-Hartman
` (325 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Siqueira, Jerry Zuo,
Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit 5559598742fb4538e4c51c48ef70563c49c2af23 ]
[WHAT & HOW]
"dcn20_validate_apply_pipe_split_flags" dereferences merge, and thus it
cannot be a null pointer. Let's pass a valid pointer to avoid null
dereference.
This fixes 2 FORWARD_NULL issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 3 ++-
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 2a567c4fd80b6..dbfb9552b52c0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2021,6 +2021,7 @@ bool dcn20_fast_validate_bw(
{
bool out = false;
int split[MAX_PIPES] = { 0 };
+ bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
ASSERT(pipes);
@@ -2045,7 +2046,7 @@ bool dcn20_fast_validate_bw(
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
/*initialize pipe_just_split_from to invalid idx*/
for (i = 0; i < MAX_PIPES; i++)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index dd71ea2568e2b..61e72ccd4a67d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -818,6 +818,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
{
bool out = false;
int split[MAX_PIPES] = { 0 };
+ bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
ASSERT(pipes);
@@ -860,7 +861,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
goto validate_fail;
}
- vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+ vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0674/1887] l2tp: prevent possible tunnel refcount underflow
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (672 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0673/1887] drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0675/1887] net/ncsi: Disable the ncsi work before freeing the associated structure Greg Kroah-Hartman
` (324 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Chapman, Tom Parkin,
David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Chapman <jchapman@katalix.com>
[ Upstream commit 24256415d18695b46da06c93135f5b51c548b950 ]
When a session is created, it sets a backpointer to its tunnel. When
the session refcount drops to 0, l2tp_session_free drops the tunnel
refcount if session->tunnel is non-NULL. However, session->tunnel is
set in l2tp_session_create, before the tunnel refcount is incremented
by l2tp_session_register, which leaves a small window where
session->tunnel is non-NULL when the tunnel refcount hasn't been
bumped.
Moving the assignment to l2tp_session_register is trivial but
l2tp_session_create calls l2tp_session_set_header_len which uses
session->tunnel to get the tunnel's encap. Add an encap arg to
l2tp_session_set_header_len to avoid using session->tunnel.
If l2tpv3 sessions have colliding IDs, it is possible for
l2tp_v3_session_get to race with l2tp_session_register and fetch a
session which doesn't yet have session->tunnel set. Add a check for
this case.
Signed-off-by: James Chapman <jchapman@katalix.com>
Signed-off-by: Tom Parkin <tparkin@katalix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/l2tp/l2tp_core.c | 16 ++++++++++------
net/l2tp/l2tp_core.h | 3 ++-
net/l2tp/l2tp_netlink.c | 4 +++-
net/l2tp/l2tp_ppp.c | 3 ++-
4 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 3c701795fa100..717559ead628a 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -380,11 +380,13 @@ int l2tp_session_register(struct l2tp_session *session,
}
l2tp_tunnel_inc_refcount(tunnel);
+ WRITE_ONCE(session->tunnel, tunnel);
hlist_add_head_rcu(&session->global_hlist, g_head);
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
} else {
l2tp_tunnel_inc_refcount(tunnel);
+ WRITE_ONCE(session->tunnel, tunnel);
}
hlist_add_head_rcu(&session->hlist, head);
@@ -698,7 +700,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
if (!session->lns_mode && !session->send_seq) {
trace_session_seqnum_lns_enable(session);
session->send_seq = 1;
- l2tp_session_set_header_len(session, tunnel->version);
+ l2tp_session_set_header_len(session, tunnel->version,
+ tunnel->encap);
}
} else {
/* No sequence numbers.
@@ -719,7 +722,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
if (!session->lns_mode && session->send_seq) {
trace_session_seqnum_lns_disable(session);
session->send_seq = 0;
- l2tp_session_set_header_len(session, tunnel->version);
+ l2tp_session_set_header_len(session, tunnel->version,
+ tunnel->encap);
} else if (session->send_seq) {
pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
session->name);
@@ -1579,7 +1583,8 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete);
/* We come here whenever a session's send_seq, cookie_len or
* l2specific_type parameters are set.
*/
-void l2tp_session_set_header_len(struct l2tp_session *session, int version)
+void l2tp_session_set_header_len(struct l2tp_session *session, int version,
+ enum l2tp_encap_type encap)
{
if (version == L2TP_HDR_VER_2) {
session->hdr_len = 6;
@@ -1588,7 +1593,7 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
} else {
session->hdr_len = 4 + session->cookie_len;
session->hdr_len += l2tp_get_l2specific_len(session);
- if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP)
+ if (encap == L2TP_ENCAPTYPE_UDP)
session->hdr_len += 4;
}
}
@@ -1602,7 +1607,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
session = kzalloc(sizeof(*session) + priv_size, GFP_KERNEL);
if (session) {
session->magic = L2TP_SESSION_MAGIC;
- session->tunnel = tunnel;
session->session_id = session_id;
session->peer_session_id = peer_session_id;
@@ -1638,7 +1642,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
memcpy(&session->peer_cookie[0], &cfg->peer_cookie[0], cfg->peer_cookie_len);
}
- l2tp_session_set_header_len(session, tunnel->version);
+ l2tp_session_set_header_len(session, tunnel->version, tunnel->encap);
refcount_set(&session->ref_count, 1);
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index a88e070b431d8..9f7143d2dd31b 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -261,7 +261,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
/* Transmit path helpers for sending packets over the tunnel socket. */
-void l2tp_session_set_header_len(struct l2tp_session *session, int version);
+void l2tp_session_set_header_len(struct l2tp_session *session, int version,
+ enum l2tp_encap_type encap);
int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb);
/* Pseudowire management.
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index e27e00cb16c6b..05314419c7bbb 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -690,8 +690,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf
session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
if (info->attrs[L2TP_ATTR_SEND_SEQ]) {
+ struct l2tp_tunnel *tunnel = session->tunnel;
+
session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
- l2tp_session_set_header_len(session, session->tunnel->version);
+ l2tp_session_set_header_len(session, tunnel->version, tunnel->encap);
}
if (info->attrs[L2TP_ATTR_LNS_MODE])
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 2e856a83a7506..1573edb66ee35 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1194,7 +1194,8 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
}
- l2tp_session_set_header_len(session, session->tunnel->version);
+ l2tp_session_set_header_len(session, session->tunnel->version,
+ session->tunnel->encap);
break;
case PPPOL2TP_SO_LNSMODE:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0675/1887] net/ncsi: Disable the ncsi work before freeing the associated structure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (673 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0674/1887] l2tp: prevent possible tunnel refcount underflow Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0676/1887] drm/amd/display: Implement bounds check for stream encoder creation in DCN401 Greg Kroah-Hartman
` (323 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Eddie James, Paolo Abeni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eddie James <eajames@linux.ibm.com>
[ Upstream commit a0ffa68c70b367358b2672cdab6fa5bc4c40de2c ]
The work function can run after the ncsi device is freed, resulting
in use-after-free bugs or kernel panic.
Fixes: 2d283bdd079c ("net/ncsi: Resource management")
Signed-off-by: Eddie James <eajames@linux.ibm.com>
Link: https://patch.msgid.link/20240925155523.1017097-1-eajames@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ncsi/ncsi-manage.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 6a58ae8b5d035..82030281e60ac 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -1967,6 +1967,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
list_del_rcu(&ndp->node);
spin_unlock_irqrestore(&ncsi_dev_lock, flags);
+ cancel_work_sync(&ndp->work);
+
kfree(ndp);
}
EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0676/1887] drm/amd/display: Implement bounds check for stream encoder creation in DCN401
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (674 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0675/1887] net/ncsi: Disable the ncsi work before freeing the associated structure Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0677/1887] cpufreq: amd-pstate: add check for cpufreq_cpu_gets return value Greg Kroah-Hartman
` (322 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Chung, Rodrigo Siqueira,
Roman Li, Alex Hung, Aurabindo Pillai, Harry Wentland,
Hamza Mahfooz, Srinivasan Shanmugam, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
[ Upstream commit bdf606810210e8e07a0cdf1af3c467291363b295 ]
'stream_enc_regs' array is an array of dcn10_stream_enc_registers
structures. The array is initialized with four elements, corresponding
to the four calls to stream_enc_regs() in the array initializer. This
means that valid indices for this array are 0, 1, 2, and 3.
The error message 'stream_enc_regs' 4 <= 5 below, is indicating that
there is an attempt to access this array with an index of 5, which is
out of bounds. This could lead to undefined behavior
Here, eng_id is used as an index to access the stream_enc_regs array. If
eng_id is 5, this would result in an out-of-bounds access on the
stream_enc_regs array.
Thus fixing Buffer overflow error in dcn401_stream_encoder_create
Found by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn401/dcn401_resource.c:1209 dcn401_stream_encoder_create() error: buffer overflow 'stream_enc_regs' 4 <= 5
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
index 85430e5baa455..4a1be0e371288 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
@@ -1208,7 +1208,7 @@ static struct stream_encoder *dcn321_stream_encoder_create(
vpg = dcn321_vpg_create(ctx, vpg_inst);
afmt = dcn321_afmt_create(ctx, afmt_inst);
- if (!enc1 || !vpg || !afmt) {
+ if (!enc1 || !vpg || !afmt || eng_id >= ARRAY_SIZE(stream_enc_regs)) {
kfree(enc1);
kfree(vpg);
kfree(afmt);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0677/1887] cpufreq: amd-pstate: add check for cpufreq_cpu_gets return value
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (675 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0676/1887] drm/amd/display: Implement bounds check for stream encoder creation in DCN401 Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0678/1887] nvme-pci: fix race condition between reset and nvme_dev_disable() Greg Kroah-Hartman
` (321 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anastasia Belova, Perry Yuan,
Viresh Kumar, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anastasia Belova <abelova@astralinux.ru>
[ Upstream commit 5493f9714e4cdaf0ee7cec15899a231400cb1a9f ]
cpufreq_cpu_get may return NULL. To avoid NULL-dereference check it
and return in case of error.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
Reviewed-by: Perry Yuan <perry.yuan@amd.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cpufreq/amd-pstate.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 90dcf26f09731..106aef210003d 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -309,9 +309,14 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
unsigned long max_perf, min_perf, des_perf,
cap_perf, lowest_nonlinear_perf, max_freq;
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
- struct amd_cpudata *cpudata = policy->driver_data;
+ struct amd_cpudata *cpudata;
unsigned int target_freq;
+ if (!policy)
+ return;
+
+ cpudata = policy->driver_data;
+
cap_perf = READ_ONCE(cpudata->highest_perf);
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
max_freq = READ_ONCE(cpudata->max_freq);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0678/1887] nvme-pci: fix race condition between reset and nvme_dev_disable()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (676 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0677/1887] cpufreq: amd-pstate: add check for cpufreq_cpu_gets return value Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0679/1887] cxl/port: Fix use-after-free, permit out-of-order decoder shutdown Greg Kroah-Hartman
` (320 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yi Zhang, Christoph Hellwig,
Maurizio Lombardi, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi <mlombard@redhat.com>
[ Upstream commit 26bc0a81f64ce00fc4342c38eeb2eddaad084dd2 ]
nvme_dev_disable() modifies the dev->online_queues field, therefore
nvme_pci_update_nr_queues() should avoid racing against it, otherwise
we could end up passing invalid values to blk_mq_update_nr_hw_queues().
WARNING: CPU: 39 PID: 61303 at drivers/pci/msi/api.c:347
pci_irq_get_affinity+0x187/0x210
Workqueue: nvme-reset-wq nvme_reset_work [nvme]
RIP: 0010:pci_irq_get_affinity+0x187/0x210
Call Trace:
<TASK>
? blk_mq_pci_map_queues+0x87/0x3c0
? pci_irq_get_affinity+0x187/0x210
blk_mq_pci_map_queues+0x87/0x3c0
nvme_pci_map_queues+0x189/0x460 [nvme]
blk_mq_update_nr_hw_queues+0x2a/0x40
nvme_reset_work+0x1be/0x2a0 [nvme]
Fix the bug by locking the shutdown_lock mutex before using
dev->online_queues. Give up if nvme_dev_disable() is running or if
it has been executed already.
Fixes: 949928c1c731 ("NVMe: Fix possible queue use after freed")
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/pci.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index a12d3ad54a1b6..0ed96b0ecb9e3 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2620,11 +2620,23 @@ static void nvme_pci_alloc_tag_set(struct nvme_dev *dev)
dev->ctrl.tagset = set;
}
-static void nvme_pci_update_nr_queues(struct nvme_dev *dev)
+static bool nvme_pci_update_nr_queues(struct nvme_dev *dev)
{
+ /* Give up if we are racing with nvme_dev_disable() */
+ if (!mutex_trylock(&dev->shutdown_lock))
+ return false;
+
+ /* Check if nvme_dev_disable() has been executed already */
+ if (!dev->online_queues) {
+ mutex_unlock(&dev->shutdown_lock);
+ return false;
+ }
+
blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
/* free previously allocated queues that are no longer usable */
nvme_free_queues(dev, dev->online_queues);
+ mutex_unlock(&dev->shutdown_lock);
+ return true;
}
static int nvme_pci_enable(struct nvme_dev *dev)
@@ -2986,8 +2998,8 @@ static void nvme_reset_work(struct work_struct *work)
nvme_wait_freeze(&dev->ctrl);
if (!dev->ctrl.tagset)
nvme_pci_alloc_tag_set(dev);
- else
- nvme_pci_update_nr_queues(dev);
+ else if (!nvme_pci_update_nr_queues(dev))
+ goto out;
nvme_dbbuf_set(dev);
nvme_unfreeze(&dev->ctrl);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0679/1887] cxl/port: Fix use-after-free, permit out-of-order decoder shutdown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (677 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0678/1887] nvme-pci: fix race condition between reset and nvme_dev_disable() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0680/1887] ksmbd: check outstanding simultaneous SMB operations Greg Kroah-Hartman
` (319 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron, Davidlohr Bueso,
Dave Jiang, Alison Schofield, Ira Weiny, Zijun Hu, Dan Williams,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <dan.j.williams@intel.com>
[ Upstream commit 101c268bd2f37e965a5468353e62d154db38838e ]
In support of investigating an initialization failure report [1],
cxl_test was updated to register mock memory-devices after the mock
root-port/bus device had been registered. That led to cxl_test crashing
with a use-after-free bug with the following signature:
cxl_port_attach_region: cxl region3: cxl_host_bridge.0:port3 decoder3.0 add: mem0:decoder7.0 @ 0 next: cxl_switch_uport.0 nr_eps: 1 nr_targets: 1
cxl_port_attach_region: cxl region3: cxl_host_bridge.0:port3 decoder3.0 add: mem4:decoder14.0 @ 1 next: cxl_switch_uport.0 nr_eps: 2 nr_targets: 1
cxl_port_setup_targets: cxl region3: cxl_switch_uport.0:port6 target[0] = cxl_switch_dport.0 for mem0:decoder7.0 @ 0
1) cxl_port_setup_targets: cxl region3: cxl_switch_uport.0:port6 target[1] = cxl_switch_dport.4 for mem4:decoder14.0 @ 1
[..]
cxld_unregister: cxl decoder14.0:
cxl_region_decode_reset: cxl_region region3:
mock_decoder_reset: cxl_port port3: decoder3.0 reset
2) mock_decoder_reset: cxl_port port3: decoder3.0: out of order reset, expected decoder3.1
cxl_endpoint_decoder_release: cxl decoder14.0:
[..]
cxld_unregister: cxl decoder7.0:
3) cxl_region_decode_reset: cxl_region region3:
Oops: general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6bc3: 0000 [#1] PREEMPT SMP PTI
[..]
RIP: 0010:to_cxl_port+0x8/0x60 [cxl_core]
[..]
Call Trace:
<TASK>
cxl_region_decode_reset+0x69/0x190 [cxl_core]
cxl_region_detach+0xe8/0x210 [cxl_core]
cxl_decoder_kill_region+0x27/0x40 [cxl_core]
cxld_unregister+0x5d/0x60 [cxl_core]
At 1) a region has been established with 2 endpoint decoders (7.0 and
14.0). Those endpoints share a common switch-decoder in the topology
(3.0). At teardown, 2), decoder14.0 is the first to be removed and hits
the "out of order reset case" in the switch decoder. The effect though
is that region3 cleanup is aborted leaving it in-tact and
referencing decoder14.0. At 3) the second attempt to teardown region3
trips over the stale decoder14.0 object which has long since been
deleted.
The fix here is to recognize that the CXL specification places no
mandate on in-order shutdown of switch-decoders, the driver enforces
in-order allocation, and hardware enforces in-order commit. So, rather
than fail and leave objects dangling, always remove them.
In support of making cxl_region_decode_reset() always succeed,
cxl_region_invalidate_memregion() failures are turned into warnings.
Crashing the kernel is ok there since system integrity is at risk if
caches cannot be managed around physical address mutation events like
CXL region destruction.
A new device_for_each_child_reverse_from() is added to cleanup
port->commit_end after all dependent decoders have been disabled. In
other words if decoders are allocated 0->1->2 and disabled 1->2->0 then
port->commit_end only decrements from 2 after 2 has been disabled, and
it decrements all the way to zero since 1 was disabled previously.
Link: http://lore.kernel.org/20241004212504.1246-1-gourry@gourry.net [1]
Cc: stable@vger.kernel.org
Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware")
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Alison Schofield <alison.schofield@intel.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: Zijun Hu <quic_zijuhu@quicinc.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Link: https://patch.msgid.link/172964782781.81806.17902885593105284330.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/core.c | 35 ++++++++++++++++++++++++++
drivers/cxl/core/hdm.c | 48 ++++++++++++++++++++++++++++++------
drivers/cxl/core/region.c | 29 ++++++----------------
drivers/cxl/cxl.h | 3 ++-
include/linux/device.h | 3 +++
tools/testing/cxl/test/cxl.c | 14 ++++-------
6 files changed, 93 insertions(+), 39 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 00737fc051575..6427d8e43347b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -4076,6 +4076,41 @@ int device_for_each_child_reverse(struct device *parent, void *data,
}
EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
+/**
+ * device_for_each_child_reverse_from - device child iterator in reversed order.
+ * @parent: parent struct device.
+ * @from: optional starting point in child list
+ * @fn: function to be called for each device.
+ * @data: data for the callback.
+ *
+ * Iterate over @parent's child devices, starting at @from, and call @fn
+ * for each, passing it @data. This helper is identical to
+ * device_for_each_child_reverse() when @from is NULL.
+ *
+ * @fn is checked each iteration. If it returns anything other than 0,
+ * iteration stop and that value is returned to the caller of
+ * device_for_each_child_reverse_from();
+ */
+int device_for_each_child_reverse_from(struct device *parent,
+ struct device *from, const void *data,
+ int (*fn)(struct device *, const void *))
+{
+ struct klist_iter i;
+ struct device *child;
+ int error = 0;
+
+ if (!parent->p)
+ return 0;
+
+ klist_iter_init_node(&parent->p->klist_children, &i,
+ (from ? &from->p->knode_parent : NULL));
+ while ((child = prev_device(&i)) && !error)
+ error = fn(child, data);
+ klist_iter_exit(&i);
+ return error;
+}
+EXPORT_SYMBOL_GPL(device_for_each_child_reverse_from);
+
/**
* device_find_child - device iterator for locating a particular device.
* @parent: parent struct device
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 7d48f5a575ceb..580cf7834cf11 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -641,7 +641,42 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
return 0;
}
-static int cxl_decoder_reset(struct cxl_decoder *cxld)
+static int commit_reap(struct device *dev, const void *data)
+{
+ struct cxl_port *port = to_cxl_port(dev->parent);
+ struct cxl_decoder *cxld;
+
+ if (!is_switch_decoder(dev) && !is_endpoint_decoder(dev))
+ return 0;
+
+ cxld = to_cxl_decoder(dev);
+ if (port->commit_end == cxld->id &&
+ ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
+ port->commit_end--;
+ dev_dbg(&port->dev, "reap: %s commit_end: %d\n",
+ dev_name(&cxld->dev), port->commit_end);
+ }
+
+ return 0;
+}
+
+void cxl_port_commit_reap(struct cxl_decoder *cxld)
+{
+ struct cxl_port *port = to_cxl_port(cxld->dev.parent);
+
+ /*
+ * Once the highest committed decoder is disabled, free any other
+ * decoders that were pinned allocated by out-of-order release.
+ */
+ port->commit_end--;
+ dev_dbg(&port->dev, "reap: %s commit_end: %d\n", dev_name(&cxld->dev),
+ port->commit_end);
+ device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL,
+ commit_reap);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL);
+
+static void cxl_decoder_reset(struct cxl_decoder *cxld)
{
struct cxl_port *port = to_cxl_port(cxld->dev.parent);
struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
@@ -650,14 +685,14 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
u32 ctrl;
if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
- return 0;
+ return;
- if (port->commit_end != id) {
+ if (port->commit_end == id)
+ cxl_port_commit_reap(cxld);
+ else
dev_dbg(&port->dev,
"%s: out of order reset, expected decoder%d.%d\n",
dev_name(&cxld->dev), port->id, port->commit_end);
- return -EBUSY;
- }
down_read(&cxl_dpa_rwsem);
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
@@ -670,10 +705,7 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
up_read(&cxl_dpa_rwsem);
- port->commit_end--;
cxld->flags &= ~CXL_DECODER_F_ENABLE;
-
- return 0;
}
static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 0e03c4908050b..cd53738a628de 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -121,7 +121,7 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port,
return xa_load(&port->regions, (unsigned long)cxlr);
}
-static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+static void cxl_region_decode_reset(struct cxl_region *cxlr, int count)
{
struct cxl_region_params *p = &cxlr->params;
int i;
@@ -131,7 +131,6 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_port *iter = cxled_to_port(cxled);
struct cxl_ep *ep;
- int rc = 0;
while (!is_cxl_root(to_cxl_port(iter->dev.parent)))
iter = to_cxl_port(iter->dev.parent);
@@ -144,17 +143,11 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
cxl_rr = cxl_rr_load(iter, cxlr);
cxld = cxl_rr->decoder;
if (cxld->reset)
- rc = cxld->reset(cxld);
- if (rc)
- return rc;
+ cxld->reset(cxld);
}
- rc = cxled->cxld.reset(&cxled->cxld);
- if (rc)
- return rc;
+ cxled->cxld.reset(&cxled->cxld);
}
-
- return 0;
}
static int cxl_region_decode_commit(struct cxl_region *cxlr)
@@ -244,8 +237,10 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
* The lock was dropped, so need to revalidate that the reset is
* still pending.
*/
- if (p->state == CXL_CONFIG_RESET_PENDING)
- rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
+ if (p->state == CXL_CONFIG_RESET_PENDING) {
+ cxl_region_decode_reset(cxlr, p->interleave_ways);
+ p->state = CXL_CONFIG_ACTIVE;
+ }
}
if (rc)
@@ -253,8 +248,6 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
if (commit)
p->state = CXL_CONFIG_COMMIT;
- else if (p->state == CXL_CONFIG_RESET_PENDING)
- p->state = CXL_CONFIG_ACTIVE;
out:
up_write(&cxl_region_rwsem);
@@ -1393,13 +1386,7 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
get_device(&cxlr->dev);
if (p->state > CXL_CONFIG_ACTIVE) {
- /*
- * TODO: tear down all impacted regions if a device is
- * removed out of order
- */
- rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
- if (rc)
- goto out;
+ cxl_region_decode_reset(cxlr, p->interleave_ways);
p->state = CXL_CONFIG_ACTIVE;
}
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 827fa94cddda1..0f3568071966d 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -273,7 +273,7 @@ struct cxl_decoder {
struct cxl_region *region;
unsigned long flags;
int (*commit)(struct cxl_decoder *cxld);
- int (*reset)(struct cxl_decoder *cxld);
+ void (*reset)(struct cxl_decoder *cxld);
};
/*
@@ -555,6 +555,7 @@ static inline bool is_cxl_root(struct cxl_port *port)
bool is_cxl_port(struct device *dev);
struct cxl_port *to_cxl_port(struct device *dev);
+void cxl_port_commit_reap(struct cxl_decoder *cxld);
struct pci_bus;
int devm_cxl_register_pci_bus(struct device *host, struct device *uport,
struct pci_bus *bus);
diff --git a/include/linux/device.h b/include/linux/device.h
index eae657af3a0e5..0e83be1bccc44 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -957,6 +957,9 @@ int device_for_each_child(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
int device_for_each_child_reverse(struct device *dev, void *data,
int (*fn)(struct device *dev, void *data));
+int device_for_each_child_reverse_from(struct device *parent,
+ struct device *from, const void *data,
+ int (*fn)(struct device *, const void *));
struct device *device_find_child(struct device *dev, void *data,
int (*match)(struct device *dev, void *data));
struct device *device_find_child_by_name(struct device *parent,
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 7be8bc4e4500e..37bd29e555903 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -533,26 +533,22 @@ static int mock_decoder_commit(struct cxl_decoder *cxld)
return 0;
}
-static int mock_decoder_reset(struct cxl_decoder *cxld)
+static void mock_decoder_reset(struct cxl_decoder *cxld)
{
struct cxl_port *port = to_cxl_port(cxld->dev.parent);
int id = cxld->id;
if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
- return 0;
+ return;
dev_dbg(&port->dev, "%s reset\n", dev_name(&cxld->dev));
- if (port->commit_end != id) {
+ if (port->commit_end == id)
+ cxl_port_commit_reap(cxld);
+ else
dev_dbg(&port->dev,
"%s: out of order reset, expected decoder%d.%d\n",
dev_name(&cxld->dev), port->id, port->commit_end);
- return -EBUSY;
- }
-
- port->commit_end--;
cxld->flags &= ~CXL_DECODER_F_ENABLE;
-
- return 0;
}
static void default_mock_decoder(struct cxl_decoder *cxld)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0680/1887] ksmbd: check outstanding simultaneous SMB operations
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (678 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0679/1887] cxl/port: Fix use-after-free, permit out-of-order decoder shutdown Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0681/1887] drm/msm/gem: prevent integer overflow in msm_ioctl_gem_submit() Greg Kroah-Hartman
` (318 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 0a77d947f599b1f39065015bec99390d0c0022ee ]
If Client send simultaneous SMB operations to ksmbd, It exhausts too much
memory through the "ksmbd_work_cache”. It will cause OOM issue.
ksmbd has a credit mechanism but it can't handle this problem. This patch
add the check if it exceeds max credits to prevent this problem by assuming
that one smb request consumes at least one credit.
Cc: stable@vger.kernel.org # v5.15+
Reported-by: Norbert Szetei <norbert@doyensec.com>
Tested-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 1 +
fs/smb/server/connection.h | 1 +
fs/smb/server/server.c | 16 ++++++++++------
fs/smb/server/smb_common.c | 10 +++++++---
fs/smb/server/smb_common.h | 2 +-
5 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index 0d27651aa4cc5..d99e1343955a3 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -115,6 +115,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
atomic_set(&conn->req_running, 0);
atomic_set(&conn->r_count, 0);
atomic_set(&conn->refcnt, 1);
+ atomic_set(&conn->mux_smb_requests, 0);
conn->total_credits = 1;
conn->outstanding_credits = 0;
diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h
index d01f137223b42..a38e264889eea 100644
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -113,6 +113,7 @@ struct ksmbd_conn {
__le16 signing_algorithm;
bool binding;
atomic_t refcnt;
+ atomic_t mux_smb_requests;
};
struct ksmbd_conn_ops {
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index a5e9bb40e2191..a61488b6b5904 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -290,6 +290,7 @@ static void handle_ksmbd_work(struct work_struct *wk)
ksmbd_conn_try_dequeue_request(work);
ksmbd_free_work_struct(work);
+ atomic_dec(&conn->mux_smb_requests);
/*
* Checking waitqueue to dropping pending requests on
* disconnection. waitqueue_active is safe because it
@@ -311,6 +312,15 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
struct ksmbd_work *work;
int err;
+ err = ksmbd_init_smb_server(conn);
+ if (err)
+ return 0;
+
+ if (atomic_inc_return(&conn->mux_smb_requests) >= conn->vals->max_credits) {
+ atomic_dec_return(&conn->mux_smb_requests);
+ return -ENOSPC;
+ }
+
work = ksmbd_alloc_work_struct();
if (!work) {
pr_err("allocation for work failed\n");
@@ -321,12 +331,6 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
work->request_buf = conn->request_buf;
conn->request_buf = NULL;
- err = ksmbd_init_smb_server(work);
- if (err) {
- ksmbd_free_work_struct(work);
- return 0;
- }
-
ksmbd_conn_enqueue_request(work);
atomic_inc(&conn->r_count);
/* update activity on connection */
diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c
index bcecbd67189ad..0350697c9093b 100644
--- a/fs/smb/server/smb_common.c
+++ b/fs/smb/server/smb_common.c
@@ -388,6 +388,10 @@ static struct smb_version_ops smb1_server_ops = {
.set_rsp_status = set_smb1_rsp_status,
};
+static struct smb_version_values smb1_server_values = {
+ .max_credits = SMB2_MAX_CREDITS,
+};
+
static int smb1_negotiate(struct ksmbd_work *work)
{
return ksmbd_smb_negotiate_common(work, SMB_COM_NEGOTIATE);
@@ -399,18 +403,18 @@ static struct smb_version_cmds smb1_server_cmds[1] = {
static int init_smb1_server(struct ksmbd_conn *conn)
{
+ conn->vals = &smb1_server_values;
conn->ops = &smb1_server_ops;
conn->cmds = smb1_server_cmds;
conn->max_cmds = ARRAY_SIZE(smb1_server_cmds);
return 0;
}
-int ksmbd_init_smb_server(struct ksmbd_work *work)
+int ksmbd_init_smb_server(struct ksmbd_conn *conn)
{
- struct ksmbd_conn *conn = work->conn;
__le32 proto;
- proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol;
+ proto = *(__le32 *)((struct smb_hdr *)conn->request_buf)->Protocol;
if (conn->need_neg == false) {
if (proto == SMB1_PROTO_NUMBER)
return -EINVAL;
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index d4291834b04f1..75de404a9efcc 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -391,7 +391,7 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn);
int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count);
-int ksmbd_init_smb_server(struct ksmbd_work *work);
+int ksmbd_init_smb_server(struct ksmbd_conn *conn);
struct ksmbd_kstat;
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0681/1887] drm/msm/gem: prevent integer overflow in msm_ioctl_gem_submit()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (679 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0680/1887] ksmbd: check outstanding simultaneous SMB operations Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0682/1887] firmware: arm_scmi: Simplify chan_available transport operation Greg Kroah-Hartman
` (317 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Rob Clark,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@linaro.org>
[ Upstream commit 3a47f4b439beb98e955d501c609dfd12b7836d61 ]
The "submit->cmd[i].size" and "submit->cmd[i].offset" variables are u32
values that come from the user via the submit_lookup_cmds() function.
This addition could lead to an integer wrapping bug so use size_add()
to prevent that.
Fixes: 198725337ef1 ("drm/msm: fix cmdstream size check")
Cc: stable@vger.kernel.org
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/624696/
Signed-off-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/msm_gem_submit.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 6a02f790624a9..df2f1348897c6 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -856,8 +856,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
goto out;
if (!submit->cmd[i].size ||
- ((submit->cmd[i].size + submit->cmd[i].offset) >
- msm_obj->base.size / 4)) {
+ (size_add(submit->cmd[i].size, submit->cmd[i].offset) > msm_obj->base.size / 4)) {
DRM_ERROR("invalid cmdstream size: %u\n", submit->cmd[i].size * 4);
ret = -EINVAL;
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0682/1887] firmware: arm_scmi: Simplify chan_available transport operation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (680 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0681/1887] drm/msm/gem: prevent integer overflow in msm_ioctl_gem_submit() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0683/1887] firmware: arm_scmi: Use dedicated devices to initialize channels Greg Kroah-Hartman
` (316 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 7a75b7afd8ff7b891e60b2fc9622148e6d1e010a ]
SCMI transport operation .chan_available determines in a transport
specific way if an SCMI channel is still available and to be configured.
Such information is derived by analyzing bits of device node in a
transport specific way, all it needs is a device node to operate up on,
not necessarily a full blown device.
Simplify the helper to receive in input a reference to a device_node
instead of a device carrying a pointer to such device_node.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-2-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/common.h | 2 +-
drivers/firmware/arm_scmi/driver.c | 2 +-
drivers/firmware/arm_scmi/mailbox.c | 4 ++--
drivers/firmware/arm_scmi/optee.c | 4 ++--
drivers/firmware/arm_scmi/smc.c | 4 ++--
drivers/firmware/arm_scmi/virtio.c | 2 +-
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 4ac72754c2554..15882266910b6 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -153,7 +153,7 @@ struct scmi_chan_info {
*/
struct scmi_transport_ops {
int (*link_supplier)(struct device *dev);
- bool (*chan_available)(struct device *dev, int idx);
+ bool (*chan_available)(struct device_node *of_node, int idx);
int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
bool tx);
int (*chan_free)(int id, void *p, void *data);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 53fd9b17b9bd3..f6d1063699f1e 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2047,7 +2047,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
if (cinfo)
return 0;
- if (!info->desc->ops->chan_available(dev, idx)) {
+ if (!info->desc->ops->chan_available(dev->of_node, idx)) {
cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
return -EINVAL;
diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
index 81c902672a305..2017f93599e66 100644
--- a/drivers/firmware/arm_scmi/mailbox.c
+++ b/drivers/firmware/arm_scmi/mailbox.c
@@ -60,9 +60,9 @@ static void rx_callback(struct mbox_client *cl, void *m)
scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL);
}
-static bool mailbox_chan_available(struct device *dev, int idx)
+static bool mailbox_chan_available(struct device_node *of_node, int idx)
{
- return !of_parse_phandle_with_args(dev->of_node, "mboxes",
+ return !of_parse_phandle_with_args(of_node, "mboxes",
"#mbox-cells", idx, NULL);
}
diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
index f5f6ec83d3e1f..78d5dd399aba0 100644
--- a/drivers/firmware/arm_scmi/optee.c
+++ b/drivers/firmware/arm_scmi/optee.c
@@ -328,11 +328,11 @@ static int scmi_optee_link_supplier(struct device *dev)
return 0;
}
-static bool scmi_optee_chan_available(struct device *dev, int idx)
+static bool scmi_optee_chan_available(struct device_node *of_node, int idx)
{
u32 channel_id;
- return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id",
+ return !of_property_read_u32_index(of_node, "linaro,optee-channel-id",
idx, &channel_id);
}
diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index 42ea308a2c1d5..795f7ccc89b12 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -54,9 +54,9 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data)
return IRQ_HANDLED;
}
-static bool smc_chan_available(struct device *dev, int idx)
+static bool smc_chan_available(struct device_node *of_node, int idx)
{
- struct device_node *np = of_parse_phandle(dev->of_node, "shmem", 0);
+ struct device_node *np = of_parse_phandle(of_node, "shmem", 0);
if (!np)
return false;
diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
index 1db975c088969..a917eca7d9024 100644
--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -385,7 +385,7 @@ static int virtio_link_supplier(struct device *dev)
return 0;
}
-static bool virtio_chan_available(struct device *dev, int idx)
+static bool virtio_chan_available(struct device_node *of_node, int idx)
{
struct scmi_vio_channel *channels, *vioch = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0683/1887] firmware: arm_scmi: Use dedicated devices to initialize channels
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (681 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0682/1887] firmware: arm_scmi: Simplify chan_available transport operation Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0684/1887] firmware: arm_scmi: Move protocol registration helpers Greg Kroah-Hartman
` (315 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 05a2801d8b90c1b5159618d4bd3a3c65d60f3ff1 ]
Refactor channels initialization to use dedicated transport devices
instead of using devices borrowed from the SCMI drivers.
Initialize all channels, as described in the device tree, upfront during
SCMI core stack probe phase and free all of them, including the underlying
devices, when the SCMI core is removed.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-3-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/common.h | 1 -
drivers/firmware/arm_scmi/driver.c | 158 ++++++++++++++++++++--------
drivers/firmware/arm_scmi/mailbox.c | 2 -
drivers/firmware/arm_scmi/optee.c | 2 -
drivers/firmware/arm_scmi/smc.c | 2 -
drivers/firmware/arm_scmi/virtio.c | 2 -
6 files changed, 116 insertions(+), 51 deletions(-)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 15882266910b6..3b601e4d99507 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -229,7 +229,6 @@ extern const struct scmi_desc scmi_optee_desc;
#endif
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
-void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
/* shmem related declarations */
struct scmi_shared_mem;
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index f6d1063699f1e..018713475d16d 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2031,23 +2031,20 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
return ret;
}
-static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
+static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
int prot_id, bool tx)
{
int ret, idx;
+ char name[32];
struct scmi_chan_info *cinfo;
struct idr *idr;
+ struct scmi_device *tdev = NULL;
/* Transmit channel is first entry i.e. index 0 */
idx = tx ? 0 : 1;
idr = tx ? &info->tx_idr : &info->rx_idr;
- /* check if already allocated, used for multiple device per protocol */
- cinfo = idr_find(idr, prot_id);
- if (cinfo)
- return 0;
-
- if (!info->desc->ops->chan_available(dev->of_node, idx)) {
+ if (!info->desc->ops->chan_available(of_node, idx)) {
cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
return -EINVAL;
@@ -2058,27 +2055,49 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
if (!cinfo)
return -ENOMEM;
- cinfo->dev = dev;
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
+ /* Create a unique name for this transport device */
+ snprintf(name, 32, "__scmi_transport_device_%s_%02X",
+ idx ? "rx" : "tx", prot_id);
+ /* Create a uniquely named, dedicated transport device for this chan */
+ tdev = scmi_device_create(of_node, info->dev, prot_id, name);
+ if (!tdev) {
+ devm_kfree(info->dev, cinfo);
+ return -EINVAL;
+ }
+ of_node_get(of_node);
+
+ cinfo->dev = &tdev->dev;
ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
- if (ret)
+ if (ret) {
+ of_node_put(of_node);
+ scmi_device_destroy(tdev);
+ devm_kfree(info->dev, cinfo);
return ret;
+ }
if (tx && is_polling_required(cinfo, info)) {
if (is_transport_polling_capable(info))
- dev_info(dev,
+ dev_info(&tdev->dev,
"Enabled polling mode TX channel - prot_id:%d\n",
prot_id);
else
- dev_warn(dev,
+ dev_warn(&tdev->dev,
"Polling mode NOT supported by transport.\n");
}
idr_alloc:
ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
if (ret != prot_id) {
- dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret);
+ dev_err(info->dev,
+ "unable to allocate SCMI idr slot err %d\n", ret);
+ /* Destroy channel and device only if created by this call. */
+ if (tdev) {
+ of_node_put(of_node);
+ scmi_device_destroy(tdev);
+ devm_kfree(info->dev, cinfo);
+ }
return ret;
}
@@ -2087,13 +2106,14 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
}
static inline int
-scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
+scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node,
+ int prot_id)
{
- int ret = scmi_chan_setup(info, dev, prot_id, true);
+ int ret = scmi_chan_setup(info, of_node, prot_id, true);
if (!ret) {
/* Rx is optional, report only memory errors */
- ret = scmi_chan_setup(info, dev, prot_id, false);
+ ret = scmi_chan_setup(info, of_node, prot_id, false);
if (ret && ret != -ENOMEM)
ret = 0;
}
@@ -2101,6 +2121,54 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
return ret;
}
+/**
+ * scmi_channels_setup - Helper to initialize all required channels
+ *
+ * @info: The SCMI instance descriptor.
+ *
+ * Initialize all the channels found described in the DT against the underlying
+ * configured transport using custom defined dedicated devices instead of
+ * borrowing devices from the SCMI drivers; this way channels are initialized
+ * upfront during core SCMI stack probing and are no more coupled with SCMI
+ * devices used by SCMI drivers.
+ *
+ * Note that, even though a pair of TX/RX channels is associated to each
+ * protocol defined in the DT, a distinct freshly initialized channel is
+ * created only if the DT node for the protocol at hand describes a dedicated
+ * channel: in all the other cases the common BASE protocol channel is reused.
+ *
+ * Return: 0 on Success
+ */
+static int scmi_channels_setup(struct scmi_info *info)
+{
+ int ret;
+ struct device_node *child, *top_np = info->dev->of_node;
+
+ /* Initialize a common generic channel at first */
+ ret = scmi_txrx_setup(info, top_np, SCMI_PROTOCOL_BASE);
+ if (ret)
+ return ret;
+
+ for_each_available_child_of_node(top_np, child) {
+ u32 prot_id;
+
+ if (of_property_read_u32(child, "reg", &prot_id))
+ continue;
+
+ if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id))
+ dev_err(info->dev,
+ "Out of range protocol %d\n", prot_id);
+
+ ret = scmi_txrx_setup(info, child, prot_id);
+ if (ret) {
+ of_node_put(child);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
/**
* scmi_get_protocol_device - Helper to get/create an SCMI device.
*
@@ -2150,14 +2218,6 @@ scmi_get_protocol_device(struct device_node *np, struct scmi_info *info,
return NULL;
}
- if (scmi_txrx_setup(info, &sdev->dev, prot_id)) {
- dev_err(&sdev->dev, "failed to setup transport\n");
- scmi_device_destroy(sdev);
- mutex_unlock(&scmi_syspower_mtx);
-
- return NULL;
- }
-
if (prot_id == SCMI_PROTOCOL_SYSTEM)
scmi_syspower_registered = true;
@@ -2391,19 +2451,39 @@ void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
mutex_unlock(&scmi_requested_devices_mtx);
}
-static int scmi_cleanup_txrx_channels(struct scmi_info *info)
+static int scmi_chan_destroy(int id, void *p, void *idr)
{
- int ret;
- struct idr *idr = &info->tx_idr;
+ struct scmi_chan_info *cinfo = p;
+
+ if (cinfo->dev) {
+ struct scmi_device *sdev = to_scmi_dev(cinfo->dev);
- ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
- idr_destroy(&info->tx_idr);
+ of_node_put(cinfo->dev->of_node);
+ scmi_device_destroy(sdev);
+ cinfo->dev = NULL;
+ }
- idr = &info->rx_idr;
- ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
- idr_destroy(&info->rx_idr);
+ idr_remove(idr, id);
- return ret;
+ return 0;
+}
+
+static void scmi_cleanup_channels(struct scmi_info *info, struct idr *idr)
+{
+ /* At first free all channels at the transport layer ... */
+ idr_for_each(idr, info->desc->ops->chan_free, idr);
+
+ /* ...then destroy all underlying devices */
+ idr_for_each(idr, scmi_chan_destroy, idr);
+
+ idr_destroy(idr);
+}
+
+static void scmi_cleanup_txrx_channels(struct scmi_info *info)
+{
+ scmi_cleanup_channels(info, &info->tx_idr);
+
+ scmi_cleanup_channels(info, &info->rx_idr);
}
static int scmi_probe(struct platform_device *pdev)
@@ -2455,7 +2535,8 @@ static int scmi_probe(struct platform_device *pdev)
return ret;
}
- ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
+ /* Setup all channels described in the DT at first */
+ ret = scmi_channels_setup(info);
if (ret)
return ret;
@@ -2525,14 +2606,9 @@ static int scmi_probe(struct platform_device *pdev)
return ret;
}
-void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
-{
- idr_remove(idr, id);
-}
-
static int scmi_remove(struct platform_device *pdev)
{
- int ret, id;
+ int id;
struct scmi_info *info = platform_get_drvdata(pdev);
struct device_node *child;
@@ -2554,9 +2630,7 @@ static int scmi_remove(struct platform_device *pdev)
idr_destroy(&info->active_protocols);
/* Safe to free channels since no more users */
- ret = scmi_cleanup_txrx_channels(info);
- if (ret)
- dev_warn(&pdev->dev, "Failed to cleanup SCMI channels.\n");
+ scmi_cleanup_txrx_channels(info);
return 0;
}
diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
index 2017f93599e66..3cd731cbe9b88 100644
--- a/drivers/firmware/arm_scmi/mailbox.c
+++ b/drivers/firmware/arm_scmi/mailbox.c
@@ -173,8 +173,6 @@ static int mailbox_chan_free(int id, void *p, void *data)
smbox->cinfo = NULL;
}
- scmi_free_channel(cinfo, data, id);
-
return 0;
}
diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
index 78d5dd399aba0..dd3ddda136e00 100644
--- a/drivers/firmware/arm_scmi/optee.c
+++ b/drivers/firmware/arm_scmi/optee.c
@@ -488,8 +488,6 @@ static int scmi_optee_chan_free(int id, void *p, void *data)
cinfo->transport_info = NULL;
channel->cinfo = NULL;
- scmi_free_channel(cinfo, data, id);
-
return 0;
}
diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index 795f7ccc89b12..7413dda373d40 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -185,8 +185,6 @@ static int smc_chan_free(int id, void *p, void *data)
cinfo->transport_info = NULL;
scmi_info->cinfo = NULL;
- scmi_free_channel(cinfo, data, id);
-
return 0;
}
diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
index a917eca7d9024..d68c01cb7aa00 100644
--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -489,8 +489,6 @@ static int virtio_chan_free(int id, void *p, void *data)
virtio_break_device(vioch->vqueue->vdev);
scmi_vio_channel_cleanup_sync(vioch);
- scmi_free_channel(cinfo, data, id);
-
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0684/1887] firmware: arm_scmi: Move protocol registration helpers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (682 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0683/1887] firmware: arm_scmi: Use dedicated devices to initialize channels Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0685/1887] firmware: arm_scmi: Add common notifier helpers Greg Kroah-Hartman
` (314 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 9115c20ac1ee9e92a3e751e352db818b7f95746a ]
Move protocol registration helpers and logic out of bus.c compilation
unit into driver.c.
No functional change.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-4-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 68 ------------------------------
drivers/firmware/arm_scmi/common.h | 3 --
drivers/firmware/arm_scmi/driver.c | 67 +++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 71 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 8c6f99d15f22f..83829c6303c22 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -16,8 +16,6 @@
#include "common.h"
static DEFINE_IDA(scmi_bus_id);
-static DEFINE_IDR(scmi_protocols);
-static DEFINE_SPINLOCK(protocol_lock);
static const struct scmi_device_id *
scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
@@ -79,30 +77,6 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
return to_scmi_dev(dev);
}
-const struct scmi_protocol *scmi_protocol_get(int protocol_id)
-{
- const struct scmi_protocol *proto;
-
- proto = idr_find(&scmi_protocols, protocol_id);
- if (!proto || !try_module_get(proto->owner)) {
- pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
- return NULL;
- }
-
- pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
-
- return proto;
-}
-
-void scmi_protocol_put(int protocol_id)
-{
- const struct scmi_protocol *proto;
-
- proto = idr_find(&scmi_protocols, protocol_id);
- if (proto)
- module_put(proto->owner);
-}
-
static int scmi_dev_probe(struct device *dev)
{
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
@@ -235,48 +209,6 @@ void scmi_set_handle(struct scmi_device *scmi_dev)
scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
}
-int scmi_protocol_register(const struct scmi_protocol *proto)
-{
- int ret;
-
- if (!proto) {
- pr_err("invalid protocol\n");
- return -EINVAL;
- }
-
- if (!proto->instance_init) {
- pr_err("missing init for protocol 0x%x\n", proto->id);
- return -EINVAL;
- }
-
- spin_lock(&protocol_lock);
- ret = idr_alloc(&scmi_protocols, (void *)proto,
- proto->id, proto->id + 1, GFP_ATOMIC);
- spin_unlock(&protocol_lock);
- if (ret != proto->id) {
- pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
- proto->id, ret);
- return ret;
- }
-
- pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(scmi_protocol_register);
-
-void scmi_protocol_unregister(const struct scmi_protocol *proto)
-{
- spin_lock(&protocol_lock);
- idr_remove(&scmi_protocols, proto->id);
- spin_unlock(&protocol_lock);
-
- pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);
-
- return;
-}
-EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
-
static int __scmi_devices_unregister(struct device *dev, void *data)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 3b601e4d99507..2a18578a4d578 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -106,9 +106,6 @@ void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
int __init scmi_bus_init(void);
void __exit scmi_bus_exit(void);
-const struct scmi_protocol *scmi_protocol_get(int protocol_id);
-void scmi_protocol_put(int protocol_id);
-
int scmi_protocol_acquire(const struct scmi_handle *handle, u8 protocol_id);
void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 018713475d16d..dc55a492461a0 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -51,6 +51,9 @@ enum scmi_error_codes {
SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
};
+static DEFINE_IDR(scmi_protocols);
+static DEFINE_SPINLOCK(protocol_lock);
+
/* List of all SCMI devices active in system */
static LIST_HEAD(scmi_list);
/* Protection for the entire list */
@@ -194,6 +197,70 @@ static inline int scmi_to_linux_errno(int errno)
return -EIO;
}
+static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
+{
+ const struct scmi_protocol *proto;
+
+ proto = idr_find(&scmi_protocols, protocol_id);
+ if (!proto || !try_module_get(proto->owner)) {
+ pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
+ return NULL;
+ }
+
+ pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
+
+ return proto;
+}
+
+static void scmi_protocol_put(int protocol_id)
+{
+ const struct scmi_protocol *proto;
+
+ proto = idr_find(&scmi_protocols, protocol_id);
+ if (proto)
+ module_put(proto->owner);
+}
+
+int scmi_protocol_register(const struct scmi_protocol *proto)
+{
+ int ret;
+
+ if (!proto) {
+ pr_err("invalid protocol\n");
+ return -EINVAL;
+ }
+
+ if (!proto->instance_init) {
+ pr_err("missing init for protocol 0x%x\n", proto->id);
+ return -EINVAL;
+ }
+
+ spin_lock(&protocol_lock);
+ ret = idr_alloc(&scmi_protocols, (void *)proto,
+ proto->id, proto->id + 1, GFP_ATOMIC);
+ spin_unlock(&protocol_lock);
+ if (ret != proto->id) {
+ pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
+ proto->id, ret);
+ return ret;
+ }
+
+ pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(scmi_protocol_register);
+
+void scmi_protocol_unregister(const struct scmi_protocol *proto)
+{
+ spin_lock(&protocol_lock);
+ idr_remove(&scmi_protocols, proto->id);
+ spin_unlock(&protocol_lock);
+
+ pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);
+}
+EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
+
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
void *priv)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0685/1887] firmware: arm_scmi: Add common notifier helpers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (683 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0684/1887] firmware: arm_scmi: Move protocol registration helpers Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0686/1887] firmware: arm_scmi: Refactor protocol device creation Greg Kroah-Hartman
` (313 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 53b8c25df7082edd78a3fc63e359abee0f28fa70 ]
Add a pair of notifier chains and generic empty notifier callbacks.
Currently they are still unused but they will be used to act properly
on device request and creation events.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-5-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 6 ++-
drivers/firmware/arm_scmi/common.h | 5 ++
drivers/firmware/arm_scmi/driver.c | 83 +++++++++++++++++++++++++++++-
3 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 83829c6303c22..c3df8ed76bd72 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -15,6 +15,9 @@
#include "common.h"
+BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh);
+EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
+
static DEFINE_IDA(scmi_bus_id);
static const struct scmi_device_id *
@@ -97,12 +100,13 @@ static void scmi_dev_remove(struct device *dev)
scmi_drv->remove(scmi_dev);
}
-static struct bus_type scmi_bus_type = {
+struct bus_type scmi_bus_type = {
.name = "scmi_protocol",
.match = scmi_dev_match,
.probe = scmi_dev_probe,
.remove = scmi_dev_remove,
};
+EXPORT_SYMBOL_GPL(scmi_bus_type);
int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
const char *mod_name)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 2a18578a4d578..46666ecdf46c9 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -105,6 +105,11 @@ void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
int __init scmi_bus_init(void);
void __exit scmi_bus_exit(void);
+extern struct bus_type scmi_bus_type;
+
+#define SCMI_BUS_NOTIFY_DEVICE_REQUEST 0
+#define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1
+extern struct blocking_notifier_head scmi_requested_devices_nh;
int scmi_protocol_acquire(const struct scmi_handle *handle, u8 protocol_id);
void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index dc55a492461a0..a3257955b8c4e 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -150,6 +150,9 @@ struct scmi_protocol_instance {
* @notify_priv: Pointer to private data structure specific to notifications.
* @node: List head
* @users: Number of users of this instance
+ * @bus_nb: A notifier to listen for device bind/unbind on the scmi bus
+ * @dev_req_nb: A notifier to listen for device request/unrequest on the scmi
+ * bus
*/
struct scmi_info {
struct device *dev;
@@ -169,9 +172,13 @@ struct scmi_info {
void *notify_priv;
struct list_head node;
int users;
+ struct notifier_block bus_nb;
+ struct notifier_block dev_req_nb;
};
#define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle)
+#define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb)
+#define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req_nb)
static const int scmi_linux_errmap[] = {
/* better than switch case as long as return value is continuous */
@@ -2553,6 +2560,60 @@ static void scmi_cleanup_txrx_channels(struct scmi_info *info)
scmi_cleanup_channels(info, &info->rx_idr);
}
+static int scmi_bus_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct scmi_info *info = bus_nb_to_scmi_info(nb);
+ struct scmi_device *sdev = to_scmi_dev(data);
+
+ /* Skip transport devices and devices of different SCMI instances */
+ if (!strncmp(sdev->name, "__scmi_transport_device", 23) ||
+ sdev->dev.parent != info->dev)
+ return NOTIFY_DONE;
+
+ switch (action) {
+ case BUS_NOTIFY_BIND_DRIVER:
+ break;
+ case BUS_NOTIFY_UNBOUND_DRIVER:
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ dev_dbg(info->dev, "Device %s (%s) is now %s\n", dev_name(&sdev->dev),
+ sdev->name, action == BUS_NOTIFY_BIND_DRIVER ?
+ "about to be BOUND." : "UNBOUND.");
+
+ return NOTIFY_OK;
+}
+
+static int scmi_device_request_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device_node *np;
+ struct scmi_device_id *id_table = data;
+ struct scmi_info *info = req_nb_to_scmi_info(nb);
+
+ np = idr_find(&info->active_protocols, id_table->protocol_id);
+ if (!np)
+ return NOTIFY_DONE;
+
+ dev_dbg(info->dev, "%sRequested device (%s) for protocol 0x%x\n",
+ action == SCMI_BUS_NOTIFY_DEVICE_REQUEST ? "" : "UN-",
+ id_table->name, id_table->protocol_id);
+
+ switch (action) {
+ case SCMI_BUS_NOTIFY_DEVICE_REQUEST:
+ break;
+ case SCMI_BUS_NOTIFY_DEVICE_UNREQUEST:
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+
static int scmi_probe(struct platform_device *pdev)
{
int ret;
@@ -2572,6 +2633,8 @@ static int scmi_probe(struct platform_device *pdev)
info->dev = dev;
info->desc = desc;
+ info->bus_nb.notifier_call = scmi_bus_notifier;
+ info->dev_req_nb.notifier_call = scmi_device_request_notifier;
INIT_LIST_HEAD(&info->node);
idr_init(&info->protocols);
mutex_init(&info->protocols_mtx);
@@ -2607,10 +2670,19 @@ static int scmi_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = scmi_xfer_info_init(info);
+ ret = bus_register_notifier(&scmi_bus_type, &info->bus_nb);
if (ret)
goto clear_txrx_setup;
+ ret = blocking_notifier_chain_register(&scmi_requested_devices_nh,
+ &info->dev_req_nb);
+ if (ret)
+ goto clear_bus_notifier;
+
+ ret = scmi_xfer_info_init(info);
+ if (ret)
+ goto clear_dev_req_notifier;
+
if (scmi_notification_init(handle))
dev_err(dev, "SCMI Notifications NOT available.\n");
@@ -2668,6 +2740,11 @@ static int scmi_probe(struct platform_device *pdev)
notification_exit:
scmi_notification_exit(&info->handle);
+clear_dev_req_notifier:
+ blocking_notifier_chain_unregister(&scmi_requested_devices_nh,
+ &info->dev_req_nb);
+clear_bus_notifier:
+ bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
clear_txrx_setup:
scmi_cleanup_txrx_channels(info);
return ret;
@@ -2696,6 +2773,10 @@ static int scmi_remove(struct platform_device *pdev)
of_node_put(child);
idr_destroy(&info->active_protocols);
+ blocking_notifier_chain_unregister(&scmi_requested_devices_nh,
+ &info->dev_req_nb);
+ bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
+
/* Safe to free channels since no more users */
scmi_cleanup_txrx_channels(info);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0686/1887] firmware: arm_scmi: Refactor protocol device creation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (684 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0685/1887] firmware: arm_scmi: Add common notifier helpers Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0687/1887] firmware: arm_scmi: Move handle get/set helpers Greg Kroah-Hartman
` (312 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit d3cd7c525fd2ecce3a6c963f314969a54783d211 ]
Move protocol device request helpers from driver.c compilation unit to
bus.c, so reducing the cross interactions between driver.c and bus.c.
Get rid of old protocol device creation process as a whole from driver.c
and remove also stale SCMI system power unicity checks.
While at that make such helpers call into scmi_requested_devices_nh
notification chain.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-6-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 157 ++++++++++++++-
drivers/firmware/arm_scmi/common.h | 2 -
drivers/firmware/arm_scmi/driver.c | 296 -----------------------------
3 files changed, 156 insertions(+), 299 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index c3df8ed76bd72..7514b3e326114 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>
@@ -20,6 +21,160 @@ EXPORT_SYMBOL_GPL(scmi_requested_devices_nh);
static DEFINE_IDA(scmi_bus_id);
+static DEFINE_IDR(scmi_requested_devices);
+/* Protect access to scmi_requested_devices */
+static DEFINE_MUTEX(scmi_requested_devices_mtx);
+
+struct scmi_requested_dev {
+ const struct scmi_device_id *id_table;
+ struct list_head node;
+};
+
+/**
+ * scmi_protocol_device_request - Helper to request a device
+ *
+ * @id_table: A protocol/name pair descriptor for the device to be created.
+ *
+ * This helper let an SCMI driver request specific devices identified by the
+ * @id_table to be created for each active SCMI instance.
+ *
+ * The requested device name MUST NOT be already existent for any protocol;
+ * at first the freshly requested @id_table is annotated in the IDR table
+ * @scmi_requested_devices and then the requested device is advertised to any
+ * registered party via the @scmi_requested_devices_nh notification chain.
+ *
+ * Return: 0 on Success
+ */
+static int scmi_protocol_device_request(const struct scmi_device_id *id_table)
+{
+ int ret = 0;
+ unsigned int id = 0;
+ struct list_head *head, *phead = NULL;
+ struct scmi_requested_dev *rdev;
+
+ pr_debug("Requesting SCMI device (%s) for protocol %x\n",
+ id_table->name, id_table->protocol_id);
+
+ /*
+ * Search for the matching protocol rdev list and then search
+ * of any existent equally named device...fails if any duplicate found.
+ */
+ mutex_lock(&scmi_requested_devices_mtx);
+ idr_for_each_entry(&scmi_requested_devices, head, id) {
+ if (!phead) {
+ /* A list found registered in the IDR is never empty */
+ rdev = list_first_entry(head, struct scmi_requested_dev,
+ node);
+ if (rdev->id_table->protocol_id ==
+ id_table->protocol_id)
+ phead = head;
+ }
+ list_for_each_entry(rdev, head, node) {
+ if (!strcmp(rdev->id_table->name, id_table->name)) {
+ pr_err("Ignoring duplicate request [%d] %s\n",
+ rdev->id_table->protocol_id,
+ rdev->id_table->name);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+ }
+
+ /*
+ * No duplicate found for requested id_table, so let's create a new
+ * requested device entry for this new valid request.
+ */
+ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
+ if (!rdev) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ rdev->id_table = id_table;
+
+ /*
+ * Append the new requested device table descriptor to the head of the
+ * related protocol list, eventually creating such head if not already
+ * there.
+ */
+ if (!phead) {
+ phead = kzalloc(sizeof(*phead), GFP_KERNEL);
+ if (!phead) {
+ kfree(rdev);
+ ret = -ENOMEM;
+ goto out;
+ }
+ INIT_LIST_HEAD(phead);
+
+ ret = idr_alloc(&scmi_requested_devices, (void *)phead,
+ id_table->protocol_id,
+ id_table->protocol_id + 1, GFP_KERNEL);
+ if (ret != id_table->protocol_id) {
+ pr_err("Failed to save SCMI device - ret:%d\n", ret);
+ kfree(rdev);
+ kfree(phead);
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = 0;
+ }
+ list_add(&rdev->node, phead);
+
+out:
+ mutex_unlock(&scmi_requested_devices_mtx);
+
+ if (!ret)
+ blocking_notifier_call_chain(&scmi_requested_devices_nh,
+ SCMI_BUS_NOTIFY_DEVICE_REQUEST,
+ (void *)rdev->id_table);
+
+ return ret;
+}
+
+/**
+ * scmi_protocol_device_unrequest - Helper to unrequest a device
+ *
+ * @id_table: A protocol/name pair descriptor for the device to be unrequested.
+ *
+ * The unrequested device, described by the provided id_table, is at first
+ * removed from the IDR @scmi_requested_devices and then the removal is
+ * advertised to any registered party via the @scmi_requested_devices_nh
+ * notification chain.
+ */
+static void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
+{
+ struct list_head *phead;
+
+ pr_debug("Unrequesting SCMI device (%s) for protocol %x\n",
+ id_table->name, id_table->protocol_id);
+
+ mutex_lock(&scmi_requested_devices_mtx);
+ phead = idr_find(&scmi_requested_devices, id_table->protocol_id);
+ if (phead) {
+ struct scmi_requested_dev *victim, *tmp;
+
+ list_for_each_entry_safe(victim, tmp, phead, node) {
+ if (!strcmp(victim->id_table->name, id_table->name)) {
+ list_del(&victim->node);
+
+ mutex_unlock(&scmi_requested_devices_mtx);
+ blocking_notifier_call_chain(&scmi_requested_devices_nh,
+ SCMI_BUS_NOTIFY_DEVICE_UNREQUEST,
+ (void *)victim->id_table);
+ kfree(victim);
+ mutex_lock(&scmi_requested_devices_mtx);
+ break;
+ }
+ }
+
+ if (list_empty(phead)) {
+ idr_remove(&scmi_requested_devices,
+ id_table->protocol_id);
+ kfree(phead);
+ }
+ }
+ mutex_unlock(&scmi_requested_devices_mtx);
+}
+
static const struct scmi_device_id *
scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
{
@@ -127,7 +282,7 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
retval = driver_register(&driver->driver);
if (!retval)
- pr_debug("registered new scmi driver %s\n", driver->name);
+ pr_debug("Registered new scmi driver %s\n", driver->name);
return retval;
}
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 46666ecdf46c9..feccde5e29650 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -172,8 +172,6 @@ struct scmi_transport_ops {
bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
};
-int scmi_protocol_device_request(const struct scmi_device_id *id_table);
-void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table);
struct scmi_device *scmi_child_dev_find(struct device *parent,
int prot_id, const char *name);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index a3257955b8c4e..9fa5632aa2c75 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -61,19 +61,6 @@ static DEFINE_MUTEX(scmi_list_mutex);
/* Track the unique id for the transfers for debug & profiling purpose */
static atomic_t transfer_last_id;
-static DEFINE_IDR(scmi_requested_devices);
-static DEFINE_MUTEX(scmi_requested_devices_mtx);
-
-/* Track globally the creation of SCMI SystemPower related devices */
-static bool scmi_syspower_registered;
-/* Protect access to scmi_syspower_registered */
-static DEFINE_MUTEX(scmi_syspower_mtx);
-
-struct scmi_requested_dev {
- const struct scmi_device_id *id_table;
- struct list_head node;
-};
-
/**
* struct scmi_xfers_info - Structure to manage transfer information
*
@@ -2243,288 +2230,6 @@ static int scmi_channels_setup(struct scmi_info *info)
return 0;
}
-/**
- * scmi_get_protocol_device - Helper to get/create an SCMI device.
- *
- * @np: A device node representing a valid active protocols for the referred
- * SCMI instance.
- * @info: The referred SCMI instance for which we are getting/creating this
- * device.
- * @prot_id: The protocol ID.
- * @name: The device name.
- *
- * Referring to the specific SCMI instance identified by @info, this helper
- * takes care to return a properly initialized device matching the requested
- * @proto_id and @name: if device was still not existent it is created as a
- * child of the specified SCMI instance @info and its transport properly
- * initialized as usual.
- *
- * Return: A properly initialized scmi device, NULL otherwise.
- */
-static inline struct scmi_device *
-scmi_get_protocol_device(struct device_node *np, struct scmi_info *info,
- int prot_id, const char *name)
-{
- struct scmi_device *sdev;
-
- /* Already created for this parent SCMI instance ? */
- sdev = scmi_child_dev_find(info->dev, prot_id, name);
- if (sdev)
- return sdev;
-
- mutex_lock(&scmi_syspower_mtx);
- if (prot_id == SCMI_PROTOCOL_SYSTEM && scmi_syspower_registered) {
- dev_warn(info->dev,
- "SCMI SystemPower protocol device must be unique !\n");
- mutex_unlock(&scmi_syspower_mtx);
-
- return NULL;
- }
-
- pr_debug("Creating SCMI device (%s) for protocol %x\n", name, prot_id);
-
- sdev = scmi_device_create(np, info->dev, prot_id, name);
- if (!sdev) {
- dev_err(info->dev, "failed to create %d protocol device\n",
- prot_id);
- mutex_unlock(&scmi_syspower_mtx);
-
- return NULL;
- }
-
- if (prot_id == SCMI_PROTOCOL_SYSTEM)
- scmi_syspower_registered = true;
-
- mutex_unlock(&scmi_syspower_mtx);
-
- return sdev;
-}
-
-static inline void
-scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
- int prot_id, const char *name)
-{
- struct scmi_device *sdev;
-
- sdev = scmi_get_protocol_device(np, info, prot_id, name);
- if (!sdev)
- return;
-
- /* setup handle now as the transport is ready */
- scmi_set_handle(sdev);
-}
-
-/**
- * scmi_create_protocol_devices - Create devices for all pending requests for
- * this SCMI instance.
- *
- * @np: The device node describing the protocol
- * @info: The SCMI instance descriptor
- * @prot_id: The protocol ID
- *
- * All devices previously requested for this instance (if any) are found and
- * created by scanning the proper @&scmi_requested_devices entry.
- */
-static void scmi_create_protocol_devices(struct device_node *np,
- struct scmi_info *info, int prot_id)
-{
- struct list_head *phead;
-
- mutex_lock(&scmi_requested_devices_mtx);
- phead = idr_find(&scmi_requested_devices, prot_id);
- if (phead) {
- struct scmi_requested_dev *rdev;
-
- list_for_each_entry(rdev, phead, node)
- scmi_create_protocol_device(np, info, prot_id,
- rdev->id_table->name);
- }
- mutex_unlock(&scmi_requested_devices_mtx);
-}
-
-/**
- * scmi_protocol_device_request - Helper to request a device
- *
- * @id_table: A protocol/name pair descriptor for the device to be created.
- *
- * This helper let an SCMI driver request specific devices identified by the
- * @id_table to be created for each active SCMI instance.
- *
- * The requested device name MUST NOT be already existent for any protocol;
- * at first the freshly requested @id_table is annotated in the IDR table
- * @scmi_requested_devices, then a matching device is created for each already
- * active SCMI instance. (if any)
- *
- * This way the requested device is created straight-away for all the already
- * initialized(probed) SCMI instances (handles) and it remains also annotated
- * as pending creation if the requesting SCMI driver was loaded before some
- * SCMI instance and related transports were available: when such late instance
- * is probed, its probe will take care to scan the list of pending requested
- * devices and create those on its own (see @scmi_create_protocol_devices and
- * its enclosing loop)
- *
- * Return: 0 on Success
- */
-int scmi_protocol_device_request(const struct scmi_device_id *id_table)
-{
- int ret = 0;
- unsigned int id = 0;
- struct list_head *head, *phead = NULL;
- struct scmi_requested_dev *rdev;
- struct scmi_info *info;
-
- pr_debug("Requesting SCMI device (%s) for protocol %x\n",
- id_table->name, id_table->protocol_id);
-
- /*
- * Search for the matching protocol rdev list and then search
- * of any existent equally named device...fails if any duplicate found.
- */
- mutex_lock(&scmi_requested_devices_mtx);
- idr_for_each_entry(&scmi_requested_devices, head, id) {
- if (!phead) {
- /* A list found registered in the IDR is never empty */
- rdev = list_first_entry(head, struct scmi_requested_dev,
- node);
- if (rdev->id_table->protocol_id ==
- id_table->protocol_id)
- phead = head;
- }
- list_for_each_entry(rdev, head, node) {
- if (!strcmp(rdev->id_table->name, id_table->name)) {
- pr_err("Ignoring duplicate request [%d] %s\n",
- rdev->id_table->protocol_id,
- rdev->id_table->name);
- ret = -EINVAL;
- goto out;
- }
- }
- }
-
- /*
- * No duplicate found for requested id_table, so let's create a new
- * requested device entry for this new valid request.
- */
- rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
- if (!rdev) {
- ret = -ENOMEM;
- goto out;
- }
- rdev->id_table = id_table;
-
- /*
- * Append the new requested device table descriptor to the head of the
- * related protocol list, eventually creating such head if not already
- * there.
- */
- if (!phead) {
- phead = kzalloc(sizeof(*phead), GFP_KERNEL);
- if (!phead) {
- kfree(rdev);
- ret = -ENOMEM;
- goto out;
- }
- INIT_LIST_HEAD(phead);
-
- ret = idr_alloc(&scmi_requested_devices, (void *)phead,
- id_table->protocol_id,
- id_table->protocol_id + 1, GFP_KERNEL);
- if (ret != id_table->protocol_id) {
- pr_err("Failed to save SCMI device - ret:%d\n", ret);
- kfree(rdev);
- kfree(phead);
- ret = -EINVAL;
- goto out;
- }
- ret = 0;
- }
- list_add(&rdev->node, phead);
-
- /*
- * Now effectively create and initialize the requested device for every
- * already initialized SCMI instance which has registered the requested
- * protocol as a valid active one: i.e. defined in DT and supported by
- * current platform FW.
- */
- mutex_lock(&scmi_list_mutex);
- list_for_each_entry(info, &scmi_list, node) {
- struct device_node *child;
-
- child = idr_find(&info->active_protocols,
- id_table->protocol_id);
- if (child) {
- struct scmi_device *sdev;
-
- sdev = scmi_get_protocol_device(child, info,
- id_table->protocol_id,
- id_table->name);
- if (sdev) {
- /* Set handle if not already set: device existed */
- if (!sdev->handle)
- sdev->handle =
- scmi_handle_get_from_info_unlocked(info);
- /* Relink consumer and suppliers */
- if (sdev->handle)
- scmi_device_link_add(&sdev->dev,
- sdev->handle->dev);
- }
- } else {
- dev_err(info->dev,
- "Failed. SCMI protocol %d not active.\n",
- id_table->protocol_id);
- }
- }
- mutex_unlock(&scmi_list_mutex);
-
-out:
- mutex_unlock(&scmi_requested_devices_mtx);
-
- return ret;
-}
-
-/**
- * scmi_protocol_device_unrequest - Helper to unrequest a device
- *
- * @id_table: A protocol/name pair descriptor for the device to be unrequested.
- *
- * An helper to let an SCMI driver release its request about devices; note that
- * devices are created and initialized once the first SCMI driver request them
- * but they destroyed only on SCMI core unloading/unbinding.
- *
- * The current SCMI transport layer uses such devices as internal references and
- * as such they could be shared as same transport between multiple drivers so
- * that cannot be safely destroyed till the whole SCMI stack is removed.
- * (unless adding further burden of refcounting.)
- */
-void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
-{
- struct list_head *phead;
-
- pr_debug("Unrequesting SCMI device (%s) for protocol %x\n",
- id_table->name, id_table->protocol_id);
-
- mutex_lock(&scmi_requested_devices_mtx);
- phead = idr_find(&scmi_requested_devices, id_table->protocol_id);
- if (phead) {
- struct scmi_requested_dev *victim, *tmp;
-
- list_for_each_entry_safe(victim, tmp, phead, node) {
- if (!strcmp(victim->id_table->name, id_table->name)) {
- list_del(&victim->node);
- kfree(victim);
- break;
- }
- }
-
- if (list_empty(phead)) {
- idr_remove(&scmi_requested_devices,
- id_table->protocol_id);
- kfree(phead);
- }
- }
- mutex_unlock(&scmi_requested_devices_mtx);
-}
-
static int scmi_chan_destroy(int id, void *p, void *idr)
{
struct scmi_chan_info *cinfo = p;
@@ -2733,7 +2438,6 @@ static int scmi_probe(struct platform_device *pdev)
}
of_node_get(child);
- scmi_create_protocol_devices(child, info, prot_id);
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0687/1887] firmware: arm_scmi: Move handle get/set helpers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (685 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0686/1887] firmware: arm_scmi: Refactor protocol device creation Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0688/1887] firmware: arm_scmi: Refactor device create/destroy helpers Greg Kroah-Hartman
` (311 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 971fc0665f1361f23251e4d85fac4aed1b683505 ]
Move handle get/set helpers definitions into driver.c and invoke them
through the bus notifier helper.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-7-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 17 ---------------
drivers/firmware/arm_scmi/common.h | 4 ----
drivers/firmware/arm_scmi/driver.c | 35 +++++++++++++++++++++---------
3 files changed, 25 insertions(+), 31 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 7514b3e326114..14f96583b6e0d 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -347,27 +347,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol,
void scmi_device_destroy(struct scmi_device *scmi_dev)
{
kfree_const(scmi_dev->name);
- scmi_handle_put(scmi_dev->handle);
ida_free(&scmi_bus_id, scmi_dev->id);
device_unregister(&scmi_dev->dev);
}
-void scmi_device_link_add(struct device *consumer, struct device *supplier)
-{
- struct device_link *link;
-
- link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER);
-
- WARN_ON(!link);
-}
-
-void scmi_set_handle(struct scmi_device *scmi_dev)
-{
- scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
- if (scmi_dev->handle)
- scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
-}
-
static int __scmi_devices_unregister(struct device *dev, void *data)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index feccde5e29650..23f0ab3f2ed7f 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -96,10 +96,6 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
struct scmi_revision_info *
scmi_revision_area_get(const struct scmi_protocol_handle *ph);
-int scmi_handle_put(const struct scmi_handle *handle);
-void scmi_device_link_add(struct device *consumer, struct device *supplier);
-struct scmi_handle *scmi_handle_get(struct device *dev);
-void scmi_set_handle(struct scmi_device *scmi_dev);
void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
u8 *prot_imp);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 9fa5632aa2c75..f01097b9e953a 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1934,13 +1934,6 @@ static bool scmi_is_transport_atomic(const struct scmi_handle *handle,
return ret;
}
-static inline
-struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
-{
- info->users++;
- return &info->handle;
-}
-
/**
* scmi_handle_get() - Get the SCMI handle for a device
*
@@ -1952,7 +1945,7 @@ struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
*
* Return: pointer to handle if successful, NULL on error
*/
-struct scmi_handle *scmi_handle_get(struct device *dev)
+static struct scmi_handle *scmi_handle_get(struct device *dev)
{
struct list_head *p;
struct scmi_info *info;
@@ -1962,7 +1955,8 @@ struct scmi_handle *scmi_handle_get(struct device *dev)
list_for_each(p, &scmi_list) {
info = list_entry(p, struct scmi_info, node);
if (dev->parent == info->dev) {
- handle = scmi_handle_get_from_info_unlocked(info);
+ info->users++;
+ handle = &info->handle;
break;
}
}
@@ -1983,7 +1977,7 @@ struct scmi_handle *scmi_handle_get(struct device *dev)
* Return: 0 is successfully released
* if null was passed, it returns -EINVAL;
*/
-int scmi_handle_put(const struct scmi_handle *handle)
+static int scmi_handle_put(const struct scmi_handle *handle)
{
struct scmi_info *info;
@@ -1999,6 +1993,23 @@ int scmi_handle_put(const struct scmi_handle *handle)
return 0;
}
+static void scmi_device_link_add(struct device *consumer,
+ struct device *supplier)
+{
+ struct device_link *link;
+
+ link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER);
+
+ WARN_ON(!link);
+}
+
+static void scmi_set_handle(struct scmi_device *scmi_dev)
+{
+ scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
+ if (scmi_dev->handle)
+ scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
+}
+
static int __scmi_xfer_info_init(struct scmi_info *sinfo,
struct scmi_xfers_info *info)
{
@@ -2278,8 +2289,12 @@ static int scmi_bus_notifier(struct notifier_block *nb,
switch (action) {
case BUS_NOTIFY_BIND_DRIVER:
+ /* setup handle now as the transport is ready */
+ scmi_set_handle(sdev);
break;
case BUS_NOTIFY_UNBOUND_DRIVER:
+ scmi_handle_put(sdev->handle);
+ sdev->handle = NULL;
break;
default:
return NOTIFY_DONE;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0688/1887] firmware: arm_scmi: Refactor device create/destroy helpers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (686 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0687/1887] firmware: arm_scmi: Move handle get/set helpers Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0689/1887] firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier() Greg Kroah-Hartman
` (310 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Marussi, Sudeep Holla,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Marussi <cristian.marussi@arm.com>
[ Upstream commit 2c3e674465e73e2f7eb52c39dc5c5e97e78e68ea ]
Refactor SCMI device create/destroy helpers: it is now possible to ask
for the creation of all the currently requested devices for a whole
protocol, not only for the creation of a single well-defined device.
While at that, re-instate uniqueness checks on the creation of SCMI
SystemPower devices.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-8-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Stable-dep-of: 295416091e44 ("firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 141 ++++++++++++++++++++++++++---
drivers/firmware/arm_scmi/common.h | 8 +-
drivers/firmware/arm_scmi/driver.c | 9 +-
include/linux/scmi_protocol.h | 5 -
4 files changed, 141 insertions(+), 22 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 14f96583b6e0d..36f75b6629db0 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -30,6 +31,9 @@ struct scmi_requested_dev {
struct list_head node;
};
+/* Track globally the creation of SCMI SystemPower related devices */
+static atomic_t scmi_syspower_registered = ATOMIC_INIT(0);
+
/**
* scmi_protocol_device_request - Helper to request a device
*
@@ -213,11 +217,11 @@ static int scmi_match_by_id_table(struct device *dev, void *data)
struct scmi_device_id *id_table = data;
return sdev->protocol_id == id_table->protocol_id &&
- !strcmp(sdev->name, id_table->name);
+ (id_table->name && !strcmp(sdev->name, id_table->name));
}
-struct scmi_device *scmi_child_dev_find(struct device *parent,
- int prot_id, const char *name)
+static struct scmi_device *scmi_child_dev_find(struct device *parent,
+ int prot_id, const char *name)
{
struct scmi_device_id id_table;
struct device *dev;
@@ -300,13 +304,53 @@ static void scmi_device_release(struct device *dev)
kfree(to_scmi_dev(dev));
}
-struct scmi_device *
-scmi_device_create(struct device_node *np, struct device *parent, int protocol,
- const char *name)
+static void __scmi_device_destroy(struct scmi_device *scmi_dev)
+{
+ pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
+ of_node_full_name(scmi_dev->dev.parent->of_node),
+ dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
+ scmi_dev->name);
+
+ if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
+ atomic_set(&scmi_syspower_registered, 0);
+
+ kfree_const(scmi_dev->name);
+ ida_free(&scmi_bus_id, scmi_dev->id);
+ device_unregister(&scmi_dev->dev);
+}
+
+static struct scmi_device *
+__scmi_device_create(struct device_node *np, struct device *parent,
+ int protocol, const char *name)
{
int id, retval;
struct scmi_device *scmi_dev;
+ /*
+ * If the same protocol/name device already exist under the same parent
+ * (i.e. SCMI instance) just return the existent device.
+ * This avoids any race between the SCMI driver, creating devices for
+ * each DT defined protocol at probe time, and the concurrent
+ * registration of SCMI drivers.
+ */
+ scmi_dev = scmi_child_dev_find(parent, protocol, name);
+ if (scmi_dev)
+ return scmi_dev;
+
+ /*
+ * Ignore any possible subsequent failures while creating the device
+ * since we are doomed anyway at that point; not using a mutex which
+ * spans across this whole function to keep things simple and to avoid
+ * to serialize all the __scmi_device_create calls across possibly
+ * different SCMI server instances (parent)
+ */
+ if (protocol == SCMI_PROTOCOL_SYSTEM &&
+ atomic_cmpxchg(&scmi_syspower_registered, 0, 1)) {
+ dev_warn(parent,
+ "SCMI SystemPower protocol device must be unique !\n");
+ return NULL;
+ }
+
scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
if (!scmi_dev)
return NULL;
@@ -336,6 +380,10 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol,
if (retval)
goto put_dev;
+ pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n",
+ of_node_full_name(parent->of_node),
+ dev_name(&scmi_dev->dev), protocol, name);
+
return scmi_dev;
put_dev:
kfree_const(scmi_dev->name);
@@ -344,18 +392,85 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol,
return NULL;
}
-void scmi_device_destroy(struct scmi_device *scmi_dev)
+/**
+ * scmi_device_create - A method to create one or more SCMI devices
+ *
+ * @np: A reference to the device node to use for the new device(s)
+ * @parent: The parent device to use identifying a specific SCMI instance
+ * @protocol: The SCMI protocol to be associated with this device
+ * @name: The requested-name of the device to be created; this is optional
+ * and if no @name is provided, all the devices currently known to
+ * be requested on the SCMI bus for @protocol will be created.
+ *
+ * This method can be invoked to create a single well-defined device (like
+ * a transport device or a device requested by an SCMI driver loaded after
+ * the core SCMI stack has been probed), or to create all the devices currently
+ * known to have been requested by the loaded SCMI drivers for a specific
+ * protocol (typically during SCMI core protocol enumeration at probe time).
+ *
+ * Return: The created device (or one of them if @name was NOT provided and
+ * multiple devices were created) or NULL if no device was created;
+ * note that NULL indicates an error ONLY in case a specific @name
+ * was provided: when @name param was not provided, a number of devices
+ * could have been potentially created for a whole protocol, unless no
+ * device was found to have been requested for that specific protocol.
+ */
+struct scmi_device *scmi_device_create(struct device_node *np,
+ struct device *parent, int protocol,
+ const char *name)
{
- kfree_const(scmi_dev->name);
- ida_free(&scmi_bus_id, scmi_dev->id);
- device_unregister(&scmi_dev->dev);
+ struct list_head *phead;
+ struct scmi_requested_dev *rdev;
+ struct scmi_device *scmi_dev = NULL;
+
+ if (name)
+ return __scmi_device_create(np, parent, protocol, name);
+
+ mutex_lock(&scmi_requested_devices_mtx);
+ phead = idr_find(&scmi_requested_devices, protocol);
+ /* Nothing to do. */
+ if (!phead) {
+ mutex_unlock(&scmi_requested_devices_mtx);
+ return scmi_dev;
+ }
+
+ /* Walk the list of requested devices for protocol and create them */
+ list_for_each_entry(rdev, phead, node) {
+ struct scmi_device *sdev;
+
+ sdev = __scmi_device_create(np, parent,
+ rdev->id_table->protocol_id,
+ rdev->id_table->name);
+ /* Report errors and carry on... */
+ if (sdev)
+ scmi_dev = sdev;
+ else
+ pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n",
+ of_node_full_name(parent->of_node),
+ rdev->id_table->protocol_id,
+ rdev->id_table->name);
+ }
+ mutex_unlock(&scmi_requested_devices_mtx);
+
+ return scmi_dev;
}
+EXPORT_SYMBOL_GPL(scmi_device_create);
+
+void scmi_device_destroy(struct device *parent, int protocol, const char *name)
+{
+ struct scmi_device *scmi_dev;
+
+ scmi_dev = scmi_child_dev_find(parent, protocol, name);
+ if (scmi_dev)
+ __scmi_device_destroy(scmi_dev);
+}
+EXPORT_SYMBOL_GPL(scmi_device_destroy);
static int __scmi_devices_unregister(struct device *dev, void *data)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
- scmi_device_destroy(scmi_dev);
+ __scmi_device_destroy(scmi_dev);
return 0;
}
@@ -377,6 +492,10 @@ int __init scmi_bus_init(void)
void __exit scmi_bus_exit(void)
{
+ /*
+ * Destroy all remaining devices: just in case the drivers were
+ * manually unbound and at first and then the modules unloaded.
+ */
scmi_devices_unregister();
bus_unregister(&scmi_bus_type);
ida_destroy(&scmi_bus_id);
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 23f0ab3f2ed7f..a08d8da198be1 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -107,6 +107,11 @@ extern struct bus_type scmi_bus_type;
#define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1
extern struct blocking_notifier_head scmi_requested_devices_nh;
+struct scmi_device *scmi_device_create(struct device_node *np,
+ struct device *parent, int protocol,
+ const char *name);
+void scmi_device_destroy(struct device *parent, int protocol, const char *name);
+
int scmi_protocol_acquire(const struct scmi_handle *handle, u8 protocol_id);
void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
@@ -168,9 +173,6 @@ struct scmi_transport_ops {
bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer);
};
-struct scmi_device *scmi_child_dev_find(struct device *parent,
- int prot_id, const char *name);
-
/**
* struct scmi_desc - Description of SoC integration
*
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index f01097b9e953a..4c3677a205a8f 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2135,6 +2135,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
/* Create a uniquely named, dedicated transport device for this chan */
tdev = scmi_device_create(of_node, info->dev, prot_id, name);
if (!tdev) {
+ dev_err(info->dev,
+ "failed to create transport device (%s)\n", name);
devm_kfree(info->dev, cinfo);
return -EINVAL;
}
@@ -2144,7 +2146,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
if (ret) {
of_node_put(of_node);
- scmi_device_destroy(tdev);
+ scmi_device_destroy(info->dev, prot_id, name);
devm_kfree(info->dev, cinfo);
return ret;
}
@@ -2167,7 +2169,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
/* Destroy channel and device only if created by this call. */
if (tdev) {
of_node_put(of_node);
- scmi_device_destroy(tdev);
+ scmi_device_destroy(info->dev, prot_id, name);
devm_kfree(info->dev, cinfo);
}
return ret;
@@ -2246,10 +2248,11 @@ static int scmi_chan_destroy(int id, void *p, void *idr)
struct scmi_chan_info *cinfo = p;
if (cinfo->dev) {
+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
struct scmi_device *sdev = to_scmi_dev(cinfo->dev);
of_node_put(cinfo->dev->of_node);
- scmi_device_destroy(sdev);
+ scmi_device_destroy(info->dev, id, sdev->name);
cinfo->dev = NULL;
}
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 4f765bc788ffb..0ce5746a4470a 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -804,11 +804,6 @@ struct scmi_device {
#define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
-struct scmi_device *
-scmi_device_create(struct device_node *np, struct device *parent, int protocol,
- const char *name);
-void scmi_device_destroy(struct scmi_device *scmi_dev);
-
struct scmi_device_id {
u8 protocol_id;
const char *name;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0689/1887] firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (687 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0688/1887] firmware: arm_scmi: Refactor device create/destroy helpers Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0690/1887] afs: Fix lock recursion Greg Kroah-Hartman
` (309 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xinqi Zhang, Cristian Marussi,
Bjorn Andersson, Sudeep Holla, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xinqi Zhang <quic_xinqzhan@quicinc.com>
[ Upstream commit 295416091e44806760ccf753aeafdafc0ae268f3 ]
The scmi_dev->name is released prematurely in __scmi_device_destroy(),
which causes slab-use-after-free when accessing scmi_dev->name in
scmi_bus_notifier(). So move the release of scmi_dev->name to
scmi_device_release() to avoid slab-use-after-free.
| BUG: KASAN: slab-use-after-free in strncmp+0xe4/0xec
| Read of size 1 at addr ffffff80a482bcc0 by task swapper/0/1
|
| CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.6.38-debug #1
| Hardware name: Qualcomm Technologies, Inc. SA8775P Ride (DT)
| Call trace:
| dump_backtrace+0x94/0x114
| show_stack+0x18/0x24
| dump_stack_lvl+0x48/0x60
| print_report+0xf4/0x5b0
| kasan_report+0xa4/0xec
| __asan_report_load1_noabort+0x20/0x2c
| strncmp+0xe4/0xec
| scmi_bus_notifier+0x5c/0x54c
| notifier_call_chain+0xb4/0x31c
| blocking_notifier_call_chain+0x68/0x9c
| bus_notify+0x54/0x78
| device_del+0x1bc/0x840
| device_unregister+0x20/0xb4
| __scmi_device_destroy+0xac/0x280
| scmi_device_destroy+0x94/0xd0
| scmi_chan_setup+0x524/0x750
| scmi_probe+0x7fc/0x1508
| platform_probe+0xc4/0x19c
| really_probe+0x32c/0x99c
| __driver_probe_device+0x15c/0x3c4
| driver_probe_device+0x5c/0x170
| __driver_attach+0x1c8/0x440
| bus_for_each_dev+0xf4/0x178
| driver_attach+0x3c/0x58
| bus_add_driver+0x234/0x4d4
| driver_register+0xf4/0x3c0
| __platform_driver_register+0x60/0x88
| scmi_driver_init+0xb0/0x104
| do_one_initcall+0xb4/0x664
| kernel_init_freeable+0x3c8/0x894
| kernel_init+0x24/0x1e8
| ret_from_fork+0x10/0x20
|
| Allocated by task 1:
| kasan_save_stack+0x2c/0x54
| kasan_set_track+0x2c/0x40
| kasan_save_alloc_info+0x24/0x34
| __kasan_kmalloc+0xa0/0xb8
| __kmalloc_node_track_caller+0x6c/0x104
| kstrdup+0x48/0x84
| kstrdup_const+0x34/0x40
| __scmi_device_create.part.0+0x8c/0x408
| scmi_device_create+0x104/0x370
| scmi_chan_setup+0x2a0/0x750
| scmi_probe+0x7fc/0x1508
| platform_probe+0xc4/0x19c
| really_probe+0x32c/0x99c
| __driver_probe_device+0x15c/0x3c4
| driver_probe_device+0x5c/0x170
| __driver_attach+0x1c8/0x440
| bus_for_each_dev+0xf4/0x178
| driver_attach+0x3c/0x58
| bus_add_driver+0x234/0x4d4
| driver_register+0xf4/0x3c0
| __platform_driver_register+0x60/0x88
| scmi_driver_init+0xb0/0x104
| do_one_initcall+0xb4/0x664
| kernel_init_freeable+0x3c8/0x894
| kernel_init+0x24/0x1e8
| ret_from_fork+0x10/0x20
|
| Freed by task 1:
| kasan_save_stack+0x2c/0x54
| kasan_set_track+0x2c/0x40
| kasan_save_free_info+0x38/0x5c
| __kasan_slab_free+0xe8/0x164
| __kmem_cache_free+0x11c/0x230
| kfree+0x70/0x130
| kfree_const+0x20/0x40
| __scmi_device_destroy+0x70/0x280
| scmi_device_destroy+0x94/0xd0
| scmi_chan_setup+0x524/0x750
| scmi_probe+0x7fc/0x1508
| platform_probe+0xc4/0x19c
| really_probe+0x32c/0x99c
| __driver_probe_device+0x15c/0x3c4
| driver_probe_device+0x5c/0x170
| __driver_attach+0x1c8/0x440
| bus_for_each_dev+0xf4/0x178
| driver_attach+0x3c/0x58
| bus_add_driver+0x234/0x4d4
| driver_register+0xf4/0x3c0
| __platform_driver_register+0x60/0x88
| scmi_driver_init+0xb0/0x104
| do_one_initcall+0xb4/0x664
| kernel_init_freeable+0x3c8/0x894
| kernel_init+0x24/0x1e8
| ret_from_fork+0x10/0x20
Fixes: ee7a9c9f67c5 ("firmware: arm_scmi: Add support for multiple device per protocol")
Signed-off-by: Xinqi Zhang <quic_xinqzhan@quicinc.com>
Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Message-Id: <20241016-fix-arm-scmi-slab-use-after-free-v2-1-1783685ef90d@quicinc.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 36f75b6629db0..323e1e48cabde 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -301,7 +301,10 @@ EXPORT_SYMBOL_GPL(scmi_driver_unregister);
static void scmi_device_release(struct device *dev)
{
- kfree(to_scmi_dev(dev));
+ struct scmi_device *scmi_dev = to_scmi_dev(dev);
+
+ kfree_const(scmi_dev->name);
+ kfree(scmi_dev);
}
static void __scmi_device_destroy(struct scmi_device *scmi_dev)
@@ -314,7 +317,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
atomic_set(&scmi_syspower_registered, 0);
- kfree_const(scmi_dev->name);
ida_free(&scmi_bus_id, scmi_dev->id);
device_unregister(&scmi_dev->dev);
}
@@ -386,7 +388,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
return scmi_dev;
put_dev:
- kfree_const(scmi_dev->name);
put_device(&scmi_dev->dev);
ida_free(&scmi_bus_id, id);
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0690/1887] afs: Fix lock recursion
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (688 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0689/1887] firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0691/1887] bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx Greg Kroah-Hartman
` (308 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Marc Dionne,
linux-afs, linux-fsdevel, Christian Brauner, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 610a79ffea02102899a1373fe226d949944a7ed6 ]
afs_wake_up_async_call() can incur lock recursion. The problem is that it
is called from AF_RXRPC whilst holding the ->notify_lock, but it tries to
take a ref on the afs_call struct in order to pass it to a work queue - but
if the afs_call is already queued, we then have an extraneous ref that must
be put... calling afs_put_call() may call back down into AF_RXRPC through
rxrpc_kernel_shutdown_call(), however, which might try taking the
->notify_lock again.
This case isn't very common, however, so defer it to a workqueue. The oops
looks something like:
BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646
lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0
CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351
Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
Call Trace:
<TASK>
dump_stack_lvl+0x47/0x70
do_raw_spin_lock+0x3c/0x90
rxrpc_kernel_shutdown_call+0x83/0xb0
afs_put_call+0xd7/0x180
rxrpc_notify_socket+0xa0/0x190
rxrpc_input_split_jumbo+0x198/0x1d0
rxrpc_input_data+0x14b/0x1e0
? rxrpc_input_call_packet+0xc2/0x1f0
rxrpc_input_call_event+0xad/0x6b0
rxrpc_input_packet_on_conn+0x1e1/0x210
rxrpc_input_packet+0x3f2/0x4d0
rxrpc_io_thread+0x243/0x410
? __pfx_rxrpc_io_thread+0x10/0x10
kthread+0xcf/0xe0
? __pfx_kthread+0x10/0x10
ret_from_fork+0x24/0x40
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/1394602.1729162732@warthog.procyon.org.uk
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/afs/internal.h | 2 ++
fs/afs/rxrpc.c | 79 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 59 insertions(+), 22 deletions(-)
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index fd4310272ccc1..325be1d29a71e 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -99,6 +99,7 @@ struct afs_call {
wait_queue_head_t waitq; /* processes awaiting completion */
struct work_struct async_work; /* async I/O processor */
struct work_struct work; /* actual work processor */
+ struct work_struct free_work; /* Deferred free processor */
struct rxrpc_call *rxcall; /* RxRPC call handle */
struct key *key; /* security for this call */
struct afs_net *net; /* The network namespace */
@@ -1283,6 +1284,7 @@ extern int __net_init afs_open_socket(struct afs_net *);
extern void __net_exit afs_close_socket(struct afs_net *);
extern void afs_charge_preallocation(struct work_struct *);
extern void afs_put_call(struct afs_call *);
+void afs_deferred_put_call(struct afs_call *call);
extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t);
extern long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *);
extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index a0715e5dc38d5..0658523bd7865 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -16,6 +16,7 @@
struct workqueue_struct *afs_async_calls;
+static void afs_deferred_free_worker(struct work_struct *work);
static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
static void afs_process_async_call(struct work_struct *);
@@ -153,6 +154,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
call->debug_id = atomic_inc_return(&rxrpc_debug_id);
refcount_set(&call->ref, 1);
INIT_WORK(&call->async_work, afs_process_async_call);
+ INIT_WORK(&call->free_work, afs_deferred_free_worker);
init_waitqueue_head(&call->waitq);
spin_lock_init(&call->state_lock);
call->iter = &call->def_iter;
@@ -163,6 +165,34 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
return call;
}
+static void afs_free_call(struct afs_call *call)
+{
+ struct afs_net *net = call->net;
+ int o;
+
+ ASSERT(!work_pending(&call->async_work));
+
+ if (call->rxcall) {
+ rxrpc_kernel_end_call(net->socket, call->rxcall);
+ call->rxcall = NULL;
+ }
+ if (call->type->destructor)
+ call->type->destructor(call);
+
+ afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
+ afs_put_addrlist(call->alist);
+ kfree(call->request);
+
+ o = atomic_read(&net->nr_outstanding_calls);
+ trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
+ __builtin_return_address(0));
+ kfree(call);
+
+ o = atomic_dec_return(&net->nr_outstanding_calls);
+ if (o == 0)
+ wake_up_var(&net->nr_outstanding_calls);
+}
+
/*
* Dispose of a reference on a call.
*/
@@ -177,30 +207,34 @@ void afs_put_call(struct afs_call *call)
o = atomic_read(&net->nr_outstanding_calls);
trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
__builtin_return_address(0));
+ if (zero)
+ afs_free_call(call);
+}
- if (zero) {
- ASSERT(!work_pending(&call->async_work));
- ASSERT(call->type->name != NULL);
-
- if (call->rxcall) {
- rxrpc_kernel_end_call(net->socket, call->rxcall);
- call->rxcall = NULL;
- }
- if (call->type->destructor)
- call->type->destructor(call);
+static void afs_deferred_free_worker(struct work_struct *work)
+{
+ struct afs_call *call = container_of(work, struct afs_call, free_work);
- afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
- afs_put_addrlist(call->alist);
- kfree(call->request);
+ afs_free_call(call);
+}
- trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
- __builtin_return_address(0));
- kfree(call);
+/*
+ * Dispose of a reference on a call, deferring the cleanup to a workqueue
+ * to avoid lock recursion.
+ */
+void afs_deferred_put_call(struct afs_call *call)
+{
+ struct afs_net *net = call->net;
+ unsigned int debug_id = call->debug_id;
+ bool zero;
+ int r, o;
- o = atomic_dec_return(&net->nr_outstanding_calls);
- if (o == 0)
- wake_up_var(&net->nr_outstanding_calls);
- }
+ zero = __refcount_dec_and_test(&call->ref, &r);
+ o = atomic_read(&net->nr_outstanding_calls);
+ trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
+ __builtin_return_address(0));
+ if (zero)
+ schedule_work(&call->free_work);
}
static struct afs_call *afs_get_call(struct afs_call *call,
@@ -667,7 +701,8 @@ static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall,
}
/*
- * wake up an asynchronous call
+ * Wake up an asynchronous call. The caller is holding the call notify
+ * spinlock around this, so we can't call afs_put_call().
*/
static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
unsigned long call_user_ID)
@@ -684,7 +719,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
__builtin_return_address(0));
if (!queue_work(afs_async_calls, &call->async_work))
- afs_put_call(call);
+ afs_deferred_put_call(call);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0691/1887] bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (689 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0690/1887] afs: Fix lock recursion Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0692/1887] RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES Greg Kroah-Hartman
` (307 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zijian Zhang, Stanislav Fomichev,
Jakub Kicinski, Cong Wang, Stefano Garzarella, Martin KaFai Lau,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijian Zhang <zijianzhang@bytedance.com>
[ Upstream commit 44d0469f79bd3d0b3433732877358df7dc6b17b1 ]
As the introduction of the support for vsock and unix sockets in sockmap,
tls_sw_has_ctx_tx/rx cannot presume the socket passed in must be IS_ICSK.
vsock and af_unix sockets have vsock_sock and unix_sock instead of
inet_connection_sock. For these sockets, tls_get_ctx may return an invalid
pointer and cause page fault in function tls_sw_ctx_rx.
BUG: unable to handle page fault for address: 0000000000040030
Workqueue: vsock-loopback vsock_loopback_work
RIP: 0010:sk_psock_strp_data_ready+0x23/0x60
Call Trace:
? __die+0x81/0xc3
? no_context+0x194/0x350
? do_page_fault+0x30/0x110
? async_page_fault+0x3e/0x50
? sk_psock_strp_data_ready+0x23/0x60
virtio_transport_recv_pkt+0x750/0x800
? update_load_avg+0x7e/0x620
vsock_loopback_work+0xd0/0x100
process_one_work+0x1a7/0x360
worker_thread+0x30/0x390
? create_worker+0x1a0/0x1a0
kthread+0x112/0x130
? __kthread_cancel_work+0x40/0x40
ret_from_fork+0x1f/0x40
v2:
- Add IS_ICSK check
v3:
- Update the commits in Fixes
Fixes: 634f1a7110b4 ("vsock: support sockmap")
Fixes: 94531cfcbe79 ("af_unix: Add unix_stream_proto for sockmap")
Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Cong Wang <cong.wang@bytedance.com>
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20241106003742.399240-1-zijianzhang@bytedance.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/tls.h | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/net/tls.h b/include/net/tls.h
index b5856a28070da..cd0dfa25c591e 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -405,8 +405,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
{
- struct tls_context *ctx = tls_get_ctx(sk);
+ struct tls_context *ctx;
+
+ if (!sk_is_inet(sk) || !inet_sk(sk)->is_icsk)
+ return false;
+ ctx = tls_get_ctx(sk);
if (!ctx)
return false;
return !!tls_sw_ctx_tx(ctx);
@@ -414,8 +418,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
{
- struct tls_context *ctx = tls_get_ctx(sk);
+ struct tls_context *ctx;
+
+ if (!sk_is_inet(sk) || !inet_sk(sk)->is_icsk)
+ return false;
+ ctx = tls_get_ctx(sk);
if (!ctx)
return false;
return !!tls_sw_ctx_rx(ctx);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0692/1887] RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (690 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0691/1887] bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0693/1887] smb: client: Fix use-after-free of network namespace Greg Kroah-Hartman
` (306 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Showrya M N, Potnuri Bharat Teja,
Jason Gunthorpe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Showrya M N <showrya@chelsio.com>
[ Upstream commit 4e1e3dd88a4cedd5ccc1a3fc3d71e03b70a7a791 ]
While running ISER over SIW, the initiator machine encounters a warning
from skb_splice_from_iter() indicating that a slab page is being used in
send_page. To address this, it is better to add a sendpage_ok() check
within the driver itself, and if it returns 0, then MSG_SPLICE_PAGES flag
should be disabled before entering the network stack.
A similar issue has been discussed for NVMe in this thread:
https://lore.kernel.org/all/20240530142417.146696-1-ofir.gal@volumez.com/
WARNING: CPU: 0 PID: 5342 at net/core/skbuff.c:7140 skb_splice_from_iter+0x173/0x320
Call Trace:
tcp_sendmsg_locked+0x368/0xe40
siw_tx_hdt+0x695/0xa40 [siw]
siw_qp_sq_process+0x102/0xb00 [siw]
siw_sq_resume+0x39/0x110 [siw]
siw_run_sq+0x74/0x160 [siw]
kthread+0xd2/0x100
ret_from_fork+0x34/0x40
ret_from_fork_asm+0x1a/0x30
Link: https://patch.msgid.link/r/20241007125835.89942-1-showrya@chelsio.com
Signed-off-by: Showrya M N <showrya@chelsio.com>
Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/siw/siw_qp_tx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index b98a4100aeebf..1f06a7cb76500 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -338,6 +338,8 @@ static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset,
msg.msg_flags &= ~MSG_MORE;
tcp_rate_check_app_limited(sk);
+ if (!sendpage_ok(page[i]))
+ msg.msg_flags &= ~MSG_SPLICE_PAGES;
bvec_set_page(&bvec, page[i], bytes, offset);
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, bytes);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0693/1887] smb: client: Fix use-after-free of network namespace.
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (691 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0692/1887] RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0694/1887] pmdomain: imx93-blk-ctrl: correct remove path Greg Kroah-Hartman
` (305 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Tom Talpey,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@amazon.com>
[ Upstream commit ef7134c7fc48e1441b398e55a862232868a6f0a7 ]
Recently, we got a customer report that CIFS triggers oops while
reconnecting to a server. [0]
The workload runs on Kubernetes, and some pods mount CIFS servers
in non-root network namespaces. The problem rarely happened, but
it was always while the pod was dying.
The root cause is wrong reference counting for network namespace.
CIFS uses kernel sockets, which do not hold refcnt of the netns that
the socket belongs to. That means CIFS must ensure the socket is
always freed before its netns; otherwise, use-after-free happens.
The repro steps are roughly:
1. mount CIFS in a non-root netns
2. drop packets from the netns
3. destroy the netns
4. unmount CIFS
We can reproduce the issue quickly with the script [1] below and see
the splat [2] if CONFIG_NET_NS_REFCNT_TRACKER is enabled.
When the socket is TCP, it is hard to guarantee the netns lifetime
without holding refcnt due to async timers.
Let's hold netns refcnt for each socket as done for SMC in commit
9744d2bf1976 ("smc: Fix use-after-free in tcp_write_timer_handler().").
Note that we need to move put_net() from cifs_put_tcp_session() to
clean_demultiplex_info(); otherwise, __sock_create() still could touch a
freed netns while cifsd tries to reconnect from cifs_demultiplex_thread().
Also, maybe_get_net() cannot be put just before __sock_create() because
the code is not under RCU and there is a small chance that the same
address happened to be reallocated to another netns.
[0]:
CIFS: VFS: \\XXXXXXXXXXX has not responded in 15 seconds. Reconnecting...
CIFS: Serverclose failed 4 times, giving up
Unable to handle kernel paging request at virtual address 14de99e461f84a07
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
[14de99e461f84a07] address between user and kernel address ranges
Internal error: Oops: 0000000096000004 [#1] SMP
Modules linked in: cls_bpf sch_ingress nls_utf8 cifs cifs_arc4 cifs_md4 dns_resolver tcp_diag inet_diag veth xt_state xt_connmark nf_conntrack_netlink xt_nat xt_statistic xt_MASQUERADE xt_mark xt_addrtype ipt_REJECT nf_reject_ipv4 nft_chain_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_comment nft_compat nf_tables nfnetlink overlay nls_ascii nls_cp437 sunrpc vfat fat aes_ce_blk aes_ce_cipher ghash_ce sm4_ce_cipher sm4 sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 sha1_ce ena button sch_fq_codel loop fuse configfs dmi_sysfs sha2_ce sha256_arm64 dm_mirror dm_region_hash dm_log dm_mod dax efivarfs
CPU: 5 PID: 2690970 Comm: cifsd Not tainted 6.1.103-109.184.amzn2023.aarch64 #1
Hardware name: Amazon EC2 r7g.4xlarge/, BIOS 1.0 11/1/2018
pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : fib_rules_lookup+0x44/0x238
lr : __fib_lookup+0x64/0xbc
sp : ffff8000265db790
x29: ffff8000265db790 x28: 0000000000000000 x27: 000000000000bd01
x26: 0000000000000000 x25: ffff000b4baf8000 x24: ffff00047b5e4580
x23: ffff8000265db7e0 x22: 0000000000000000 x21: ffff00047b5e4500
x20: ffff0010e3f694f8 x19: 14de99e461f849f7 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 0000000000000000 x12: 3f92800abd010002
x11: 0000000000000001 x10: ffff0010e3f69420 x9 : ffff800008a6f294
x8 : 0000000000000000 x7 : 0000000000000006 x6 : 0000000000000000
x5 : 0000000000000001 x4 : ffff001924354280 x3 : ffff8000265db7e0
x2 : 0000000000000000 x1 : ffff0010e3f694f8 x0 : ffff00047b5e4500
Call trace:
fib_rules_lookup+0x44/0x238
__fib_lookup+0x64/0xbc
ip_route_output_key_hash_rcu+0x2c4/0x398
ip_route_output_key_hash+0x60/0x8c
tcp_v4_connect+0x290/0x488
__inet_stream_connect+0x108/0x3d0
inet_stream_connect+0x50/0x78
kernel_connect+0x6c/0xac
generic_ip_connect+0x10c/0x6c8 [cifs]
__reconnect_target_unlocked+0xa0/0x214 [cifs]
reconnect_dfs_server+0x144/0x460 [cifs]
cifs_reconnect+0x88/0x148 [cifs]
cifs_readv_from_socket+0x230/0x430 [cifs]
cifs_read_from_socket+0x74/0xa8 [cifs]
cifs_demultiplex_thread+0xf8/0x704 [cifs]
kthread+0xd0/0xd4
Code: aa0003f8 f8480f13 eb18027f 540006c0 (b9401264)
[1]:
CIFS_CRED="/root/cred.cifs"
CIFS_USER="Administrator"
CIFS_PASS="Password"
CIFS_IP="X.X.X.X"
CIFS_PATH="//${CIFS_IP}/Users/Administrator/Desktop/CIFS_TEST"
CIFS_MNT="/mnt/smb"
DEV="enp0s3"
cat <<EOF > ${CIFS_CRED}
username=${CIFS_USER}
password=${CIFS_PASS}
domain=EXAMPLE.COM
EOF
unshare -n bash -c "
mkdir -p ${CIFS_MNT}
ip netns attach root 1
ip link add eth0 type veth peer veth0 netns root
ip link set eth0 up
ip -n root link set veth0 up
ip addr add 192.168.0.2/24 dev eth0
ip -n root addr add 192.168.0.1/24 dev veth0
ip route add default via 192.168.0.1 dev eth0
ip netns exec root sysctl net.ipv4.ip_forward=1
ip netns exec root iptables -t nat -A POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE
mount -t cifs ${CIFS_PATH} ${CIFS_MNT} -o vers=3.0,sec=ntlmssp,credentials=${CIFS_CRED},rsize=65536,wsize=65536,cache=none,echo_interval=1
touch ${CIFS_MNT}/a.txt
ip netns exec root iptables -t nat -D POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE
"
umount ${CIFS_MNT}
[2]:
ref_tracker: net notrefcnt@000000004bbc008d has 1/1 users at
sk_alloc (./include/net/net_namespace.h:339 net/core/sock.c:2227)
inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252)
__sock_create (net/socket.c:1576)
generic_ip_connect (fs/smb/client/connect.c:3075)
cifs_get_tcp_session.part.0 (fs/smb/client/connect.c:3160 fs/smb/client/connect.c:1798)
cifs_mount_get_session (fs/smb/client/trace.h:959 fs/smb/client/connect.c:3366)
dfs_mount_share (fs/smb/client/dfs.c:63 fs/smb/client/dfs.c:285)
cifs_mount (fs/smb/client/connect.c:3622)
cifs_smb3_do_mount (fs/smb/client/cifsfs.c:949)
smb3_get_tree (fs/smb/client/fs_context.c:784 fs/smb/client/fs_context.c:802 fs/smb/client/fs_context.c:794)
vfs_get_tree (fs/super.c:1800)
path_mount (fs/namespace.c:3508 fs/namespace.c:3834)
__x64_sys_mount (fs/namespace.c:3848 fs/namespace.c:4057 fs/namespace.c:4034 fs/namespace.c:4034)
do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Tom Talpey <tom@talpey.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/connect.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 32c57b040e7cf..1661f6135e417 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1083,6 +1083,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
*/
}
+ put_net(cifs_net_ns(server));
#ifdef CONFIG_CIFS_DFS_UPCALL
kfree(server->origin_fullpath);
kfree(server->leaf_fullpath);
@@ -1677,8 +1678,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
/* srv_count can never go negative */
WARN_ON(server->srv_count < 0);
- put_net(cifs_net_ns(server));
-
list_del_init(&server->tcp_ses_list);
spin_unlock(&cifs_tcp_ses_lock);
@@ -3079,7 +3078,10 @@ generic_ip_connect(struct TCP_Server_Info *server)
}
if (socket == NULL) {
- rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
+ struct net *net = cifs_net_ns(server);
+ struct sock *sk;
+
+ rc = __sock_create(net, sfamily, SOCK_STREAM,
IPPROTO_TCP, &socket, 1);
if (rc < 0) {
cifs_server_dbg(VFS, "Error %d creating socket\n", rc);
@@ -3087,6 +3089,11 @@ generic_ip_connect(struct TCP_Server_Info *server)
return rc;
}
+ sk = socket->sk;
+ sk->sk_net_refcnt = 1;
+ get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
+ sock_inuse_add(net, 1);
+
/* BB other socket options to set KEEPALIVE, NODELAY? */
cifs_dbg(FYI, "Socket created\n");
server->ssocket = socket;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0694/1887] pmdomain: imx93-blk-ctrl: correct remove path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (692 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0693/1887] smb: client: Fix use-after-free of network namespace Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0695/1887] exfat: fix out-of-bounds access of directory entries Greg Kroah-Hartman
` (304 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peng Fan, Stefan Wahren, Ulf Hansson,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <peng.fan@nxp.com>
[ Upstream commit f7c7c5aa556378a2c8da72c1f7f238b6648f95fb ]
The check condition should be 'i < bc->onecell_data.num_domains', not
'bc->onecell_data.num_domains' which will make the look never finish
and cause kernel panic.
Also disable runtime to address
"imx93-blk-ctrl 4ac10000.system-controller: Unbalanced pm_runtime_enable!"
Fixes: e9aa77d413c9 ("soc: imx: add i.MX93 media blk ctrl driver")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
Cc: stable@vger.kernel.org
Message-ID: <20241101101252.1448466-1-peng.fan@oss.nxp.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/imx/imx93-blk-ctrl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/imx/imx93-blk-ctrl.c b/drivers/soc/imx/imx93-blk-ctrl.c
index 2c600329436cf..955e084c9d11b 100644
--- a/drivers/soc/imx/imx93-blk-ctrl.c
+++ b/drivers/soc/imx/imx93-blk-ctrl.c
@@ -298,7 +298,9 @@ static int imx93_blk_ctrl_remove(struct platform_device *pdev)
of_genpd_del_provider(pdev->dev.of_node);
- for (i = 0; bc->onecell_data.num_domains; i++) {
+ pm_runtime_disable(&pdev->dev);
+
+ for (i = 0; i < bc->onecell_data.num_domains; i++) {
struct imx93_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0695/1887] exfat: fix out-of-bounds access of directory entries
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (693 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0694/1887] pmdomain: imx93-blk-ctrl: correct remove path Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0696/1887] sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket Greg Kroah-Hartman
` (303 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuezhang Mo, Namjae Jeon,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <Yuezhang.Mo@sony.com>
[ Upstream commit 184fa506e392eb78364d9283c961217ff2c0617b ]
In the case of the directory size is greater than or equal to
the cluster size, if start_clu becomes an EOF cluster(an invalid
cluster) due to file system corruption, then the directory entry
where ei->hint_femp.eidx hint is outside the directory, resulting
in an out-of-bounds access, which may cause further file system
corruption.
This commit adds a check for start_clu, if it is an invalid cluster,
the file or directory will be treated as empty.
Cc: stable@vger.kernel.org
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Co-developed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/exfat/namei.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index 51743ea617333..ae36930408e6b 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -656,14 +656,19 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
info->type = exfat_get_entry_type(ep);
info->attr = le16_to_cpu(ep->dentry.file.attr);
info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
+
+ info->start_clu = le32_to_cpu(ep2->dentry.stream.start_clu);
+ if (!is_valid_cluster(sbi, info->start_clu) && info->size) {
+ exfat_warn(sb, "start_clu is invalid cluster(0x%x)",
+ info->start_clu);
+ info->size = 0;
+ }
+
if (info->size == 0) {
info->flags = ALLOC_NO_FAT_CHAIN;
info->start_clu = EXFAT_EOF_CLUSTER;
- } else {
+ } else
info->flags = ep2->dentry.stream.flags;
- info->start_clu =
- le32_to_cpu(ep2->dentry.stream.start_clu);
- }
exfat_get_entry_time(sbi, &info->crtime,
ep->dentry.file.create_tz,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0696/1887] sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (694 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0695/1887] exfat: fix out-of-bounds access of directory entries Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0697/1887] smb: Dont leak cfid when reconnect races with open_cached_dir Greg Kroah-Hartman
` (302 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liu Jian, Jeff Layton,
Kuniyuki Iwashima, Trond Myklebust, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <liujian56@huawei.com>
[ Upstream commit 3f23f96528e8fcf8619895c4c916c52653892ec1 ]
BUG: KASAN: slab-use-after-free in tcp_write_timer_handler+0x156/0x3e0
Read of size 1 at addr ffff888111f322cd by task swapper/0/0
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc4-dirty #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1
Call Trace:
<IRQ>
dump_stack_lvl+0x68/0xa0
print_address_description.constprop.0+0x2c/0x3d0
print_report+0xb4/0x270
kasan_report+0xbd/0xf0
tcp_write_timer_handler+0x156/0x3e0
tcp_write_timer+0x66/0x170
call_timer_fn+0xfb/0x1d0
__run_timers+0x3f8/0x480
run_timer_softirq+0x9b/0x100
handle_softirqs+0x153/0x390
__irq_exit_rcu+0x103/0x120
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x76/0x90
</IRQ>
<TASK>
asm_sysvec_apic_timer_interrupt+0x1a/0x20
RIP: 0010:default_idle+0xf/0x20
Code: 4c 01 c7 4c 29 c2 e9 72 ff ff ff 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 f3 0f 1e fa 66 90 0f 00 2d 33 f8 25 00 fb f4 <fa> c3 cc cc cc
cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90
RSP: 0018:ffffffffa2007e28 EFLAGS: 00000242
RAX: 00000000000f3b31 RBX: 1ffffffff4400fc7 RCX: ffffffffa09c3196
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff9f00590f
RBP: 0000000000000000 R08: 0000000000000001 R09: ffffed102360835d
R10: ffff88811b041aeb R11: 0000000000000001 R12: 0000000000000000
R13: ffffffffa202d7c0 R14: 0000000000000000 R15: 00000000000147d0
default_idle_call+0x6b/0xa0
cpuidle_idle_call+0x1af/0x1f0
do_idle+0xbc/0x130
cpu_startup_entry+0x33/0x40
rest_init+0x11f/0x210
start_kernel+0x39a/0x420
x86_64_start_reservations+0x18/0x30
x86_64_start_kernel+0x97/0xa0
common_startup_64+0x13e/0x141
</TASK>
Allocated by task 595:
kasan_save_stack+0x24/0x50
kasan_save_track+0x14/0x30
__kasan_slab_alloc+0x87/0x90
kmem_cache_alloc_noprof+0x12b/0x3f0
copy_net_ns+0x94/0x380
create_new_namespaces+0x24c/0x500
unshare_nsproxy_namespaces+0x75/0xf0
ksys_unshare+0x24e/0x4f0
__x64_sys_unshare+0x1f/0x30
do_syscall_64+0x70/0x180
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Freed by task 100:
kasan_save_stack+0x24/0x50
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x54/0x70
kmem_cache_free+0x156/0x5d0
cleanup_net+0x5d3/0x670
process_one_work+0x776/0xa90
worker_thread+0x2e2/0x560
kthread+0x1a8/0x1f0
ret_from_fork+0x34/0x60
ret_from_fork_asm+0x1a/0x30
Reproduction script:
mkdir -p /mnt/nfsshare
mkdir -p /mnt/nfs/netns_1
mkfs.ext4 /dev/sdb
mount /dev/sdb /mnt/nfsshare
systemctl restart nfs-server
chmod 777 /mnt/nfsshare
exportfs -i -o rw,no_root_squash *:/mnt/nfsshare
ip netns add netns_1
ip link add name veth_1_peer type veth peer veth_1
ifconfig veth_1_peer 11.11.0.254 up
ip link set veth_1 netns netns_1
ip netns exec netns_1 ifconfig veth_1 11.11.0.1
ip netns exec netns_1 /root/iptables -A OUTPUT -d 11.11.0.254 -p tcp \
--tcp-flags FIN FIN -j DROP
(note: In my environment, a DESTROY_CLIENTID operation is always sent
immediately, breaking the nfs tcp connection.)
ip netns exec netns_1 timeout -s 9 300 mount -t nfs -o proto=tcp,vers=4.1 \
11.11.0.254:/mnt/nfsshare /mnt/nfs/netns_1
ip netns del netns_1
The reason here is that the tcp socket in netns_1 (nfs side) has been
shutdown and closed (done in xs_destroy), but the FIN message (with ack)
is discarded, and the nfsd side keeps sending retransmission messages.
As a result, when the tcp sock in netns_1 processes the received message,
it sends the message (FIN message) in the sending queue, and the tcp timer
is re-established. When the network namespace is deleted, the net structure
accessed by tcp's timer handler function causes problems.
To fix this problem, let's hold netns refcnt for the tcp kernel socket as
done in other modules. This is an ugly hack which can easily be backported
to earlier kernels. A proper fix which cleans up the interfaces will
follow, but may not be so easy to backport.
Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
Signed-off-by: Liu Jian <liujian56@huawei.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/svcsock.c | 3 +++
net/sunrpc/xprtsock.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 23b4c728de598..69d40d0980cf0 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1457,6 +1457,9 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
newlen = error;
if (protocol == IPPROTO_TCP) {
+ sock->sk->sk_net_refcnt = 1;
+ get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL);
+ sock_inuse_add(net, 1);
if ((error = kernel_listen(sock, 64)) < 0)
goto bummer;
}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b9dc8e197dde8..74689050038a2 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1855,6 +1855,12 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt,
goto out;
}
+ if (protocol == IPPROTO_TCP) {
+ sock->sk->sk_net_refcnt = 1;
+ get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL);
+ sock_inuse_add(xprt->xprt_net, 1);
+ }
+
filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
if (IS_ERR(filp))
return ERR_CAST(filp);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0697/1887] smb: Dont leak cfid when reconnect races with open_cached_dir
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (695 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0696/1887] sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0698/1887] smb: client: stop flooding dmesg in smb2_calc_signature() Greg Kroah-Hartman
` (301 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Paul Aurich, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <paul@darkrain42.org>
[ Upstream commit 7afb86733685c64c604d32faf00fa4a1f22c2ab1 ]
open_cached_dir() may either race with the tcon reconnection even before
compound_send_recv() or directly trigger a reconnection via
SMB2_open_init() or SMB_query_info_init().
The reconnection process invokes invalidate_all_cached_dirs() via
cifs_mark_open_files_invalid(), which removes all cfids from the
cfids->entries list but doesn't drop a ref if has_lease isn't true. This
results in the currently-being-constructed cfid not being on the list,
but still having a refcount of 2. It leaks if returned from
open_cached_dir().
Fix this by setting cfid->has_lease when the ref is actually taken; the
cfid will not be used by other threads until it has a valid time.
Addresses these kmemleaks:
unreferenced object 0xffff8881090c4000 (size 1024):
comm "bash", pid 1860, jiffies 4295126592
hex dump (first 32 bytes):
00 01 00 00 00 00 ad de 22 01 00 00 00 00 ad de ........".......
00 ca 45 22 81 88 ff ff f8 dc 4f 04 81 88 ff ff ..E"......O.....
backtrace (crc 6f58c20f):
[<ffffffff8b895a1e>] __kmalloc_cache_noprof+0x2be/0x350
[<ffffffff8bda06e3>] open_cached_dir+0x993/0x1fb0
[<ffffffff8bdaa750>] cifs_readdir+0x15a0/0x1d50
[<ffffffff8b9a853f>] iterate_dir+0x28f/0x4b0
[<ffffffff8b9a9aed>] __x64_sys_getdents64+0xfd/0x200
[<ffffffff8cf6da05>] do_syscall_64+0x95/0x1a0
[<ffffffff8d00012f>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
unreferenced object 0xffff8881044fdcf8 (size 8):
comm "bash", pid 1860, jiffies 4295126592
hex dump (first 8 bytes):
00 cc cc cc cc cc cc cc ........
backtrace (crc 10c106a9):
[<ffffffff8b89a3d3>] __kmalloc_node_track_caller_noprof+0x363/0x480
[<ffffffff8b7d7256>] kstrdup+0x36/0x60
[<ffffffff8bda0700>] open_cached_dir+0x9b0/0x1fb0
[<ffffffff8bdaa750>] cifs_readdir+0x15a0/0x1d50
[<ffffffff8b9a853f>] iterate_dir+0x28f/0x4b0
[<ffffffff8b9a9aed>] __x64_sys_getdents64+0xfd/0x200
[<ffffffff8cf6da05>] do_syscall_64+0x95/0x1a0
[<ffffffff8d00012f>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
And addresses these BUG splats when unmounting the SMB filesystem:
BUG: Dentry ffff888140590ba0{i=1000000000080,n=/} still in use (2) [unmount of cifs cifs]
WARNING: CPU: 3 PID: 3433 at fs/dcache.c:1536 umount_check+0xd0/0x100
Modules linked in:
CPU: 3 UID: 0 PID: 3433 Comm: bash Not tainted 6.12.0-rc4-g850925a8133c-dirty #49
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
RIP: 0010:umount_check+0xd0/0x100
Code: 8d 7c 24 40 e8 31 5a f4 ff 49 8b 54 24 40 41 56 49 89 e9 45 89 e8 48 89 d9 41 57 48 89 de 48 c7 c7 80 e7 db ac e8 f0 72 9a ff <0f> 0b 58 31 c0 5a 5b 5d 41 5c 41 5d 41 5e 41 5f e9 2b e5 5d 01 41
RSP: 0018:ffff88811cc27978 EFLAGS: 00010286
RAX: 0000000000000000 RBX: ffff888140590ba0 RCX: ffffffffaaf20bae
RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff8881f6fb6f40
RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed1023984ee3
R10: ffff88811cc2771f R11: 00000000016cfcc0 R12: ffff888134383e08
R13: 0000000000000002 R14: ffff8881462ec668 R15: ffffffffaceab4c0
FS: 00007f23bfa98740(0000) GS:ffff8881f6f80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000556de4a6f808 CR3: 0000000123c80000 CR4: 0000000000350ef0
Call Trace:
<TASK>
d_walk+0x6a/0x530
shrink_dcache_for_umount+0x6a/0x200
generic_shutdown_super+0x52/0x2a0
kill_anon_super+0x22/0x40
cifs_kill_sb+0x159/0x1e0
deactivate_locked_super+0x66/0xe0
cleanup_mnt+0x140/0x210
task_work_run+0xfb/0x170
syscall_exit_to_user_mode+0x29f/0x2b0
do_syscall_64+0xa1/0x1a0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f23bfb93ae7
Code: ff ff ff ff c3 66 0f 1f 44 00 00 48 8b 0d 11 93 0d 00 f7 d8 64 89 01 b8 ff ff ff ff eb bf 0f 1f 44 00 00 b8 50 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e9 92 0d 00 f7 d8 64 89 01 48
RSP: 002b:00007ffee9138598 EFLAGS: 00000246 ORIG_RAX: 0000000000000050
RAX: 0000000000000000 RBX: 0000558f1803e9a0 RCX: 00007f23bfb93ae7
RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000558f1803e9a0
RBP: 0000558f1803e600 R08: 0000000000000007 R09: 0000558f17fab610
R10: d91d5ec34ab757b0 R11: 0000000000000246 R12: 0000000000000001
R13: 0000000000000000 R14: 0000000000000015 R15: 0000000000000000
</TASK>
irq event stamp: 1163486
hardirqs last enabled at (1163485): [<ffffffffac98d344>] _raw_spin_unlock_irqrestore+0x34/0x60
hardirqs last disabled at (1163486): [<ffffffffac97dcfc>] __schedule+0xc7c/0x19a0
softirqs last enabled at (1163482): [<ffffffffab79a3ee>] __smb_send_rqst+0x3de/0x990
softirqs last disabled at (1163480): [<ffffffffac2314f1>] release_sock+0x21/0xf0
---[ end trace 0000000000000000 ]---
VFS: Busy inodes after unmount of cifs (cifs)
------------[ cut here ]------------
kernel BUG at fs/super.c:661!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 3433 Comm: bash Tainted: G W 6.12.0-rc4-g850925a8133c-dirty #49
Tainted: [W]=WARN
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
RIP: 0010:generic_shutdown_super+0x290/0x2a0
Code: e8 15 7c f7 ff 48 8b 5d 28 48 89 df e8 09 7c f7 ff 48 8b 0b 48 89 ee 48 8d 95 68 06 00 00 48 c7 c7 80 7f db ac e8 00 69 af ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90
RSP: 0018:ffff88811cc27a50 EFLAGS: 00010246
RAX: 000000000000003e RBX: ffffffffae994420 RCX: 0000000000000027
RDX: 0000000000000000 RSI: ffffffffab06180e RDI: ffff8881f6eb18c8
RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed103edd6319
R10: ffff8881f6eb18cb R11: 00000000016d3158 R12: ffff8881462ec9c0
R13: ffff8881462ec050 R14: 0000000000000001 R15: 0000000000000000
FS: 00007f23bfa98740(0000) GS:ffff8881f6e80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f8364005d68 CR3: 0000000123c80000 CR4: 0000000000350ef0
Call Trace:
<TASK>
kill_anon_super+0x22/0x40
cifs_kill_sb+0x159/0x1e0
deactivate_locked_super+0x66/0xe0
cleanup_mnt+0x140/0x210
task_work_run+0xfb/0x170
syscall_exit_to_user_mode+0x29f/0x2b0
do_syscall_64+0xa1/0x1a0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f23bfb93ae7
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:generic_shutdown_super+0x290/0x2a0
Code: e8 15 7c f7 ff 48 8b 5d 28 48 89 df e8 09 7c f7 ff 48 8b 0b 48 89 ee 48 8d 95 68 06 00 00 48 c7 c7 80 7f db ac e8 00 69 af ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90
RSP: 0018:ffff88811cc27a50 EFLAGS: 00010246
RAX: 000000000000003e RBX: ffffffffae994420 RCX: 0000000000000027
RDX: 0000000000000000 RSI: ffffffffab06180e RDI: ffff8881f6eb18c8
RBP: ffff8881462ec000 R08: 0000000000000001 R09: ffffed103edd6319
R10: ffff8881f6eb18cb R11: 00000000016d3158 R12: ffff8881462ec9c0
R13: ffff8881462ec050 R14: 0000000000000001 R15: 0000000000000000
FS: 00007f23bfa98740(0000) GS:ffff8881f6e80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f8364005d68 CR3: 0000000123c80000 CR4: 0000000000350ef0
This reproduces eventually with an SMB mount and two shells running
these loops concurrently
- while true; do
cd ~; sleep 1;
for i in {1..3}; do cd /mnt/test/subdir;
echo $PWD; sleep 1; cd ..; echo $PWD; sleep 1;
done;
echo ...;
done
- while true; do
iptables -F OUTPUT; mount -t cifs -a;
for _ in {0..2}; do ls /mnt/test/subdir/ | wc -l; done;
iptables -I OUTPUT -p tcp --dport 445 -j DROP;
sleep 10
echo "unmounting"; umount -l -t cifs -a; echo "done unmounting";
sleep 20
echo "recovering"; iptables -F OUTPUT;
sleep 10;
done
Fixes: ebe98f1447bb ("cifs: enable caching of directories for which a lease is held")
Fixes: 5c86919455c1 ("smb: client: fix use-after-free in smb2_query_info_compound()")
Cc: stable@vger.kernel.org
Signed-off-by: Paul Aurich <paul@darkrain42.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cached_dir.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index bac6ceccaaa9c..194cf24f52df9 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -57,6 +57,16 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
list_add(&cfid->entry, &cfids->entries);
cfid->on_list = true;
kref_get(&cfid->refcount);
+ /*
+ * Set @cfid->has_lease to true during construction so that the lease
+ * reference can be put in cached_dir_lease_break() due to a potential
+ * lease break right after the request is sent or while @cfid is still
+ * being cached, or if a reconnection is triggered during construction.
+ * Concurrent processes won't be to use it yet due to @cfid->time being
+ * zero.
+ */
+ cfid->has_lease = true;
+
spin_unlock(&cfids->cfid_list_lock);
return cfid;
}
@@ -168,11 +178,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
return -ENOENT;
}
/*
- * At this point we either have a lease already and we can just
- * return it. If not we are guaranteed to be the only thread accessing
- * this cfid.
+ * Return cached fid if it is valid (has a lease and has a time).
+ * Otherwise, it is either a new entry or laundromat worker removed it
+ * from @cfids->entries. Caller will put last reference if the latter.
*/
- if (cfid->has_lease) {
+ if (cfid->has_lease && cfid->time) {
*ret_cfid = cfid;
kfree(utf16_path);
return 0;
@@ -263,15 +273,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
smb2_set_related(&rqst[1]);
- /*
- * Set @cfid->has_lease to true before sending out compounded request so
- * its lease reference can be put in cached_dir_lease_break() due to a
- * potential lease break right after the request is sent or while @cfid
- * is still being cached. Concurrent processes won't be to use it yet
- * due to @cfid->time being zero.
- */
- cfid->has_lease = true;
-
rc = compound_send_recv(xid, ses, server,
flags, 2, rqst,
resp_buftype, rsp_iov);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0698/1887] smb: client: stop flooding dmesg in smb2_calc_signature()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (696 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0697/1887] smb: Dont leak cfid when reconnect races with open_cached_dir Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0699/1887] smb: client: fix use-after-free of signing key Greg Kroah-Hartman
` (300 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulo Alcantara (Red Hat),
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.com>
[ Upstream commit a13ca780afab350f37f8be9eda2bf79d1aed9bdd ]
When having several mounts that share same credential and the client
couldn't re-establish an SMB session due to an expired kerberos ticket
or rotated password, smb2_calc_signature() will end up flooding dmesg
when not finding SMB sessions to calculate signatures.
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: 343d7fe6df9e ("smb: client: fix use-after-free of signing key")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2transport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 3a69f3500acde..e72c6933788e8 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -242,7 +242,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
if (unlikely(!ses)) {
- cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
+ cifs_server_dbg(FYI, "%s: Could not find session\n", __func__);
return -ENOENT;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0699/1887] smb: client: fix use-after-free of signing key
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (697 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0698/1887] smb: client: stop flooding dmesg in smb2_calc_signature() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0700/1887] io_uring: check for overflows in io_pin_pages Greg Kroah-Hartman
` (299 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jay Shin, Paulo Alcantara (Red Hat),
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.com>
[ Upstream commit 343d7fe6df9e247671440a932b6a73af4fa86d95 ]
Customers have reported use-after-free in @ses->auth_key.response with
SMB2.1 + sign mounts which occurs due to following race:
task A task B
cifs_mount()
dfs_mount_share()
get_session()
cifs_mount_get_session() cifs_send_recv()
cifs_get_smb_ses() compound_send_recv()
cifs_setup_session() smb2_setup_request()
kfree_sensitive() smb2_calc_signature()
crypto_shash_setkey() *UAF*
Fix this by ensuring that we have a valid @ses->auth_key.response by
checking whether @ses->ses_status is SES_GOOD or SES_EXITING with
@ses->ses_lock held. After commit 24a9799aa8ef ("smb: client: fix UAF
in smb2_reconnect_server()"), we made sure to call ->logoff() only
when @ses was known to be good (e.g. valid ->auth_key.response), so
it's safe to access signing key when @ses->ses_status == SES_EXITING.
Cc: stable@vger.kernel.org
Reported-by: Jay Shin <jaeshin@redhat.com>
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2proto.h | 2 --
fs/smb/client/smb2transport.c | 56 +++++++++++++++++++++++++----------
2 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 2897fb6f5397e..e166f49bdf696 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -37,8 +37,6 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
struct smb_rqst *rqst);
extern struct mid_q_entry *smb2_setup_async_request(
struct TCP_Server_Info *server, struct smb_rqst *rqst);
-extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
- __u64 ses_id);
extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
__u64 ses_id, __u32 tid);
extern int smb2_calc_signature(struct smb_rqst *rqst,
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index e72c6933788e8..f709bc3424dd8 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -75,7 +75,7 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
static
-int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
+int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
{
struct cifs_chan *chan;
struct TCP_Server_Info *pserver;
@@ -168,16 +168,41 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
return NULL;
}
-struct cifs_ses *
-smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
+static int smb2_get_sign_key(struct TCP_Server_Info *server,
+ __u64 ses_id, u8 *key)
{
struct cifs_ses *ses;
+ int rc = -ENOENT;
+
+ if (CIFS_SERVER_IS_CHAN(server))
+ server = server->primary_server;
spin_lock(&cifs_tcp_ses_lock);
- ses = smb2_find_smb_ses_unlocked(server, ses_id);
- spin_unlock(&cifs_tcp_ses_lock);
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ if (ses->Suid != ses_id)
+ continue;
- return ses;
+ rc = 0;
+ spin_lock(&ses->ses_lock);
+ switch (ses->ses_status) {
+ case SES_EXITING: /* SMB2_LOGOFF */
+ case SES_GOOD:
+ if (likely(ses->auth_key.response)) {
+ memcpy(key, ses->auth_key.response,
+ SMB2_NTLMV2_SESSKEY_SIZE);
+ } else {
+ rc = -EIO;
+ }
+ break;
+ default:
+ rc = -EAGAIN;
+ break;
+ }
+ spin_unlock(&ses->ses_lock);
+ break;
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+ return rc;
}
static struct cifs_tcon *
@@ -236,14 +261,16 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
unsigned char *sigptr = smb2_signature;
struct kvec *iov = rqst->rq_iov;
struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
- struct cifs_ses *ses;
struct shash_desc *shash = NULL;
struct smb_rqst drqst;
+ __u64 sid = le64_to_cpu(shdr->SessionId);
+ u8 key[SMB2_NTLMV2_SESSKEY_SIZE];
- ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
- if (unlikely(!ses)) {
- cifs_server_dbg(FYI, "%s: Could not find session\n", __func__);
- return -ENOENT;
+ rc = smb2_get_sign_key(server, sid, key);
+ if (unlikely(rc)) {
+ cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n",
+ __func__, sid, rc);
+ return rc;
}
memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
@@ -260,8 +287,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
shash = server->secmech.hmacsha256;
}
- rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response,
- SMB2_NTLMV2_SESSKEY_SIZE);
+ rc = crypto_shash_setkey(shash->tfm, key, sizeof(key));
if (rc) {
cifs_server_dbg(VFS,
"%s: Could not update with response\n",
@@ -303,8 +329,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
out:
if (allocate_crypto)
cifs_free_hash(&shash);
- if (ses)
- cifs_put_smb_ses(ses);
return rc;
}
@@ -582,7 +606,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
struct smb_rqst drqst;
u8 key[SMB3_SIGN_KEY_SIZE];
- rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+ rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
if (unlikely(rc)) {
cifs_server_dbg(VFS, "%s: Could not get signing key\n", __func__);
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0700/1887] io_uring: check for overflows in io_pin_pages
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (698 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0699/1887] smb: client: fix use-after-free of signing key Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0701/1887] KVM: arm64: Get rid of userspace_irqchip_in_use Greg Kroah-Hartman
` (298 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2159cbb522b02847c053,
Pavel Begunkov, Jens Axboe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <asml.silence@gmail.com>
[ Upstream commit 0c0a4eae26ac78379d0c1db053de168a8febc6c9 ]
WARNING: CPU: 0 PID: 5834 at io_uring/memmap.c:144 io_pin_pages+0x149/0x180 io_uring/memmap.c:144
CPU: 0 UID: 0 PID: 5834 Comm: syz-executor825 Not tainted 6.12.0-next-20241118-syzkaller #0
Call Trace:
<TASK>
__io_uaddr_map+0xfb/0x2d0 io_uring/memmap.c:183
io_rings_map io_uring/io_uring.c:2611 [inline]
io_allocate_scq_urings+0x1c0/0x650 io_uring/io_uring.c:3470
io_uring_create+0x5b5/0xc00 io_uring/io_uring.c:3692
io_uring_setup io_uring/io_uring.c:3781 [inline]
...
</TASK>
io_pin_pages()'s uaddr parameter came directly from the user and can be
garbage. Don't just add size to it as it can overflow.
Cc: stable@vger.kernel.org
Reported-by: syzbot+2159cbb522b02847c053@syzkaller.appspotmail.com
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/1b7520ddb168e1d537d64be47414a0629d0d8f8f.1732581026.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/rsrc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index ac658cfa89c63..1c5abe2dcd5e3 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -983,7 +983,12 @@ struct page **io_pin_pages(unsigned long ubuf, unsigned long len, int *npages)
struct page **pages = NULL;
int i, pret, ret = -ENOMEM;
- end = (ubuf + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (check_add_overflow(ubuf, len, &end))
+ return ERR_PTR(-EOVERFLOW);
+ if (check_add_overflow(end, PAGE_SIZE - 1, &end))
+ return ERR_PTR(-EOVERFLOW);
+
+ end = end >> PAGE_SHIFT;
start = ubuf >> PAGE_SHIFT;
nr_pages = end - start;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0701/1887] KVM: arm64: Get rid of userspace_irqchip_in_use
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (699 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0700/1887] io_uring: check for overflows in io_pin_pages Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0702/1887] nfsd: release svc_expkey/svc_export with rcu_work Greg Kroah-Hartman
` (297 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot, Marc Zyngier,
Raghavendra Rao Ananta, Oliver Upton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raghavendra Rao Ananta <rananta@google.com>
[ Upstream commit 38d7aacca09230fdb98a34194fec2af597e8e20d ]
Improper use of userspace_irqchip_in_use led to syzbot hitting the
following WARN_ON() in kvm_timer_update_irq():
WARNING: CPU: 0 PID: 3281 at arch/arm64/kvm/arch_timer.c:459
kvm_timer_update_irq+0x21c/0x394
Call trace:
kvm_timer_update_irq+0x21c/0x394 arch/arm64/kvm/arch_timer.c:459
kvm_timer_vcpu_reset+0x158/0x684 arch/arm64/kvm/arch_timer.c:968
kvm_reset_vcpu+0x3b4/0x560 arch/arm64/kvm/reset.c:264
kvm_vcpu_set_target arch/arm64/kvm/arm.c:1553 [inline]
kvm_arch_vcpu_ioctl_vcpu_init arch/arm64/kvm/arm.c:1573 [inline]
kvm_arch_vcpu_ioctl+0x112c/0x1b3c arch/arm64/kvm/arm.c:1695
kvm_vcpu_ioctl+0x4ec/0xf74 virt/kvm/kvm_main.c:4658
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl fs/ioctl.c:893 [inline]
__arm64_sys_ioctl+0x108/0x184 fs/ioctl.c:893
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x78/0x1b8 arch/arm64/kernel/syscall.c:49
el0_svc_common+0xe8/0x1b0 arch/arm64/kernel/syscall.c:132
do_el0_svc+0x40/0x50 arch/arm64/kernel/syscall.c:151
el0_svc+0x54/0x14c arch/arm64/kernel/entry-common.c:712
el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730
el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
The following sequence led to the scenario:
- Userspace creates a VM and a vCPU.
- The vCPU is initialized with KVM_ARM_VCPU_PMU_V3 during
KVM_ARM_VCPU_INIT.
- Without any other setup, such as vGIC or vPMU, userspace issues
KVM_RUN on the vCPU. Since the vPMU is requested, but not setup,
kvm_arm_pmu_v3_enable() fails in kvm_arch_vcpu_run_pid_change().
As a result, KVM_RUN returns after enabling the timer, but before
incrementing 'userspace_irqchip_in_use':
kvm_arch_vcpu_run_pid_change()
ret = kvm_arm_pmu_v3_enable()
if (!vcpu->arch.pmu.created)
return -EINVAL;
if (ret)
return ret;
[...]
if (!irqchip_in_kernel(kvm))
static_branch_inc(&userspace_irqchip_in_use);
- Userspace ignores the error and issues KVM_ARM_VCPU_INIT again.
Since the timer is already enabled, control moves through the
following flow, ultimately hitting the WARN_ON():
kvm_timer_vcpu_reset()
if (timer->enabled)
kvm_timer_update_irq()
if (!userspace_irqchip())
ret = kvm_vgic_inject_irq()
ret = vgic_lazy_init()
if (unlikely(!vgic_initialized(kvm)))
if (kvm->arch.vgic.vgic_model !=
KVM_DEV_TYPE_ARM_VGIC_V2)
return -EBUSY;
WARN_ON(ret);
Theoretically, since userspace_irqchip_in_use's functionality can be
simply replaced by '!irqchip_in_kernel()', get rid of the static key
to avoid the mismanagement, which also helps with the syzbot issue.
Cc: <stable@vger.kernel.org>
Reported-by: syzbot <syzkaller@googlegroups.com>
Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 2 --
arch/arm64/kvm/arch_timer.c | 3 +--
arch/arm64/kvm/arm.c | 18 +++---------------
3 files changed, 4 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0935f98495104..f57f02a52a84d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -64,8 +64,6 @@ enum kvm_mode {
};
enum kvm_mode kvm_get_mode(void);
-DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
-
extern unsigned int kvm_sve_max_vl;
extern unsigned int kvm_host_sve_max_vl;
int kvm_arm_init_sve(void);
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index bb24a76b4224b..52df63aa73a13 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -161,8 +161,7 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
static inline bool userspace_irqchip(struct kvm *kvm)
{
- return static_branch_unlikely(&userspace_irqchip_in_use) &&
- unlikely(!irqchip_in_kernel(kvm));
+ return unlikely(!irqchip_in_kernel(kvm));
}
static void soft_timer_start(struct hrtimer *hrt, u64 ns)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b589ed95c89e6..4ef70acabb9e3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -56,7 +56,6 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
static bool vgic_present;
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
-DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
{
@@ -384,9 +383,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
{
- if (vcpu_has_run_once(vcpu) && unlikely(!irqchip_in_kernel(vcpu->kvm)))
- static_branch_dec(&userspace_irqchip_in_use);
-
kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
kvm_timer_vcpu_terminate(vcpu);
kvm_pmu_vcpu_destroy(vcpu);
@@ -609,14 +605,6 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
if (ret)
return ret;
- if (!irqchip_in_kernel(kvm)) {
- /*
- * Tell the rest of the code that there are userspace irqchip
- * VMs in the wild.
- */
- static_branch_inc(&userspace_irqchip_in_use);
- }
-
/*
* Initialize traps for protected VMs.
* NOTE: Move to run in EL2 directly, rather than via a hypercall, once
@@ -829,7 +817,7 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
* state gets updated in kvm_timer_update_run and
* kvm_pmu_update_run below).
*/
- if (static_branch_unlikely(&userspace_irqchip_in_use)) {
+ if (unlikely(!irqchip_in_kernel(vcpu->kvm))) {
if (kvm_timer_should_notify_user(vcpu) ||
kvm_pmu_should_notify_user(vcpu)) {
*ret = -EINTR;
@@ -948,7 +936,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
vcpu->mode = OUTSIDE_GUEST_MODE;
isb(); /* Ensure work in x_flush_hwstate is committed */
kvm_pmu_sync_hwstate(vcpu);
- if (static_branch_unlikely(&userspace_irqchip_in_use))
+ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
kvm_timer_sync_user(vcpu);
kvm_vgic_sync_hwstate(vcpu);
local_irq_enable();
@@ -994,7 +982,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* we don't want vtimer interrupts to race with syncing the
* timer virtual interrupt state.
*/
- if (static_branch_unlikely(&userspace_irqchip_in_use))
+ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
kvm_timer_sync_user(vcpu);
kvm_arch_vcpu_ctxsync_fp(vcpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0702/1887] nfsd: release svc_expkey/svc_export with rcu_work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (700 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0701/1887] KVM: arm64: Get rid of userspace_irqchip_in_use Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0703/1887] RDMA/mlx5: Move events notifier registration to be after device registration Greg Kroah-Hartman
` (296 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yang Erkun, Jeff Layton, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <yangerkun@huawei.com>
[ Upstream commit f8c989a0c89a75d30f899a7cabdc14d72522bb8d ]
The last reference for `cache_head` can be reduced to zero in `c_show`
and `e_show`(using `rcu_read_lock` and `rcu_read_unlock`). Consequently,
`svc_export_put` and `expkey_put` will be invoked, leading to two
issues:
1. The `svc_export_put` will directly free ex_uuid. However,
`e_show`/`c_show` will access `ex_uuid` after `cache_put`, which can
trigger a use-after-free issue, shown below.
==================================================================
BUG: KASAN: slab-use-after-free in svc_export_show+0x362/0x430 [nfsd]
Read of size 1 at addr ff11000010fdc120 by task cat/870
CPU: 1 UID: 0 PID: 870 Comm: cat Not tainted 6.12.0-rc3+ #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.16.1-2.fc37 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
print_address_description.constprop.0+0x2c/0x3a0
print_report+0xb9/0x280
kasan_report+0xae/0xe0
svc_export_show+0x362/0x430 [nfsd]
c_show+0x161/0x390 [sunrpc]
seq_read_iter+0x589/0x770
seq_read+0x1e5/0x270
proc_reg_read+0xe1/0x140
vfs_read+0x125/0x530
ksys_read+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Allocated by task 830:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
__kmalloc_node_track_caller_noprof+0x1bc/0x400
kmemdup_noprof+0x22/0x50
svc_export_parse+0x8a9/0xb80 [nfsd]
cache_do_downcall+0x71/0xa0 [sunrpc]
cache_write_procfs+0x8e/0xd0 [sunrpc]
proc_reg_write+0xe1/0x140
vfs_write+0x1a5/0x6d0
ksys_write+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Freed by task 868:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x37/0x50
kfree+0xf3/0x3e0
svc_export_put+0x87/0xb0 [nfsd]
cache_purge+0x17f/0x1f0 [sunrpc]
nfsd_destroy_serv+0x226/0x2d0 [nfsd]
nfsd_svc+0x125/0x1e0 [nfsd]
write_threads+0x16a/0x2a0 [nfsd]
nfsctl_transaction_write+0x74/0xa0 [nfsd]
vfs_write+0x1a5/0x6d0
ksys_write+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e
2. We cannot sleep while using `rcu_read_lock`/`rcu_read_unlock`.
However, `svc_export_put`/`expkey_put` will call path_put, which
subsequently triggers a sleeping operation due to the following
`dput`.
=============================
WARNING: suspicious RCU usage
5.10.0-dirty #141 Not tainted
-----------------------------
...
Call Trace:
dump_stack+0x9a/0xd0
___might_sleep+0x231/0x240
dput+0x39/0x600
path_put+0x1b/0x30
svc_export_put+0x17/0x80
e_show+0x1c9/0x200
seq_read_iter+0x63f/0x7c0
seq_read+0x226/0x2d0
vfs_read+0x113/0x2c0
ksys_read+0xc9/0x170
do_syscall_64+0x33/0x40
entry_SYSCALL_64_after_hwframe+0x67/0xd1
Fix these issues by using `rcu_work` to help release
`svc_expkey`/`svc_export`. This approach allows for an asynchronous
context to invoke `path_put` and also facilitates the freeing of
`uuid/exp/key` after an RCU grace period.
Fixes: 9ceddd9da134 ("knfsd: Allow lockless lookups of the exports")
Signed-off-by: Yang Erkun <yangerkun@huawei.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/export.c | 31 +++++++++++++++++++++++++------
fs/nfsd/export.h | 4 ++--
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a9d794cfd10e0..191842a5d7ee7 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -40,15 +40,24 @@
#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
-static void expkey_put(struct kref *ref)
+static void expkey_put_work(struct work_struct *work)
{
- struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
+ struct svc_expkey *key =
+ container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);
if (test_bit(CACHE_VALID, &key->h.flags) &&
!test_bit(CACHE_NEGATIVE, &key->h.flags))
path_put(&key->ek_path);
auth_domain_put(key->ek_client);
- kfree_rcu(key, ek_rcu);
+ kfree(key);
+}
+
+static void expkey_put(struct kref *ref)
+{
+ struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
+
+ INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work);
+ queue_rcu_work(system_wq, &key->ek_rcu_work);
}
static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
@@ -351,16 +360,26 @@ static void export_stats_destroy(struct export_stats *stats)
EXP_STATS_COUNTERS_NUM);
}
-static void svc_export_put(struct kref *ref)
+static void svc_export_put_work(struct work_struct *work)
{
- struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
+ struct svc_export *exp =
+ container_of(to_rcu_work(work), struct svc_export, ex_rcu_work);
+
path_put(&exp->ex_path);
auth_domain_put(exp->ex_client);
nfsd4_fslocs_free(&exp->ex_fslocs);
export_stats_destroy(exp->ex_stats);
kfree(exp->ex_stats);
kfree(exp->ex_uuid);
- kfree_rcu(exp, ex_rcu);
+ kfree(exp);
+}
+
+static void svc_export_put(struct kref *ref)
+{
+ struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
+
+ INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work);
+ queue_rcu_work(system_wq, &exp->ex_rcu_work);
}
static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h
index f73e23bb24a1e..fa545d8dcc369 100644
--- a/fs/nfsd/export.h
+++ b/fs/nfsd/export.h
@@ -75,7 +75,7 @@ struct svc_export {
u32 ex_layout_types;
struct nfsd4_deviceid_map *ex_devid_map;
struct cache_detail *cd;
- struct rcu_head ex_rcu;
+ struct rcu_work ex_rcu_work;
struct export_stats *ex_stats;
};
@@ -91,7 +91,7 @@ struct svc_expkey {
u32 ek_fsid[6];
struct path ek_path;
- struct rcu_head ek_rcu;
+ struct rcu_work ek_rcu_work;
};
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0703/1887] RDMA/mlx5: Move events notifier registration to be after device registration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (701 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0702/1887] nfsd: release svc_expkey/svc_export with rcu_work Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0704/1887] netfilter: IDLETIMER: Fix for possible ABBA deadlock Greg Kroah-Hartman
` (295 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Patrisious Haddad, Michael Guralnik,
Leon Romanovsky, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <phaddad@nvidia.com>
[ Upstream commit ede132a5cf559f3ab35a4c28bac4f4a6c20334d8 ]
Move pkey change work initialization and cleanup from device resources
stage to notifier stage, since this is the stage which handles this work
events.
Fix a race between the device deregistration and pkey change work by moving
MLX5_IB_STAGE_DEVICE_NOTIFIER to be after MLX5_IB_STAGE_IB_REG in order to
ensure that the notifier is deregistered before the device during cleanup.
Which ensures there are no works that are being executed after the
device has already unregistered which can cause the panic below.
BUG: kernel NULL pointer dereference, address: 0000000000000000
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 630071 Comm: kworker/1:2 Kdump: loaded Tainted: G W OE --------- --- 5.14.0-162.6.1.el9_1.x86_64 #1
Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090008 02/27/2023
Workqueue: events pkey_change_handler [mlx5_ib]
RIP: 0010:setup_qp+0x38/0x1f0 [mlx5_ib]
Code: ee 41 54 45 31 e4 55 89 f5 53 48 89 fb 48 83 ec 20 8b 77 08 65 48 8b 04 25 28 00 00 00 48 89 44 24 18 48 8b 07 48 8d 4c 24 16 <4c> 8b 38 49 8b 87 80 0b 00 00 4c 89 ff 48 8b 80 08 05 00 00 8b 40
RSP: 0018:ffffbcc54068be20 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff954054494128 RCX: ffffbcc54068be36
RDX: ffff954004934000 RSI: 0000000000000001 RDI: ffff954054494128
RBP: 0000000000000023 R08: ffff954001be2c20 R09: 0000000000000001
R10: ffff954001be2c20 R11: ffff9540260133c0 R12: 0000000000000000
R13: 0000000000000023 R14: 0000000000000000 R15: ffff9540ffcb0905
FS: 0000000000000000(0000) GS:ffff9540ffc80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000010625c001 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
mlx5_ib_gsi_pkey_change+0x20/0x40 [mlx5_ib]
process_one_work+0x1e8/0x3c0
worker_thread+0x50/0x3b0
? rescuer_thread+0x380/0x380
kthread+0x149/0x170
? set_kthread_struct+0x50/0x50
ret_from_fork+0x22/0x30
Modules linked in: rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) mlx5_fwctl(OE) fwctl(OE) ib_uverbs(OE) mlx5_core(OE) mlxdevm(OE) ib_core(OE) mlx_compat(OE) psample mlxfw(OE) tls knem(OE) netconsole nfsv3 nfs_acl nfs lockd grace fscache netfs qrtr rfkill sunrpc intel_rapl_msr intel_rapl_common rapl hv_balloon hv_utils i2c_piix4 pcspkr joydev fuse ext4 mbcache jbd2 sr_mod sd_mod cdrom t10_pi sg ata_generic pci_hyperv pci_hyperv_intf hyperv_drm drm_shmem_helper drm_kms_helper hv_storvsc syscopyarea hv_netvsc sysfillrect sysimgblt hid_hyperv fb_sys_fops scsi_transport_fc hyperv_keyboard drm ata_piix crct10dif_pclmul crc32_pclmul crc32c_intel libata ghash_clmulni_intel hv_vmbus serio_raw [last unloaded: ib_core]
CR2: 0000000000000000
---[ end trace f6f8be4eae12f7bc ]---
Fixes: 7722f47e71e5 ("IB/mlx5: Create GSI transmission QPs when P_Key table is changed")
Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
Link: https://patch.msgid.link/d271ceeff0c08431b3cbbbb3e2d416f09b6d1621.1731496944.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/main.c | 40 +++++++++++++---------------
drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +-
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 9da42edecb05c..993bdd815bbb2 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -2802,7 +2802,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
struct ib_srq_init_attr attr;
struct ib_device *ibdev;
struct ib_cq_init_attr cq_attr = {.cqe = 1};
- int port;
int ret = 0;
ibdev = &dev->ib_dev;
@@ -2851,10 +2850,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
goto error6;
}
- for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
- INIT_WORK(&devr->ports[port].pkey_change_work,
- pkey_change_handler);
-
return 0;
error6:
@@ -2873,16 +2868,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
{
struct mlx5_ib_resources *devr = &dev->devr;
- int port;
-
- /*
- * Make sure no change P_Key work items are still executing.
- *
- * At this stage, the mlx5_ib_event should be unregistered
- * and it ensures that no new works are added.
- */
- for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
- cancel_work_sync(&devr->ports[port].pkey_change_work);
ib_destroy_srq(devr->s1);
ib_destroy_srq(devr->s0);
@@ -4089,6 +4074,13 @@ static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)
static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
{
+ struct mlx5_ib_resources *devr = &dev->devr;
+ int port;
+
+ for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+ INIT_WORK(&devr->ports[port].pkey_change_work,
+ pkey_change_handler);
+
dev->mdev_events.notifier_call = mlx5_ib_event;
mlx5_notifier_register(dev->mdev, &dev->mdev_events);
return 0;
@@ -4096,7 +4088,13 @@ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev)
{
+ struct mlx5_ib_resources *devr = &dev->devr;
+ int port;
+
mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
+
+ for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+ cancel_work_sync(&devr->ports[port].pkey_change_work);
}
void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
@@ -4170,9 +4168,6 @@ static const struct mlx5_ib_profile pf_profile = {
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
mlx5_ib_dev_res_init,
mlx5_ib_dev_res_cleanup),
- STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
- mlx5_ib_stage_dev_notifier_init,
- mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_ODP,
mlx5_ib_odp_init_one,
mlx5_ib_odp_cleanup_one),
@@ -4197,6 +4192,9 @@ static const struct mlx5_ib_profile pf_profile = {
STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
mlx5_ib_stage_ib_reg_init,
mlx5_ib_stage_ib_reg_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+ mlx5_ib_stage_dev_notifier_init,
+ mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
mlx5_ib_stage_post_ib_reg_umr_init,
NULL),
@@ -4233,9 +4231,6 @@ const struct mlx5_ib_profile raw_eth_profile = {
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
mlx5_ib_dev_res_init,
mlx5_ib_dev_res_cleanup),
- STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
- mlx5_ib_stage_dev_notifier_init,
- mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
mlx5_ib_counters_init,
mlx5_ib_counters_cleanup),
@@ -4257,6 +4252,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
mlx5_ib_stage_ib_reg_init,
mlx5_ib_stage_ib_reg_cleanup),
+ STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+ mlx5_ib_stage_dev_notifier_init,
+ mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
mlx5_ib_stage_post_ib_reg_umr_init,
NULL),
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 0ef347e91ffeb..e8e285233b355 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -927,7 +927,6 @@ enum mlx5_ib_stages {
MLX5_IB_STAGE_QP,
MLX5_IB_STAGE_SRQ,
MLX5_IB_STAGE_DEVICE_RESOURCES,
- MLX5_IB_STAGE_DEVICE_NOTIFIER,
MLX5_IB_STAGE_ODP,
MLX5_IB_STAGE_COUNTERS,
MLX5_IB_STAGE_CONG_DEBUGFS,
@@ -936,6 +935,7 @@ enum mlx5_ib_stages {
MLX5_IB_STAGE_PRE_IB_REG_UMR,
MLX5_IB_STAGE_WHITELIST_UID,
MLX5_IB_STAGE_IB_REG,
+ MLX5_IB_STAGE_DEVICE_NOTIFIER,
MLX5_IB_STAGE_POST_IB_REG_UMR,
MLX5_IB_STAGE_DELAY_DROP,
MLX5_IB_STAGE_RESTRACK,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0704/1887] netfilter: IDLETIMER: Fix for possible ABBA deadlock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (702 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0703/1887] RDMA/mlx5: Move events notifier registration to be after device registration Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0705/1887] drm: zynqmp_kms: Unplug DRM device before removal Greg Kroah-Hartman
` (294 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Phil Sutter, Pablo Neira Ayuso,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <phil@nwl.cc>
[ Upstream commit f36b01994d68ffc253c8296e2228dfe6e6431c03 ]
Deletion of the last rule referencing a given idletimer may happen at
the same time as a read of its file in sysfs:
| ======================================================
| WARNING: possible circular locking dependency detected
| 6.12.0-rc7-01692-g5e9a28f41134-dirty #594 Not tainted
| ------------------------------------------------------
| iptables/3303 is trying to acquire lock:
| ffff8881057e04b8 (kn->active#48){++++}-{0:0}, at: __kernfs_remove+0x20
|
| but task is already holding lock:
| ffffffffa0249068 (list_mutex){+.+.}-{3:3}, at: idletimer_tg_destroy_v]
|
| which lock already depends on the new lock.
A simple reproducer is:
| #!/bin/bash
|
| while true; do
| iptables -A INPUT -i foo -j IDLETIMER --timeout 10 --label "testme"
| iptables -D INPUT -i foo -j IDLETIMER --timeout 10 --label "testme"
| done &
| while true; do
| cat /sys/class/xt_idletimer/timers/testme >/dev/null
| done
Avoid this by freeing list_mutex right after deleting the element from
the list, then continuing with the teardown.
Fixes: 0902b469bd25 ("netfilter: xtables: idletimer target implementation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/xt_IDLETIMER.c | 52 +++++++++++++++++++-----------------
1 file changed, 28 insertions(+), 24 deletions(-)
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index 9733f49847a6d..aa93c812317e2 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -415,21 +415,23 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) {
- pr_debug("deleting timer %s\n", info->label);
-
- list_del(&info->timer->entry);
- del_timer_sync(&info->timer->timer);
- cancel_work_sync(&info->timer->work);
- sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
- kfree(info->timer->attr.attr.name);
- kfree(info->timer);
- } else {
+ if (--info->timer->refcnt > 0) {
pr_debug("decreased refcnt of timer %s to %u\n",
info->label, info->timer->refcnt);
+ mutex_unlock(&list_mutex);
+ return;
}
+ pr_debug("deleting timer %s\n", info->label);
+
+ list_del(&info->timer->entry);
mutex_unlock(&list_mutex);
+
+ del_timer_sync(&info->timer->timer);
+ cancel_work_sync(&info->timer->work);
+ sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
+ kfree(info->timer->attr.attr.name);
+ kfree(info->timer);
}
static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
@@ -440,25 +442,27 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
mutex_lock(&list_mutex);
- if (--info->timer->refcnt == 0) {
- pr_debug("deleting timer %s\n", info->label);
-
- list_del(&info->timer->entry);
- if (info->timer->timer_type & XT_IDLETIMER_ALARM) {
- alarm_cancel(&info->timer->alarm);
- } else {
- del_timer_sync(&info->timer->timer);
- }
- cancel_work_sync(&info->timer->work);
- sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
- kfree(info->timer->attr.attr.name);
- kfree(info->timer);
- } else {
+ if (--info->timer->refcnt > 0) {
pr_debug("decreased refcnt of timer %s to %u\n",
info->label, info->timer->refcnt);
+ mutex_unlock(&list_mutex);
+ return;
}
+ pr_debug("deleting timer %s\n", info->label);
+
+ list_del(&info->timer->entry);
mutex_unlock(&list_mutex);
+
+ if (info->timer->timer_type & XT_IDLETIMER_ALARM) {
+ alarm_cancel(&info->timer->alarm);
+ } else {
+ del_timer_sync(&info->timer->timer);
+ }
+ cancel_work_sync(&info->timer->work);
+ sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
+ kfree(info->timer->attr.attr.name);
+ kfree(info->timer);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0705/1887] drm: zynqmp_kms: Unplug DRM device before removal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (703 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0704/1887] netfilter: IDLETIMER: Fix for possible ABBA deadlock Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0706/1887] f2fs: fix to drop all discards after creating snapshot on lvm device Greg Kroah-Hartman
` (293 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Anderson, Tomi Valkeinen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <sean.anderson@linux.dev>
[ Upstream commit 2e07c88914fc5289c21820b1aa94f058feb38197 ]
Prevent userspace accesses to the DRM device from causing
use-after-frees by unplugging the device before we remove it. This
causes any further userspace accesses to result in an error without
further calls into this driver's internals.
Fixes: d76271d22694 ("drm: xlnx: DRM/KMS driver for Xilinx ZynqMP DisplayPort Subsystem")
Closes: https://lore.kernel.org/dri-devel/4d8f4c9b-2efb-4774-9a37-2f257f79b2c9@linux.dev/
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-2-sean.anderson@linux.dev
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index f34d4ec1d92f3..463407d5f6600 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -253,7 +253,7 @@ static int zynqmp_dpsub_remove(struct platform_device *pdev)
struct zynqmp_dpsub *dpsub = platform_get_drvdata(pdev);
struct drm_device *drm = &dpsub->drm;
- drm_dev_unregister(drm);
+ drm_dev_unplug(drm);
drm_atomic_helper_shutdown(drm);
drm_kms_helper_poll_fini(drm);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0706/1887] f2fs: fix to drop all discards after creating snapshot on lvm device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (704 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0705/1887] drm: zynqmp_kms: Unplug DRM device before removal Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0707/1887] mm/slub: Avoid list corruption when removing a slab from the full list Greg Kroah-Hartman
` (292 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Piergiorgio Sartor, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit bc8aeb04fd80cb8cfae3058445c84410fd0beb5e ]
Piergiorgio reported a bug in bugzilla as below:
------------[ cut here ]------------
WARNING: CPU: 2 PID: 969 at fs/f2fs/segment.c:1330
RIP: 0010:__submit_discard_cmd+0x27d/0x400 [f2fs]
Call Trace:
__issue_discard_cmd+0x1ca/0x350 [f2fs]
issue_discard_thread+0x191/0x480 [f2fs]
kthread+0xcf/0x100
ret_from_fork+0x31/0x50
ret_from_fork_asm+0x1a/0x30
w/ below testcase, it can reproduce this bug quickly:
- pvcreate /dev/vdb
- vgcreate myvg1 /dev/vdb
- lvcreate -L 1024m -n mylv1 myvg1
- mount /dev/myvg1/mylv1 /mnt/f2fs
- dd if=/dev/zero of=/mnt/f2fs/file bs=1M count=20
- sync
- rm /mnt/f2fs/file
- sync
- lvcreate -L 1024m -s -n mylv1-snapshot /dev/myvg1/mylv1
- umount /mnt/f2fs
The root cause is: it will update discard_max_bytes of mounted lvm
device to zero after creating snapshot on this lvm device, then,
__submit_discard_cmd() will pass parameter @nr_sects w/ zero value
to __blkdev_issue_discard(), it returns a NULL bio pointer, result
in panic.
This patch changes as below for fixing:
1. Let's drop all remained discards in f2fs_unfreeze() if snapshot
of lvm device is created.
2. Checking discard_max_bytes before submitting discard during
__submit_discard_cmd().
Cc: stable@vger.kernel.org
Fixes: 35ec7d574884 ("f2fs: split discard command in prior to block layer")
Reported-by: Piergiorgio Sartor <piergiorgio.sartor@nexgo.de>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219484
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/segment.c | 9 +++++++++
fs/f2fs/super.c | 12 ++++++++++++
2 files changed, 21 insertions(+)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4b13e04c6e608..bf52ba8a32c04 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1125,6 +1125,15 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
return 0;
+ /*
+ * stop issuing discard for any of below cases:
+ * 1. device is conventional zone, but it doesn't support discard.
+ * 2. device is regulare device, after snapshot it doesn't support
+ * discard.
+ */
+ if (!bdev_max_discard_sectors(bdev))
+ return -EOPNOTSUPP;
+
trace_f2fs_issue_discard(bdev, dc->start, dc->len);
lstart = dc->lstart;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 375daa37b3795..a1c33931d175e 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1742,6 +1742,18 @@ static int f2fs_freeze(struct super_block *sb)
static int f2fs_unfreeze(struct super_block *sb)
{
+ struct f2fs_sb_info *sbi = F2FS_SB(sb);
+
+ /*
+ * It will update discard_max_bytes of mounted lvm device to zero
+ * after creating snapshot on this lvm device, let's drop all
+ * remained discards.
+ * We don't need to disable real-time discard because discard_max_bytes
+ * will recover after removal of snapshot.
+ */
+ if (test_opt(sbi, DISCARD) && !f2fs_hw_support_discard(sbi))
+ f2fs_issue_discard_timeout(sbi, false);
+
clear_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0707/1887] mm/slub: Avoid list corruption when removing a slab from the full list
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (705 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0706/1887] f2fs: fix to drop all discards after creating snapshot on lvm device Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0708/1887] sched/deadline: Fix warning in migrate_enable for boosted tasks Greg Kroah-Hartman
` (291 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyeonggon Yoo, Vlastimil Babka,
yuan.gao, Christoph Lameter, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: yuan.gao <yuan.gao@ucloud.cn>
[ Upstream commit dbc16915279a548a204154368da23d402c141c81 ]
Boot with slub_debug=UFPZ.
If allocated object failed in alloc_consistency_checks, all objects of
the slab will be marked as used, and then the slab will be removed from
the partial list.
When an object belonging to the slab got freed later, the remove_full()
function is called. Because the slab is neither on the partial list nor
on the full list, it eventually lead to a list corruption (actually a
list poison being detected).
So we need to mark and isolate the slab page with metadata corruption,
do not put it back in circulation.
Because the debug caches avoid all the fastpaths, reusing the frozen bit
to mark slab page with metadata corruption seems to be fine.
[ 4277.385669] list_del corruption, ffffea00044b3e50->next is LIST_POISON1 (dead000000000100)
[ 4277.387023] ------------[ cut here ]------------
[ 4277.387880] kernel BUG at lib/list_debug.c:56!
[ 4277.388680] invalid opcode: 0000 [#1] PREEMPT SMP PTI
[ 4277.389562] CPU: 5 PID: 90 Comm: kworker/5:1 Kdump: loaded Tainted: G OE 6.6.1-1 #1
[ 4277.392113] Workqueue: xfs-inodegc/vda1 xfs_inodegc_worker [xfs]
[ 4277.393551] RIP: 0010:__list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.394518] Code: 48 91 82 e8 37 f9 9a ff 0f 0b 48 89 fe 48 c7 c7 28 49 91 82 e8 26 f9 9a ff 0f 0b 48 89 fe 48 c7 c7 58 49 91
[ 4277.397292] RSP: 0018:ffffc90000333b38 EFLAGS: 00010082
[ 4277.398202] RAX: 000000000000004e RBX: ffffea00044b3e50 RCX: 0000000000000000
[ 4277.399340] RDX: 0000000000000002 RSI: ffffffff828f8715 RDI: 00000000ffffffff
[ 4277.400545] RBP: ffffea00044b3e40 R08: 0000000000000000 R09: ffffc900003339f0
[ 4277.401710] R10: 0000000000000003 R11: ffffffff82d44088 R12: ffff888112cf9910
[ 4277.402887] R13: 0000000000000001 R14: 0000000000000001 R15: ffff8881000424c0
[ 4277.404049] FS: 0000000000000000(0000) GS:ffff88842fd40000(0000) knlGS:0000000000000000
[ 4277.405357] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 4277.406389] CR2: 00007f2ad0b24000 CR3: 0000000102a3a006 CR4: 00000000007706e0
[ 4277.407589] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 4277.408780] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 4277.410000] PKRU: 55555554
[ 4277.410645] Call Trace:
[ 4277.411234] <TASK>
[ 4277.411777] ? die+0x32/0x80
[ 4277.412439] ? do_trap+0xd6/0x100
[ 4277.413150] ? __list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.414158] ? do_error_trap+0x6a/0x90
[ 4277.414948] ? __list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.415915] ? exc_invalid_op+0x4c/0x60
[ 4277.416710] ? __list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.417675] ? asm_exc_invalid_op+0x16/0x20
[ 4277.418482] ? __list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.419466] ? __list_del_entry_valid_or_report+0x7b/0xc0
[ 4277.420410] free_to_partial_list+0x515/0x5e0
[ 4277.421242] ? xfs_iext_remove+0x41a/0xa10 [xfs]
[ 4277.422298] xfs_iext_remove+0x41a/0xa10 [xfs]
[ 4277.423316] ? xfs_inodegc_worker+0xb4/0x1a0 [xfs]
[ 4277.424383] xfs_bmap_del_extent_delay+0x4fe/0x7d0 [xfs]
[ 4277.425490] __xfs_bunmapi+0x50d/0x840 [xfs]
[ 4277.426445] xfs_itruncate_extents_flags+0x13a/0x490 [xfs]
[ 4277.427553] xfs_inactive_truncate+0xa3/0x120 [xfs]
[ 4277.428567] xfs_inactive+0x22d/0x290 [xfs]
[ 4277.429500] xfs_inodegc_worker+0xb4/0x1a0 [xfs]
[ 4277.430479] process_one_work+0x171/0x340
[ 4277.431227] worker_thread+0x277/0x390
[ 4277.431962] ? __pfx_worker_thread+0x10/0x10
[ 4277.432752] kthread+0xf0/0x120
[ 4277.433382] ? __pfx_kthread+0x10/0x10
[ 4277.434134] ret_from_fork+0x2d/0x50
[ 4277.434837] ? __pfx_kthread+0x10/0x10
[ 4277.435566] ret_from_fork_asm+0x1b/0x30
[ 4277.436280] </TASK>
Fixes: 643b113849d8 ("slub: enable tracking of full slabs")
Suggested-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: yuan.gao <yuan.gao@ucloud.cn>
Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/slab.h | 5 +++++
mm/slub.c | 9 ++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/mm/slab.h b/mm/slab.h
index 0202a8c2f0d25..42eb31375fdf9 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -40,6 +40,11 @@ struct slab {
struct {
unsigned inuse:16;
unsigned objects:15;
+ /*
+ * If slab debugging is enabled then the
+ * frozen bit can be reused to indicate
+ * that the slab was corrupted
+ */
unsigned frozen:1;
};
};
diff --git a/mm/slub.c b/mm/slub.c
index 5428a41d70eb7..bafb09a3c00a4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1196,6 +1196,11 @@ static int check_slab(struct kmem_cache *s, struct slab *slab)
slab->inuse, slab->objects);
return 0;
}
+ if (slab->frozen) {
+ slab_err(s, slab, "Slab disabled since SLUB metadata consistency check failed");
+ return 0;
+ }
+
/* Slab_pad_check fixes things up after itself */
slab_pad_check(s, slab);
return 1;
@@ -1392,6 +1397,7 @@ static noinline bool alloc_debug_processing(struct kmem_cache *s,
slab_fix(s, "Marking all objects used");
slab->inuse = slab->objects;
slab->freelist = NULL;
+ slab->frozen = 1; /* mark consistency-failed slab as frozen */
}
return false;
}
@@ -2088,7 +2094,8 @@ static void *alloc_single_from_partial(struct kmem_cache *s,
slab->inuse++;
if (!alloc_debug_processing(s, slab, object, orig_size)) {
- remove_partial(n, slab);
+ if (folio_test_slab(slab_folio(slab)))
+ remove_partial(n, slab);
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0708/1887] sched/deadline: Fix warning in migrate_enable for boosted tasks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (706 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0707/1887] mm/slub: Avoid list corruption when removing a slab from the full list Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0709/1887] scsi: hisi_sas: Move slot variable definition in hisi_sas_abort_task() Greg Kroah-Hartman
` (290 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wander Lairson Costa,
Peter Zijlstra (Intel), Juri Lelli, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wander Lairson Costa <wander@redhat.com>
[ Upstream commit 0664e2c311b9fa43b33e3e81429cd0c2d7f9c638 ]
When running the following command:
while true; do
stress-ng --cyclic 30 --timeout 30s --minimize --quiet
done
a warning is eventually triggered:
WARNING: CPU: 43 PID: 2848 at kernel/sched/deadline.c:794
setup_new_dl_entity+0x13e/0x180
...
Call Trace:
<TASK>
? show_trace_log_lvl+0x1c4/0x2df
? enqueue_dl_entity+0x631/0x6e0
? setup_new_dl_entity+0x13e/0x180
? __warn+0x7e/0xd0
? report_bug+0x11a/0x1a0
? handle_bug+0x3c/0x70
? exc_invalid_op+0x14/0x70
? asm_exc_invalid_op+0x16/0x20
enqueue_dl_entity+0x631/0x6e0
enqueue_task_dl+0x7d/0x120
__do_set_cpus_allowed+0xe3/0x280
__set_cpus_allowed_ptr_locked+0x140/0x1d0
__set_cpus_allowed_ptr+0x54/0xa0
migrate_enable+0x7e/0x150
rt_spin_unlock+0x1c/0x90
group_send_sig_info+0xf7/0x1a0
? kill_pid_info+0x1f/0x1d0
kill_pid_info+0x78/0x1d0
kill_proc_info+0x5b/0x110
__x64_sys_kill+0x93/0xc0
do_syscall_64+0x5c/0xf0
entry_SYSCALL_64_after_hwframe+0x6e/0x76
RIP: 0033:0x7f0dab31f92b
This warning occurs because set_cpus_allowed dequeues and enqueues tasks
with the ENQUEUE_RESTORE flag set. If the task is boosted, the warning
is triggered. A boosted task already had its parameters set by
rt_mutex_setprio, and a new call to setup_new_dl_entity is unnecessary,
hence the WARN_ON call.
Check if we are requeueing a boosted task and avoid calling
setup_new_dl_entity if that's the case.
Fixes: 295d6d5e3736 ("sched/deadline: Fix switching to -deadline")
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Juri Lelli <juri.lelli@redhat.com>
Link: https://lore.kernel.org/r/20240724142253.27145-2-wander@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/deadline.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 83204e5b780e4..972a5e728c10e 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1656,6 +1656,7 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags)
} else if (flags & ENQUEUE_REPLENISH) {
replenish_dl_entity(dl_se);
} else if ((flags & ENQUEUE_RESTORE) &&
+ !is_dl_boosted(dl_se) &&
dl_time_before(dl_se->deadline,
rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se))))) {
setup_new_dl_entity(dl_se);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0709/1887] scsi: hisi_sas: Move slot variable definition in hisi_sas_abort_task()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (707 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0708/1887] sched/deadline: Fix warning in migrate_enable for boosted tasks Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0710/1887] scsi: hisi_sas: Add SATA_DISK_ERR bit handling for v3 hw Greg Kroah-Hartman
` (289 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xingui Yang, John Garry,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xingui Yang <yangxingui@huawei.com>
[ Upstream commit 4b329abc91800d23941ac773e69b322a13981ecb ]
Each branch currently defines a slot variable independently, and it is
neater to move it to the function head.
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1665998435-199946-3-git-send-email-john.garry@huawei.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas_main.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 290c9915fb9b2..ae7383e9e5fc1 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1574,6 +1574,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
struct hisi_sas_internal_abort_data internal_abort_data = { false };
struct domain_device *device = task->dev;
struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_slot *slot = task->lldd_task;
struct hisi_hba *hisi_hba;
struct device *dev;
int rc = TMF_RESP_FUNC_FAILED;
@@ -1587,7 +1588,6 @@ static int hisi_sas_abort_task(struct sas_task *task)
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
- struct hisi_sas_slot *slot = task->lldd_task;
struct hisi_sas_cq *cq;
if (slot) {
@@ -1605,8 +1605,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);
- if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
- struct hisi_sas_slot *slot = task->lldd_task;
+ if (slot && task->task_proto & SAS_PROTOCOL_SSP) {
u16 tag = slot->idx;
int rc2;
@@ -1640,9 +1639,8 @@ static int hisi_sas_abort_task(struct sas_task *task)
hisi_sas_dereg_device(hisi_hba, device);
rc = hisi_sas_softreset_ata_disk(device);
}
- } else if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SMP) {
+ } else if (slot && task->task_proto & SAS_PROTOCOL_SMP) {
/* SMP */
- struct hisi_sas_slot *slot = task->lldd_task;
u32 tag = slot->idx;
struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0710/1887] scsi: hisi_sas: Add SATA_DISK_ERR bit handling for v3 hw
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (708 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0709/1887] scsi: hisi_sas: Move slot variable definition in hisi_sas_abort_task() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0711/1887] scsi: hisi_sas: Add function complete_v3_hw() Greg Kroah-Hartman
` (288 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xingui Yang, John Garry,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xingui Yang <yangxingui@huawei.com>
[ Upstream commit 930d97dabdd56681aef752a35475f0212a171741 ]
When CQ header dw3 SATA_DISK_ERR is set it means this SATA disk is in error
state and the current IPTT is invalid. An invalid IPTT does not correspond
to any slot.
In this scenario, new I/Os that delivered to disk will be rejected by the
controller and all I/Os remaining in the disk should be aborted, which we
add here with the sas_ata_device_link_abort() call.
In hisi_sas_abort_task() we don't want to issue a soft reset as it may
cause info to be lost in the target disk for the ATA EH autopsy. In this
case, just release resources - the disk won't return other I/Os normally
after NCQ Error, so this is safe.
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1665998435-199946-4-git-send-email-john.garry@huawei.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas.h | 1 +
drivers/scsi/hisi_sas/hisi_sas_main.c | 18 +++++++++-
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 48 ++++++++++++++++++++++++--
3 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 2ecf97f7ae525..423af1dc36487 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -104,6 +104,7 @@ enum {
enum dev_status {
HISI_SAS_DEV_INIT,
HISI_SAS_DEV_NORMAL,
+ HISI_SAS_DEV_NCQ_ERR,
};
enum {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index ae7383e9e5fc1..2f13bb9771d64 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1631,13 +1631,26 @@ static int hisi_sas_abort_task(struct sas_task *task)
} else if (task->task_proto & SAS_PROTOCOL_SATA ||
task->task_proto & SAS_PROTOCOL_STP) {
if (task->dev->dev_type == SAS_SATA_DEV) {
+ struct ata_queued_cmd *qc = task->uldd_task;
+
rc = hisi_sas_internal_task_abort_dev(sas_dev, false);
if (rc < 0) {
dev_err(dev, "abort task: internal abort failed\n");
goto out;
}
hisi_sas_dereg_device(hisi_hba, device);
- rc = hisi_sas_softreset_ata_disk(device);
+
+ /*
+ * If an ATA internal command times out in ATA EH, it
+ * need to execute soft reset, so check the scsicmd
+ */
+ if ((sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR) &&
+ qc && qc->scsicmd) {
+ hisi_sas_do_release_task(hisi_hba, task, slot);
+ rc = TMF_RESP_FUNC_COMPLETE;
+ } else {
+ rc = hisi_sas_softreset_ata_disk(device);
+ }
}
} else if (slot && task->task_proto & SAS_PROTOCOL_SMP) {
/* SMP */
@@ -1756,6 +1769,9 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
struct device *dev = hisi_hba->dev;
int rc;
+ if (sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR)
+ sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
+
rc = hisi_sas_internal_task_abort_dev(sas_dev, false);
if (rc < 0) {
dev_err(dev, "I_T nexus reset: internal abort (%d)\n", rc);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 3db206c743831..2b19c515acdeb 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -408,6 +408,11 @@
#define CMPLT_HDR_CMPLT_MSK (0x3 << CMPLT_HDR_CMPLT_OFF)
#define CMPLT_HDR_ERROR_PHASE_OFF 2
#define CMPLT_HDR_ERROR_PHASE_MSK (0xff << CMPLT_HDR_ERROR_PHASE_OFF)
+/* bit[9:2] Error Phase */
+#define ERR_PHASE_RESPONSE_FRAME_REV_STAGE_OFF \
+ 8
+#define ERR_PHASE_RESPONSE_FRAME_REV_STAGE_MSK \
+ (0x1 << ERR_PHASE_RESPONSE_FRAME_REV_STAGE_OFF)
#define CMPLT_HDR_RSPNS_XFRD_OFF 10
#define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)
#define CMPLT_HDR_RSPNS_GOOD_OFF 11
@@ -427,8 +432,15 @@
#define CMPLT_HDR_DEV_ID_OFF 16
#define CMPLT_HDR_DEV_ID_MSK (0xffff << CMPLT_HDR_DEV_ID_OFF)
/* dw3 */
+#define CMPLT_HDR_SATA_DISK_ERR_OFF 16
+#define CMPLT_HDR_SATA_DISK_ERR_MSK (0x1 << CMPLT_HDR_SATA_DISK_ERR_OFF)
#define CMPLT_HDR_IO_IN_TARGET_OFF 17
#define CMPLT_HDR_IO_IN_TARGET_MSK (0x1 << CMPLT_HDR_IO_IN_TARGET_OFF)
+/* bit[23:18] ERR_FIS_ATA_STATUS */
+#define FIS_ATA_STATUS_ERR_OFF 18
+#define FIS_ATA_STATUS_ERR_MSK (0x1 << FIS_ATA_STATUS_ERR_OFF)
+#define FIS_TYPE_SDB_OFF 31
+#define FIS_TYPE_SDB_MSK (0x1 << FIS_TYPE_SDB_OFF)
/* ITCT header */
/* qw0 */
@@ -2160,6 +2172,18 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p)
return IRQ_HANDLED;
}
+static bool is_ncq_err_v3_hw(struct hisi_sas_complete_v3_hdr *complete_hdr)
+{
+ u32 dw0, dw3;
+
+ dw0 = le32_to_cpu(complete_hdr->dw0);
+ dw3 = le32_to_cpu(complete_hdr->dw3);
+
+ return (dw0 & ERR_PHASE_RESPONSE_FRAME_REV_STAGE_MSK) &&
+ (dw3 & FIS_TYPE_SDB_MSK) &&
+ (dw3 & FIS_ATA_STATUS_ERR_MSK);
+}
+
static bool
slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
struct hisi_sas_slot *slot)
@@ -2400,14 +2424,34 @@ static irqreturn_t cq_thread_v3_hw(int irq_no, void *p)
while (rd_point != wr_point) {
struct hisi_sas_complete_v3_hdr *complete_hdr;
struct device *dev = hisi_hba->dev;
- u32 dw1;
+ u32 dw0, dw1, dw3;
int iptt;
complete_hdr = &complete_queue[rd_point];
+ dw0 = le32_to_cpu(complete_hdr->dw0);
dw1 = le32_to_cpu(complete_hdr->dw1);
+ dw3 = le32_to_cpu(complete_hdr->dw3);
iptt = dw1 & CMPLT_HDR_IPTT_MSK;
- if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
+ if (unlikely((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) &&
+ (dw3 & CMPLT_HDR_SATA_DISK_ERR_MSK)) {
+ int device_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >>
+ CMPLT_HDR_DEV_ID_OFF;
+ struct hisi_sas_itct *itct =
+ &hisi_hba->itct[device_id];
+ struct hisi_sas_device *sas_dev =
+ &hisi_hba->devices[device_id];
+ struct domain_device *device = sas_dev->sas_device;
+
+ dev_err(dev, "erroneous completion disk err dev id=%d sas_addr=0x%llx CQ hdr: 0x%x 0x%x 0x%x 0x%x\n",
+ device_id, itct->sas_addr, dw0, dw1,
+ complete_hdr->act, dw3);
+
+ if (is_ncq_err_v3_hw(complete_hdr))
+ sas_dev->dev_status = HISI_SAS_DEV_NCQ_ERR;
+
+ sas_ata_device_link_abort(device, true);
+ } else if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
slot = &hisi_hba->slot_info[iptt];
slot->cmplt_queue_slot = rd_point;
slot->cmplt_queue = queue;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0711/1887] scsi: hisi_sas: Add function complete_v3_hw()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (709 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0710/1887] scsi: hisi_sas: Add SATA_DISK_ERR bit handling for v3 hw Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0712/1887] scsi: hisi_sas: Directly call register snapshot instead of using workqueue Greg Kroah-Hartman
` (287 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Garry, Xiang Chen,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Chen <chenxiang66@hisilicon.com>
[ Upstream commit 538a60468966f47c53071d06db27bb78c2aaa81d ]
Put the work of processing cq slots in a separate function,
complete_v3_hw(), which can then be used by cq_thread_v3_hw() and other
functions when adding poll support.
Co-developed-by: John Garry <john.garry@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Link: https://lore.kernel.org/r/1678169355-76215-2-git-send-email-chenxiang66@hisilicon.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
[ Keep the cond_resched() call at the end of cq_thread_v3_hw() after the
split. Also pass need_lock to the hisi_sas_do_release_task() call added
by the SATA_DISK_ERR dependency, which this tree's function requires. ]
Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 17 ++++++++++++-----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 2f13bb9771d64..e13fa623ff5a6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1646,7 +1646,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
*/
if ((sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR) &&
qc && qc->scsicmd) {
- hisi_sas_do_release_task(hisi_hba, task, slot);
+ hisi_sas_do_release_task(hisi_hba, task, slot, true);
rc = TMF_RESP_FUNC_COMPLETE;
} else {
rc = hisi_sas_softreset_ata_disk(device);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 2b19c515acdeb..63db4a2ea7ba7 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2407,15 +2407,14 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
task->task_done(task);
}
-static irqreturn_t cq_thread_v3_hw(int irq_no, void *p)
+static void complete_v3_hw(struct hisi_sas_cq *cq)
{
- struct hisi_sas_cq *cq = p;
- struct hisi_hba *hisi_hba = cq->hisi_hba;
- struct hisi_sas_slot *slot;
struct hisi_sas_complete_v3_hdr *complete_queue;
- u32 rd_point = cq->rd_point, wr_point;
+ struct hisi_hba *hisi_hba = cq->hisi_hba;
+ u32 rd_point, wr_point;
int queue = cq->id;
+ rd_point = cq->rd_point;
complete_queue = hisi_hba->complete_hdr[queue];
wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +
@@ -2424,6 +2423,7 @@ static irqreturn_t cq_thread_v3_hw(int irq_no, void *p)
while (rd_point != wr_point) {
struct hisi_sas_complete_v3_hdr *complete_hdr;
struct device *dev = hisi_hba->dev;
+ struct hisi_sas_slot *slot;
u32 dw0, dw1, dw3;
int iptt;
@@ -2466,6 +2466,13 @@ static irqreturn_t cq_thread_v3_hw(int irq_no, void *p)
/* update rd_point */
cq->rd_point = rd_point;
hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
+}
+
+static irqreturn_t cq_thread_v3_hw(int irq_no, void *p)
+{
+ struct hisi_sas_cq *cq = p;
+
+ complete_v3_hw(cq);
cond_resched();
return IRQ_HANDLED;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0712/1887] scsi: hisi_sas: Directly call register snapshot instead of using workqueue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (710 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0711/1887] scsi: hisi_sas: Add function complete_v3_hw() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0713/1887] scsi: hisi_sas: Allocate DFX memory during dump trigger Greg Kroah-Hartman
` (286 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yihang Li, Xiang Chen,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihang Li <liyihang9@huawei.com>
[ Upstream commit 2ff07b5c6fe9173e7a7de3b23f300d71ad4d8fde ]
Currently, register information dump is performed via workqueue, regardless
of the trigger mode (automatic or manual). There is a delay in dumping
register through workqueue, the exact register information at trigger time
cannot be obtained.
Call register snapshot directly instead of through a workqueue.
Signed-off-by: Yihang Li <liyihang9@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Link: https://lore.kernel.org/r/1694571327-78697-3-git-send-email-chenxiang66@hisilicon.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas.h | 1 -
drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++--
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 +++-----------
3 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 423af1dc36487..2885ea87fd1eb 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -450,7 +450,6 @@ struct hisi_hba {
const struct hisi_sas_hw *hw; /* Low level hw interface */
unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
struct work_struct rst_work;
- struct work_struct debugfs_work;
u32 phy_state;
u32 intr_coal_ticks; /* Time of interrupt coalesce in us */
u32 intr_coal_count; /* Interrupt count to coalesce */
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index e13fa623ff5a6..85d544e016a61 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1907,8 +1907,11 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task,
struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
struct hisi_sas_internal_abort_data *timeout = data;
- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct)
- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
+ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) {
+ down(&hisi_hba->sem);
+ hisi_hba->hw->debugfs_snapshot_regs(hisi_hba);
+ up(&hisi_hba->sem);
+ }
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
pr_err("Internal abort: timeout %016llx\n",
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 63db4a2ea7ba7..13019517e8469 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -554,7 +554,6 @@ static int prot_mask;
module_param(prot_mask, int, 0444);
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
-static void debugfs_work_handler_v3_hw(struct work_struct *work);
static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
@@ -3311,7 +3310,6 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
hisi_hba = shost_priv(shost);
INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler);
- INIT_WORK(&hisi_hba->debugfs_work, debugfs_work_handler_v3_hw);
hisi_hba->hw = &hisi_sas_v3_hw;
hisi_hba->pci_dev = pdev;
hisi_hba->dev = dev;
@@ -3826,7 +3824,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
if (buf[0] != '1')
return -EFAULT;
- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
+ down(&hisi_hba->sem);
+ debugfs_snapshot_regs_v3_hw(hisi_hba);
+ up(&hisi_hba->sem);
return count;
}
@@ -4577,14 +4577,6 @@ static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba)
}
}
-static void debugfs_work_handler_v3_hw(struct work_struct *work)
-{
- struct hisi_hba *hisi_hba =
- container_of(work, struct hisi_hba, debugfs_work);
-
- debugfs_snapshot_regs_v3_hw(hisi_hba);
-}
-
static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
{
struct device *dev = hisi_hba->dev;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0713/1887] scsi: hisi_sas: Allocate DFX memory during dump trigger
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (711 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0712/1887] scsi: hisi_sas: Directly call register snapshot instead of using workqueue Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0714/1887] scsi: hisi_sas: Create all dump files during debugfs initialization Greg Kroah-Hartman
` (285 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yihang Li, Xiang Chen,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihang Li <liyihang9@huawei.com>
[ Upstream commit 63f0733d07ce60252e885602b39571ade0441015 ]
Currently, if CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE is enabled, the
memory space used by DFX is allocated during device initialization, which
occupies a large number of memory resources. The memory usage before and
after the driver is loaded is as follows:
Memory usage before the driver is loaded:
$ free -m
total used free shared buff/cache available
Mem: 867352 2578 864037 11 735 861681
Swap: 4095 0 4095
Memory usage after the driver which include 4 HBAs is loaded:
$ insmod hisi_sas_v3_hw.ko
$ free -m
total used free shared buff/cache available
Mem: 867352 4760 861848 11 743 859495
Swap: 4095 0 4095
The driver with 4 HBAs connected will allocate about 110 MB of memory
without enabling debugfs.
Therefore, to avoid wasting memory resources, DFX memory is allocated
during dump triggering. The dump may fail due to memory allocation
failure. After this change, each dump costs about 10 MB of memory, and each
dump lasts about 100 ms.
Signed-off-by: Yihang Li <liyihang9@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Link: https://lore.kernel.org/r/1694571327-78697-4-git-send-email-chenxiang66@hisilicon.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 113 +++++++++++++------------
2 files changed, 62 insertions(+), 53 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 2885ea87fd1eb..b0f3110c60558 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -342,7 +342,7 @@ struct hisi_sas_hw {
u8 reg_index, u8 reg_count, u8 *write_data);
void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
int delay_ms, int timeout_ms);
- void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
+ int (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
int complete_hdr_size;
struct scsi_host_template *sht;
};
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 13019517e8469..c3d4c7e26b492 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -554,7 +554,7 @@ static int prot_mask;
module_param(prot_mask, int, 0444);
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
+static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
{
@@ -3774,37 +3774,6 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
&debugfs_ras_v3_hw_fops);
}
-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
-{
- int debugfs_dump_index = hisi_hba->debugfs_dump_index;
- struct device *dev = hisi_hba->dev;
- u64 timestamp = local_clock();
-
- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
- dev_warn(dev, "dump count exceeded!\n");
- return;
- }
-
- do_div(timestamp, NSEC_PER_MSEC);
- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
-
- debugfs_snapshot_prepare_v3_hw(hisi_hba);
-
- debugfs_snapshot_global_reg_v3_hw(hisi_hba);
- debugfs_snapshot_port_reg_v3_hw(hisi_hba);
- debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
- debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
- debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
- debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
- debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
- debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
-
- debugfs_create_files_v3_hw(hisi_hba);
-
- debugfs_snapshot_restore_v3_hw(hisi_hba);
- hisi_hba->debugfs_dump_index++;
-}
-
static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
@@ -3812,9 +3781,6 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
struct hisi_hba *hisi_hba = file->f_inode->i_private;
char buf[8];
- if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count)
- return -EFAULT;
-
if (count > 8)
return -EFAULT;
@@ -3825,7 +3791,10 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
return -EFAULT;
down(&hisi_hba->sem);
- debugfs_snapshot_regs_v3_hw(hisi_hba);
+ if (debugfs_snapshot_regs_v3_hw(hisi_hba)) {
+ up(&hisi_hba->sem);
+ return -EFAULT;
+ }
up(&hisi_hba->sem);
return count;
@@ -4583,22 +4552,34 @@ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
int i;
devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache);
+ hisi_hba->debugfs_iost_cache[dump_index].cache = NULL;
devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache);
+ hisi_hba->debugfs_itct_cache[dump_index].cache = NULL;
devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost);
+ hisi_hba->debugfs_iost[dump_index].iost = NULL;
devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct);
+ hisi_hba->debugfs_itct[dump_index].itct = NULL;
- for (i = 0; i < hisi_hba->queue_count; i++)
+ for (i = 0; i < hisi_hba->queue_count; i++) {
devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr);
+ hisi_hba->debugfs_dq[dump_index][i].hdr = NULL;
+ }
- for (i = 0; i < hisi_hba->queue_count; i++)
+ for (i = 0; i < hisi_hba->queue_count; i++) {
devm_kfree(dev,
hisi_hba->debugfs_cq[dump_index][i].complete_hdr);
+ hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL;
+ }
- for (i = 0; i < DEBUGFS_REGS_NUM; i++)
+ for (i = 0; i < DEBUGFS_REGS_NUM; i++) {
devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data);
+ hisi_hba->debugfs_regs[dump_index][i].data = NULL;
+ }
- for (i = 0; i < hisi_hba->n_phy; i++)
+ for (i = 0; i < hisi_hba->n_phy; i++) {
devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data);
+ hisi_hba->debugfs_port_reg[dump_index][i].data = NULL;
+ }
}
static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = {
@@ -4611,7 +4592,7 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
{
const struct hisi_sas_hw *hw = hisi_hba->hw;
struct device *dev = hisi_hba->dev;
- int p, c, d, r, i;
+ int p, c, d, r;
size_t sz;
for (r = 0; r < DEBUGFS_REGS_NUM; r++) {
@@ -4691,11 +4672,48 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
return 0;
fail:
- for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
- debugfs_release_v3_hw(hisi_hba, i);
+ debugfs_release_v3_hw(hisi_hba, dump_index);
return -ENOMEM;
}
+static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
+{
+ int debugfs_dump_index = hisi_hba->debugfs_dump_index;
+ struct device *dev = hisi_hba->dev;
+ u64 timestamp = local_clock();
+
+ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
+ dev_warn(dev, "dump count exceeded!\n");
+ return -EINVAL;
+ }
+
+ if (debugfs_alloc_v3_hw(hisi_hba, debugfs_dump_index)) {
+ dev_warn(dev, "failed to alloc memory\n");
+ return -ENOMEM;
+ }
+
+ do_div(timestamp, NSEC_PER_MSEC);
+ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
+
+ debugfs_snapshot_prepare_v3_hw(hisi_hba);
+
+ debugfs_snapshot_global_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_port_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
+ debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
+
+ debugfs_create_files_v3_hw(hisi_hba);
+
+ debugfs_snapshot_restore_v3_hw(hisi_hba);
+ hisi_hba->debugfs_dump_index++;
+
+ return 0;
+}
+
static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba)
{
struct dentry *dir = debugfs_create_dir("phy_down_cnt",
@@ -4782,7 +4800,6 @@ static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
{
struct device *dev = hisi_hba->dev;
- int i;
hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
hisi_sas_debugfs_dir);
@@ -4799,14 +4816,6 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
debugfs_fifo_init_v3_hw(hisi_hba);
-
- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
- if (debugfs_alloc_v3_hw(hisi_hba, i)) {
- debugfs_exit_v3_hw(hisi_hba);
- dev_dbg(dev, "failed to init debugfs!\n");
- break;
- }
- }
}
static int
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0714/1887] scsi: hisi_sas: Create all dump files during debugfs initialization
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (712 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0713/1887] scsi: hisi_sas: Allocate DFX memory during dump trigger Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0715/1887] bpf: Call free_htab_elem() after htab_unlock_bucket() Greg Kroah-Hartman
` (284 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yihang Li, Xingui Yang,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihang Li <liyihang9@huawei.com>
[ Upstream commit 9f564f15f88490b484e02442dc4c4b11640ea172 ]
For the current debugfs of hisi_sas, after user triggers dump, the
driver allocate memory space to save the register information and create
debugfs files to display the saved information. In this process, the
debugfs files created after each dump.
Therefore, when the dump is triggered while the driver is unbind, the
following hang occurs:
[67840.853907] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0
[67840.862947] Mem abort info:
[67840.865855] ESR = 0x0000000096000004
[67840.869713] EC = 0x25: DABT (current EL), IL = 32 bits
[67840.875125] SET = 0, FnV = 0
[67840.878291] EA = 0, S1PTW = 0
[67840.881545] FSC = 0x04: level 0 translation fault
[67840.886528] Data abort info:
[67840.889524] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[67840.895117] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[67840.900284] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[67840.905709] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002803a1f000
[67840.912263] [00000000000000a0] pgd=0000000000000000, p4d=0000000000000000
[67840.919177] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[67840.996435] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[67841.003628] pc : down_write+0x30/0x98
[67841.007546] lr : start_creating.part.0+0x60/0x198
[67841.012495] sp : ffff8000b979ba20
[67841.016046] x29: ffff8000b979ba20 x28: 0000000000000010 x27: 0000000000024b40
[67841.023412] x26: 0000000000000012 x25: ffff20202b355ae8 x24: ffff20202b35a8c8
[67841.030779] x23: ffffa36877928208 x22: ffffa368b4972240 x21: ffff8000b979bb18
[67841.038147] x20: ffff00281dc1e3c0 x19: fffffffffffffffe x18: 0000000000000020
[67841.045515] x17: 0000000000000000 x16: ffffa368b128a530 x15: ffffffffffffffff
[67841.052888] x14: ffff8000b979bc18 x13: ffffffffffffffff x12: ffff8000b979bb18
[67841.060263] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa368b1289b18
[67841.067640] x8 : 0000000000000012 x7 : 0000000000000000 x6 : 00000000000003a9
[67841.075014] x5 : 0000000000000000 x4 : ffff002818c5cb00 x3 : 0000000000000001
[67841.082388] x2 : 0000000000000000 x1 : ffff002818c5cb00 x0 : 00000000000000a0
[67841.089759] Call trace:
[67841.092456] down_write+0x30/0x98
[67841.096017] start_creating.part.0+0x60/0x198
[67841.100613] debugfs_create_dir+0x48/0x1f8
[67841.104950] debugfs_create_files_v3_hw+0x88/0x348 [hisi_sas_v3_hw]
[67841.111447] debugfs_snapshot_regs_v3_hw+0x708/0x798 [hisi_sas_v3_hw]
[67841.118111] debugfs_trigger_dump_v3_hw_write+0x9c/0x120 [hisi_sas_v3_hw]
[67841.125115] full_proxy_write+0x68/0xc8
[67841.129175] vfs_write+0xd8/0x3f0
[67841.132708] ksys_write+0x70/0x108
[67841.136317] __arm64_sys_write+0x24/0x38
[67841.140440] invoke_syscall+0x50/0x128
[67841.144385] el0_svc_common.constprop.0+0xc8/0xf0
[67841.149273] do_el0_svc+0x24/0x38
[67841.152773] el0_svc+0x38/0xd8
[67841.156009] el0t_64_sync_handler+0xc0/0xc8
[67841.160361] el0t_64_sync+0x1a4/0x1a8
[67841.164189] Code: b9000882 d2800002 d2800023 f9800011 (c85ffc05)
[67841.170443] ---[ end trace 0000000000000000 ]---
To fix this issue, create all directories and files during debugfs
initialization. In this way, the driver only needs to allocate memory
space to save information each time the user triggers dumping.
Signed-off-by: Yihang Li <liyihang9@huawei.com>
Link: https://lore.kernel.org/r/20241008021822.2617339-13-liyihang9@huawei.com
Reviewed-by: Xingui Yang <yangxingui@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 79 ++++++++++++++++++++------
1 file changed, 61 insertions(+), 18 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index c3d4c7e26b492..3979e1cc43572 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -3467,6 +3467,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off,
return NULL;
}
+static bool debugfs_dump_is_generated_v3_hw(void *p)
+{
+ return p ? true : false;
+}
+
static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
const struct hisi_sas_debugfs_reg *reg)
{
@@ -3492,6 +3497,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p)
{
struct hisi_sas_debugfs_regs *global = s->private;
+ if (!debugfs_dump_is_generated_v3_hw(global->data))
+ return -EPERM;
+
debugfs_print_reg_v3_hw(global->data, s,
&debugfs_global_reg);
@@ -3503,6 +3511,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p)
{
struct hisi_sas_debugfs_regs *axi = s->private;
+ if (!debugfs_dump_is_generated_v3_hw(axi->data))
+ return -EPERM;
+
debugfs_print_reg_v3_hw(axi->data, s,
&debugfs_axi_reg);
@@ -3514,6 +3525,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p)
{
struct hisi_sas_debugfs_regs *ras = s->private;
+ if (!debugfs_dump_is_generated_v3_hw(ras->data))
+ return -EPERM;
+
debugfs_print_reg_v3_hw(ras->data, s,
&debugfs_ras_reg);
@@ -3526,6 +3540,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p)
struct hisi_sas_debugfs_port *port = s->private;
const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg;
+ if (!debugfs_dump_is_generated_v3_hw(port->data))
+ return -EPERM;
+
debugfs_print_reg_v3_hw(port->data, s, reg_port);
return 0;
@@ -3581,6 +3598,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p)
struct hisi_sas_debugfs_cq *debugfs_cq = s->private;
int slot;
+ if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr))
+ return -EPERM;
+
for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq);
@@ -3602,8 +3622,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot,
static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p)
{
+ struct hisi_sas_debugfs_dq *debugfs_dq = s->private;
int slot;
+ if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr))
+ return -EPERM;
+
for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
debugfs_dq_show_slot_v3_hw(s, slot, s->private);
@@ -3617,6 +3641,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p)
struct hisi_sas_iost *iost = debugfs_iost->iost;
int i, max_command_entries = HISI_SAS_MAX_COMMANDS;
+ if (!debugfs_dump_is_generated_v3_hw(iost))
+ return -EPERM;
+
for (i = 0; i < max_command_entries; i++, iost++) {
__le64 *data = &iost->qw0;
@@ -3636,6 +3663,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
int i, tab_idx;
__le64 *iost;
+ if (!debugfs_dump_is_generated_v3_hw(iost_cache))
+ return -EPERM;
+
for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
/*
* Data struct of IOST cache:
@@ -3659,6 +3689,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p)
struct hisi_sas_debugfs_itct *debugfs_itct = s->private;
struct hisi_sas_itct *itct = debugfs_itct->itct;
+ if (!debugfs_dump_is_generated_v3_hw(itct))
+ return -EPERM;
+
for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
__le64 *data = &itct->qw0;
@@ -3678,6 +3711,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
int i, tab_idx;
__le64 *itct;
+ if (!debugfs_dump_is_generated_v3_hw(itct_cache))
+ return -EPERM;
+
for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
/*
* Data struct of ITCT cache:
@@ -3695,10 +3731,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
}
DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw);
-static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
+static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
{
u64 *debugfs_timestamp;
- int dump_index = hisi_hba->debugfs_dump_index;
struct dentry *dump_dentry;
struct dentry *dentry;
char name[256];
@@ -3706,17 +3741,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
int c;
int d;
- snprintf(name, 256, "%d", dump_index);
+ snprintf(name, 256, "%d", index);
dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
- debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index];
+ debugfs_timestamp = &hisi_hba->debugfs_timestamp[index];
debugfs_create_u64("timestamp", 0400, dump_dentry,
debugfs_timestamp);
debugfs_create_file("global", 0400, dump_dentry,
- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL],
+ &hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL],
&debugfs_global_v3_hw_fops);
/* Create port dir and files */
@@ -3725,7 +3760,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
snprintf(name, 256, "%d", p);
debugfs_create_file(name, 0400, dentry,
- &hisi_hba->debugfs_port_reg[dump_index][p],
+ &hisi_hba->debugfs_port_reg[index][p],
&debugfs_port_v3_hw_fops);
}
@@ -3735,7 +3770,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
snprintf(name, 256, "%d", c);
debugfs_create_file(name, 0400, dentry,
- &hisi_hba->debugfs_cq[dump_index][c],
+ &hisi_hba->debugfs_cq[index][c],
&debugfs_cq_v3_hw_fops);
}
@@ -3745,32 +3780,32 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
snprintf(name, 256, "%d", d);
debugfs_create_file(name, 0400, dentry,
- &hisi_hba->debugfs_dq[dump_index][d],
+ &hisi_hba->debugfs_dq[index][d],
&debugfs_dq_v3_hw_fops);
}
debugfs_create_file("iost", 0400, dump_dentry,
- &hisi_hba->debugfs_iost[dump_index],
+ &hisi_hba->debugfs_iost[index],
&debugfs_iost_v3_hw_fops);
debugfs_create_file("iost_cache", 0400, dump_dentry,
- &hisi_hba->debugfs_iost_cache[dump_index],
+ &hisi_hba->debugfs_iost_cache[index],
&debugfs_iost_cache_v3_hw_fops);
debugfs_create_file("itct", 0400, dump_dentry,
- &hisi_hba->debugfs_itct[dump_index],
+ &hisi_hba->debugfs_itct[index],
&debugfs_itct_v3_hw_fops);
debugfs_create_file("itct_cache", 0400, dump_dentry,
- &hisi_hba->debugfs_itct_cache[dump_index],
+ &hisi_hba->debugfs_itct_cache[index],
&debugfs_itct_cache_v3_hw_fops);
debugfs_create_file("axi", 0400, dump_dentry,
- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI],
+ &hisi_hba->debugfs_regs[index][DEBUGFS_AXI],
&debugfs_axi_v3_hw_fops);
debugfs_create_file("ras", 0400, dump_dentry,
- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS],
+ &hisi_hba->debugfs_regs[index][DEBUGFS_RAS],
&debugfs_ras_v3_hw_fops);
}
@@ -4706,8 +4741,6 @@ static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
- debugfs_create_files_v3_hw(hisi_hba);
-
debugfs_snapshot_restore_v3_hw(hisi_hba);
hisi_hba->debugfs_dump_index++;
@@ -4791,6 +4824,17 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
}
+static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba)
+{
+ int i;
+
+ hisi_hba->debugfs_dump_dentry =
+ debugfs_create_dir("dump", hisi_hba->debugfs_dir);
+
+ for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
+ debugfs_create_files_v3_hw(hisi_hba, i);
+}
+
static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
{
debugfs_remove_recursive(hisi_hba->debugfs_dir);
@@ -4811,8 +4855,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
/* create bist structures */
debugfs_bist_init_v3_hw(hisi_hba);
- hisi_hba->debugfs_dump_dentry =
- debugfs_create_dir("dump", hisi_hba->debugfs_dir);
+ debugfs_dump_init_v3_hw(hisi_hba);
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
debugfs_fifo_init_v3_hw(hisi_hba);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0715/1887] bpf: Call free_htab_elem() after htab_unlock_bucket()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (713 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0714/1887] scsi: hisi_sas: Create all dump files during debugfs initialization Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0716/1887] mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM Greg Kroah-Hartman
` (283 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hou Tao, Alexei Starovoitov,
Andrii Nakryiko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <houtao1@huawei.com>
[ Upstream commit b9e9ed90b10c82a4e9d4d70a2890f06bfcdd3b78 ]
For htab of maps, when the map is removed from the htab, it may hold the
last reference of the map. bpf_map_fd_put_ptr() will invoke
bpf_map_free_id() to free the id of the removed map element. However,
bpf_map_fd_put_ptr() is invoked while holding a bucket lock
(raw_spin_lock_t), and bpf_map_free_id() attempts to acquire map_idr_lock
(spinlock_t), triggering the following lockdep warning:
=============================
[ BUG: Invalid wait context ]
6.11.0-rc4+ #49 Not tainted
-----------------------------
test_maps/4881 is trying to lock:
ffffffff84884578 (map_idr_lock){+...}-{3:3}, at: bpf_map_free_id.part.0+0x21/0x70
other info that might help us debug this:
context-{5:5}
2 locks held by test_maps/4881:
#0: ffffffff846caf60 (rcu_read_lock){....}-{1:3}, at: bpf_fd_htab_map_update_elem+0xf9/0x270
#1: ffff888149ced148 (&htab->lockdep_key#2){....}-{2:2}, at: htab_map_update_elem+0x178/0xa80
stack backtrace:
CPU: 0 UID: 0 PID: 4881 Comm: test_maps Not tainted 6.11.0-rc4+ #49
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ...
Call Trace:
<TASK>
dump_stack_lvl+0x6e/0xb0
dump_stack+0x10/0x20
__lock_acquire+0x73e/0x36c0
lock_acquire+0x182/0x450
_raw_spin_lock_irqsave+0x43/0x70
bpf_map_free_id.part.0+0x21/0x70
bpf_map_put+0xcf/0x110
bpf_map_fd_put_ptr+0x9a/0xb0
free_htab_elem+0x69/0xe0
htab_map_update_elem+0x50f/0xa80
bpf_fd_htab_map_update_elem+0x131/0x270
htab_map_update_elem+0x50f/0xa80
bpf_fd_htab_map_update_elem+0x131/0x270
bpf_map_update_value+0x266/0x380
__sys_bpf+0x21bb/0x36b0
__x64_sys_bpf+0x45/0x60
x64_sys_call+0x1b2a/0x20d0
do_syscall_64+0x5d/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e
One way to fix the lockdep warning is using raw_spinlock_t for
map_idr_lock as well. However, bpf_map_alloc_id() invokes
idr_alloc_cyclic() after acquiring map_idr_lock, it will trigger a
similar lockdep warning because the slab's lock (s->cpu_slab->lock) is
still a spinlock.
Instead of changing map_idr_lock's type, fix the issue by invoking
htab_put_fd_value() after htab_unlock_bucket(). However, only deferring
the invocation of htab_put_fd_value() is not enough, because the old map
pointers in htab of maps can not be saved during batched deletion.
Therefore, also defer the invocation of free_htab_elem(), so these
to-be-freed elements could be linked together similar to lru map.
There are four callers for ->map_fd_put_ptr:
(1) alloc_htab_elem() (through htab_put_fd_value())
It invokes ->map_fd_put_ptr() under a raw_spinlock_t. The invocation of
htab_put_fd_value() can not simply move after htab_unlock_bucket(),
because the old element has already been stashed in htab->extra_elems.
It may be reused immediately after htab_unlock_bucket() and the
invocation of htab_put_fd_value() after htab_unlock_bucket() may release
the newly-added element incorrectly. Therefore, saving the map pointer
of the old element for htab of maps before unlocking the bucket and
releasing the map_ptr after unlock. Beside the map pointer in the old
element, should do the same thing for the special fields in the old
element as well.
(2) free_htab_elem() (through htab_put_fd_value())
Its caller includes __htab_map_lookup_and_delete_elem(),
htab_map_delete_elem() and __htab_map_lookup_and_delete_batch().
For htab_map_delete_elem(), simply invoke free_htab_elem() after
htab_unlock_bucket(). For __htab_map_lookup_and_delete_batch(), just
like lru map, linking the to-be-freed element into node_to_free list
and invoking free_htab_elem() for these element after unlock. It is safe
to reuse batch_flink as the link for node_to_free, because these
elements have been removed from the hash llist.
Because htab of maps doesn't support lookup_and_delete operation,
__htab_map_lookup_and_delete_elem() doesn't have the problem, so kept
it as is.
(3) fd_htab_map_free()
It invokes ->map_fd_put_ptr without raw_spinlock_t.
(4) bpf_fd_htab_map_update_elem()
It invokes ->map_fd_put_ptr without raw_spinlock_t.
After moving free_htab_elem() outside htab bucket lock scope, using
pcpu_freelist_push() instead of __pcpu_freelist_push() to disable
the irq before freeing elements, and protecting the invocations of
bpf_mem_cache_free() with migrate_{disable|enable} pair.
Signed-off-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20241106063542.357743-2-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 55 ++++++++++++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 17 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 291c2befa120d..56d2879c64699 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -873,10 +873,12 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
static void htab_elem_free(struct bpf_htab *htab, struct htab_elem *l)
{
+ migrate_disable();
if (htab->map.map_type == BPF_MAP_TYPE_PERCPU_HASH)
bpf_mem_cache_free(&htab->pcpu_ma, l->ptr_to_pptr);
check_and_free_fields(htab, l);
bpf_mem_cache_free(&htab->ma, l);
+ migrate_enable();
}
static void htab_put_fd_value(struct bpf_htab *htab, struct htab_elem *l)
@@ -921,7 +923,7 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
if (htab_is_prealloc(htab)) {
check_and_free_fields(htab, l);
- __pcpu_freelist_push(&htab->freelist, &l->fnode);
+ pcpu_freelist_push(&htab->freelist, &l->fnode);
} else {
dec_elem_count(htab);
htab_elem_free(htab, l);
@@ -994,7 +996,6 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
*/
pl_new = this_cpu_ptr(htab->extra_elems);
l_new = *pl_new;
- htab_put_fd_value(htab, old_elem);
*pl_new = old_elem;
} else {
struct pcpu_freelist_node *l;
@@ -1079,6 +1080,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
struct htab_elem *l_new = NULL, *l_old;
struct hlist_nulls_head *head;
unsigned long flags;
+ void *old_map_ptr;
struct bucket *b;
u32 key_size, hash;
int ret;
@@ -1156,12 +1158,27 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
hlist_nulls_add_head_rcu(&l_new->hash_node, head);
if (l_old) {
hlist_nulls_del_rcu(&l_old->hash_node);
+
+ /* l_old has already been stashed in htab->extra_elems, free
+ * its special fields before it is available for reuse. Also
+ * save the old map pointer in htab of maps before unlock
+ * and release it after unlock.
+ */
+ old_map_ptr = NULL;
+ if (htab_is_prealloc(htab)) {
+ if (map->ops->map_fd_put_ptr)
+ old_map_ptr = fd_htab_map_get_ptr(map, l_old);
+ check_and_free_fields(htab, l_old);
+ }
+ }
+ htab_unlock_bucket(htab, b, hash, flags);
+ if (l_old) {
+ if (old_map_ptr)
+ map->ops->map_fd_put_ptr(map, old_map_ptr, true);
if (!htab_is_prealloc(htab))
free_htab_elem(htab, l_old);
- else
- check_and_free_fields(htab, l_old);
}
- ret = 0;
+ return 0;
err:
htab_unlock_bucket(htab, b, hash, flags);
return ret;
@@ -1398,15 +1415,15 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key)
return ret;
l = lookup_elem_raw(head, hash, key, key_size);
-
- if (l) {
+ if (l)
hlist_nulls_del_rcu(&l->hash_node);
- free_htab_elem(htab, l);
- } else {
+ else
ret = -ENOENT;
- }
htab_unlock_bucket(htab, b, hash, flags);
+
+ if (l)
+ free_htab_elem(htab, l);
return ret;
}
@@ -1824,13 +1841,14 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
* may cause deadlock. See comments in function
* prealloc_lru_pop(). Let us do bpf_lru_push_free()
* after releasing the bucket lock.
+ *
+ * For htab of maps, htab_put_fd_value() in
+ * free_htab_elem() may acquire a spinlock with bucket
+ * lock being held and it violates the lock rule, so
+ * invoke free_htab_elem() after unlock as well.
*/
- if (is_lru_map) {
- l->batch_flink = node_to_free;
- node_to_free = l;
- } else {
- free_htab_elem(htab, l);
- }
+ l->batch_flink = node_to_free;
+ node_to_free = l;
}
dst_key += key_size;
dst_val += value_size;
@@ -1842,7 +1860,10 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
while (node_to_free) {
l = node_to_free;
node_to_free = node_to_free->batch_flink;
- htab_lru_push_free(htab, l);
+ if (is_lru_map)
+ htab_lru_push_free(htab, l);
+ else
+ free_htab_elem(htab, l);
}
next_batch:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0716/1887] mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (714 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0715/1887] bpf: Call free_htab_elem() after htab_unlock_bucket() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0717/1887] net/smc: initialize close_work early to avoid warning Greg Kroah-Hartman
` (282 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand,
syzbot+3511625422f7aa637f0d, Liam R. Howlett, Christoph Lameter,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <david@redhat.com>
[ Upstream commit 091c1dd2d4df6edd1beebe0e5863d4034ade9572 ]
We currently assume that there is at least one VMA in a MM, which isn't
true.
So we might end up having find_vma() return NULL, to then de-reference
NULL. So properly handle find_vma() returning NULL.
This fixes the report:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 1 UID: 0 PID: 6021 Comm: syz-executor284 Not tainted 6.12.0-rc7-syzkaller-00187-gf868cd251776 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/30/2024
RIP: 0010:migrate_to_node mm/mempolicy.c:1090 [inline]
RIP: 0010:do_migrate_pages+0x403/0x6f0 mm/mempolicy.c:1194
Code: ...
RSP: 0018:ffffc9000375fd08 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffffc9000375fd78 RCX: 0000000000000000
RDX: ffff88807e171300 RSI: dffffc0000000000 RDI: ffff88803390c044
RBP: ffff88807e171428 R08: 0000000000000014 R09: fffffbfff2039ef1
R10: ffffffff901cf78f R11: 0000000000000000 R12: 0000000000000003
R13: ffffc9000375fe90 R14: ffffc9000375fe98 R15: ffffc9000375fdf8
FS: 00005555919e1380(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005555919e1ca8 CR3: 000000007f12a000 CR4: 00000000003526f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
kernel_migrate_pages+0x5b2/0x750 mm/mempolicy.c:1709
__do_sys_migrate_pages mm/mempolicy.c:1727 [inline]
__se_sys_migrate_pages mm/mempolicy.c:1723 [inline]
__x64_sys_migrate_pages+0x96/0x100 mm/mempolicy.c:1723
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
[akpm@linux-foundation.org: add unlikely()]
Link: https://lkml.kernel.org/r/20241120201151.9518-1-david@redhat.com
Fixes: 39743889aaf7 ("[PATCH] Swap Migration V5: sys_migrate_pages interface")
Signed-off-by: David Hildenbrand <david@redhat.com>
Reported-by: syzbot+3511625422f7aa637f0d@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/lkml/673d2696.050a0220.3c9d61.012f.GAE@google.com/T/
Reviewed-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
Reviewed-by: Christoph Lameter <cl@linux.com>
Cc: Liam R. Howlett <Liam.Howlett@Oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mempolicy.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 518adfe4ad85b..c4a38d1b695f0 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1068,6 +1068,8 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,
* space range and MPOL_MF_DISCONTIG_OK, this call can not fail.
*/
vma = find_vma(mm, 0);
+ if (unlikely(!vma))
+ return 0;
VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)));
queue_pages_range(mm, vma->vm_start, mm->task_size, &nmask,
flags | MPOL_MF_DISCONTIG_OK, &pagelist);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0717/1887] net/smc: initialize close_work early to avoid warning
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (715 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0716/1887] mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0718/1887] f2fs: fix to do sanity check on node blkaddr in truncate_node() Greg Kroah-Hartman
` (281 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wen Gu, Wenjia Zhang,
Alexandra Winter, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <guwen@linux.alibaba.com>
[ Upstream commit 0541db8ee32c09463a72d0987382b3a3336b0043 ]
We encountered a warning that close_work was canceled before
initialization.
WARNING: CPU: 7 PID: 111103 at kernel/workqueue.c:3047 __flush_work+0x19e/0x1b0
Workqueue: events smc_lgr_terminate_work [smc]
RIP: 0010:__flush_work+0x19e/0x1b0
Call Trace:
? __wake_up_common+0x7a/0x190
? work_busy+0x80/0x80
__cancel_work_timer+0xe3/0x160
smc_close_cancel_work+0x1a/0x70 [smc]
smc_close_active_abort+0x207/0x360 [smc]
__smc_lgr_terminate.part.38+0xc8/0x180 [smc]
process_one_work+0x19e/0x340
worker_thread+0x30/0x370
? process_one_work+0x340/0x340
kthread+0x117/0x130
? __kthread_cancel_work+0x50/0x50
ret_from_fork+0x22/0x30
This is because when smc_close_cancel_work is triggered, e.g. the RDMA
driver is rmmod and the LGR is terminated, the conn->close_work is
flushed before initialization, resulting in WARN_ON(!work->func).
__smc_lgr_terminate | smc_connect_{rdma|ism}
-------------------------------------------------------------
| smc_conn_create
| \- smc_lgr_register_conn
for conn in lgr->conns_all |
\- smc_conn_kill |
\- smc_close_active_abort |
\- smc_close_cancel_work |
\- cancel_work_sync |
\- __flush_work |
(close_work) |
| smc_close_init
| \- INIT_WORK(&close_work)
So fix this by initializing close_work before establishing the
connection.
Fixes: 46c28dbd4c23 ("net/smc: no socket state changes in tasklet context")
Fixes: 413498440e30 ("net/smc: add SMC-D support in af_smc")
Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/af_smc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 35cf30486916e..71ceaab9b6dd3 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -406,6 +406,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
sk_refcnt_debug_inc(sk);
mutex_init(&smc->clcsock_release_lock);
smc_init_saved_callbacks(smc);
+ smc_close_init(smc);
return sk;
}
@@ -1277,7 +1278,6 @@ static int smc_connect_rdma(struct smc_sock *smc,
goto connect_abort;
}
- smc_close_init(smc);
smc_rx_init(smc);
if (ini->first_contact_local) {
@@ -1397,7 +1397,6 @@ static int smc_connect_ism(struct smc_sock *smc,
}
smc_conn_save_peer_info(smc, aclc);
- smc_close_init(smc);
smc_rx_init(smc);
smc_tx_init(smc);
@@ -2430,7 +2429,6 @@ static void smc_listen_work(struct work_struct *work)
goto out_decl;
mutex_lock(&smc_server_lgr_pending);
- smc_close_init(new_smc);
smc_rx_init(new_smc);
smc_tx_init(new_smc);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0718/1887] f2fs: fix to do sanity check on node blkaddr in truncate_node()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (716 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0717/1887] net/smc: initialize close_work early to avoid warning Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0719/1887] udmabuf: fix memory leak on last export_udmabuf() error path Greg Kroah-Hartman
` (280 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+33379ce4ac76acf7d0c7, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 6babe00ccd34fc65b78ef8b99754e32b4385f23d ]
syzbot reports a f2fs bug as below:
------------[ cut here ]------------
kernel BUG at fs/f2fs/segment.c:2534!
RIP: 0010:f2fs_invalidate_blocks+0x35f/0x370 fs/f2fs/segment.c:2534
Call Trace:
truncate_node+0x1ae/0x8c0 fs/f2fs/node.c:909
f2fs_remove_inode_page+0x5c2/0x870 fs/f2fs/node.c:1288
f2fs_evict_inode+0x879/0x15c0 fs/f2fs/inode.c:856
evict+0x4e8/0x9b0 fs/inode.c:723
f2fs_handle_failed_inode+0x271/0x2e0 fs/f2fs/inode.c:986
f2fs_create+0x357/0x530 fs/f2fs/namei.c:394
lookup_open fs/namei.c:3595 [inline]
open_last_lookups fs/namei.c:3694 [inline]
path_openat+0x1c03/0x3590 fs/namei.c:3930
do_filp_open+0x235/0x490 fs/namei.c:3960
do_sys_openat2+0x13e/0x1d0 fs/open.c:1415
do_sys_open fs/open.c:1430 [inline]
__do_sys_openat fs/open.c:1446 [inline]
__se_sys_openat fs/open.c:1441 [inline]
__x64_sys_openat+0x247/0x2a0 fs/open.c:1441
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0010:f2fs_invalidate_blocks+0x35f/0x370 fs/f2fs/segment.c:2534
The root cause is: on a fuzzed image, blkaddr in nat entry may be
corrupted, then it will cause system panic when using it in
f2fs_invalidate_blocks(), to avoid this, let's add sanity check on
nat blkaddr in truncate_node().
Reported-by: syzbot+33379ce4ac76acf7d0c7@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/0000000000009a6cd706224ca720@google.com/
Cc: stable@vger.kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/node.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 9d4ec1a061bfb..8b4e8e251649c 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -918,6 +918,16 @@ static int truncate_node(struct dnode_of_data *dn)
if (err)
return err;
+ if (ni.blk_addr != NEW_ADDR &&
+ !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC_ENHANCE)) {
+ f2fs_err(sbi,
+ "nat entry is corrupted, run fsck to fix it, ino:%u, "
+ "nid:%u, blkaddr:%u", ni.ino, ni.nid, ni.blk_addr);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_handle_error(sbi, ERROR_INCONSISTENT_NAT);
+ return -EFSCORRUPTED;
+ }
+
/* Deallocate node address */
f2fs_invalidate_blocks(sbi, ni.blk_addr);
dec_valid_node_count(sbi, dn->inode, dn->nid == dn->inode->i_ino);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0719/1887] udmabuf: fix memory leak on last export_udmabuf() error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (717 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0718/1887] f2fs: fix to do sanity check on node blkaddr in truncate_node() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0720/1887] smb: Initialize cfid->tcon before performing network ops Greg Kroah-Hartman
` (279 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vivek Kasireddy, Jann Horn,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <jannh@google.com>
[ Upstream commit f49856f525acd5bef52ae28b7da2e001bbe7439e ]
In export_udmabuf(), if dma_buf_fd() fails because the FD table is full, a
dma_buf owning the udmabuf has already been created; but the error handling
in udmabuf_create() will tear down the udmabuf without doing anything about
the containing dma_buf.
This leaves a dma_buf in memory that contains a dangling pointer; though
that doesn't seem to lead to anything bad except a memory leak.
Fix it by moving the dma_buf_fd() call out of export_udmabuf() so that we
can give it different error handling.
Note that the shape of this code changed a lot in commit 5e72b2b41a21
("udmabuf: convert udmabuf driver to use folios"); but the memory leak
seems to have existed since the introduction of udmabuf.
Fixes: fbb0de795078 ("Add udmabuf misc device")
Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241204-udmabuf-fixes-v2-3-23887289de1c@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma-buf/udmabuf.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 6277c5b8d1251..3ba3574510743 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -289,7 +289,16 @@ static long udmabuf_create(struct miscdevice *device,
flags = 0;
if (head->flags & UDMABUF_FLAGS_CLOEXEC)
flags |= O_CLOEXEC;
- return dma_buf_fd(buf, flags);
+
+ /*
+ * Ownership of ubuf is held by the dmabuf from here.
+ * If the following dma_buf_fd() fails, dma_buf_put() cleans up both the
+ * dmabuf and the ubuf (through udmabuf_ops.release).
+ */
+ ret = dma_buf_fd(buf, flags);
+ if (ret < 0)
+ dma_buf_put(buf);
+ return ret;
err:
while (pgbuf > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0720/1887] smb: Initialize cfid->tcon before performing network ops
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (718 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0719/1887] udmabuf: fix memory leak on last export_udmabuf() error path Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0721/1887] vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages() Greg Kroah-Hartman
` (278 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Paul Aurich, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <paul@darkrain42.org>
[ Upstream commit c353ee4fb119a2582d0e011f66a76a38f5cf984d ]
Avoid leaking a tcon ref when a lease break races with opening the
cached directory. Processing the leak break might take a reference to
the tcon in cached_dir_lease_break() and then fail to release the ref in
cached_dir_offload_close, since cfid->tcon is still NULL.
Fixes: ebe98f1447bb ("cifs: enable caching of directories for which a lease is held")
Signed-off-by: Paul Aurich <paul@darkrain42.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cached_dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index 194cf24f52df9..baca533953fd1 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -211,6 +211,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
}
}
cfid->dentry = dentry;
+ cfid->tcon = tcon;
/*
* We do not hold the lock for the open because in case
@@ -284,7 +285,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
}
goto oshr_free;
}
- cfid->tcon = tcon;
cfid->is_open = true;
spin_lock(&cfids->cfid_list_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0721/1887] vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (719 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0720/1887] smb: Initialize cfid->tcon before performing network ops Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0722/1887] scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs Greg Kroah-Hartman
` (277 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yishai Hadas, Jason Gunthorpe,
Alex Williamson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <yishaih@nvidia.com>
[ Upstream commit 22e87bf3f77c18f5982c19ffe2732ef0c7a25f16 ]
Fix an unwind issue in mlx5vf_add_migration_pages().
If a set of pages is allocated but fails to be added to the SG table,
they need to be freed to prevent a memory leak.
Any pages successfully added to the SG table will be freed as part of
mlx5vf_free_data_buffer().
Fixes: 6fadb021266d ("vfio/mlx5: Implement vfio_pci driver for mlx5 devices")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20241114095318.16556-2-yishaih@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vfio/pci/mlx5/main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c
index fd6ccb8454a24..191d4c7b686a7 100644
--- a/drivers/vfio/pci/mlx5/main.c
+++ b/drivers/vfio/pci/mlx5/main.c
@@ -71,6 +71,7 @@ static int mlx5vf_add_migration_pages(struct mlx5_vf_migration_file *migf,
unsigned long filled;
unsigned int to_fill;
int ret;
+ int i;
to_fill = min_t(unsigned int, npages, PAGE_SIZE / sizeof(*page_list));
page_list = kvzalloc(to_fill * sizeof(*page_list), GFP_KERNEL);
@@ -90,7 +91,7 @@ static int mlx5vf_add_migration_pages(struct mlx5_vf_migration_file *migf,
GFP_KERNEL);
if (ret)
- goto err;
+ goto err_append;
migf->allocated_length += filled * PAGE_SIZE;
/* clean input for another bulk allocation */
memset(page_list, 0, filled * sizeof(*page_list));
@@ -101,6 +102,9 @@ static int mlx5vf_add_migration_pages(struct mlx5_vf_migration_file *migf,
kvfree(page_list);
return 0;
+err_append:
+ for (i = filled - 1; i >= 0; i--)
+ __free_page(page_list[i]);
err:
kvfree(page_list);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0722/1887] scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (720 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0721/1887] vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages() Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:46 ` [PATCH 6.1 0723/1887] workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker Greg Kroah-Hartman
` (276 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Prayas Patel, Ranjan Kumar,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <ranjan.kumar@broadcom.com>
[ Upstream commit 711201a8b8334a397440ac0b859df0054e174bc9 ]
The driver, through the SAS transport, exposes a sysfs interface to
enable/disable PHYs in a controller/expander setup. When multiple PHYs
are disabled and enabled in rapid succession, the persistent and current
config pages related to SAS IO unit/SAS Expander pages could get
corrupted.
Use separate memory for each config request.
Signed-off-by: Prayas Patel <prayas.patel@broadcom.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
Link: https://lore.kernel.org/r/20241110194405.10108-3-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpi3mr/mpi3mr.h | 9 ----
drivers/scsi/mpi3mr/mpi3mr_fw.c | 81 ++++++---------------------------
2 files changed, 13 insertions(+), 77 deletions(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index ffeadd1e3543b..982629a0ec803 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -130,8 +130,6 @@ extern atomic64_t event_counter;
#define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */
-#define MPI3MR_DEFAULT_CFG_PAGE_SZ 1024 /* in bytes */
-
#define MPI3MR_RESET_TOPOLOGY_SETTLE_TIME 10
#define MPI3MR_SCMD_TIMEOUT (60 * HZ)
@@ -1013,9 +1011,6 @@ struct scmd_priv {
* @io_throttle_low: I/O size to stop throttle in 512b blocks
* @num_io_throttle_group: Maximum number of throttle groups
* @throttle_groups: Pointer to throttle group info structures
- * @cfg_page: Default memory for configuration pages
- * @cfg_page_dma: Configuration page DMA address
- * @cfg_page_sz: Default configuration page memory size
* @sas_transport_enabled: SAS transport enabled or not
* @scsi_device_channel: Channel ID for SCSI devices
* @transport_cmds: Command tracker for SAS transport commands
@@ -1198,10 +1193,6 @@ struct mpi3mr_ioc {
u16 num_io_throttle_group;
struct mpi3mr_throttle_group_info *throttle_groups;
- void *cfg_page;
- dma_addr_t cfg_page_dma;
- u16 cfg_page_sz;
-
u8 sas_transport_enabled;
u8 scsi_device_channel;
struct mpi3mr_drv_cmd transport_cmds;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index d4747ff4d800a..c14bee07f8c10 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -3864,17 +3864,6 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
mpi3mr_print_ioc_info(mrioc);
- if (!mrioc->cfg_page) {
- dprint_init(mrioc, "allocating config page buffers\n");
- mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ;
- mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev,
- mrioc->cfg_page_sz, &mrioc->cfg_page_dma, GFP_KERNEL);
- if (!mrioc->cfg_page) {
- retval = -1;
- goto out_failed_noretry;
- }
- }
-
if (!mrioc->init_cmds.reply) {
retval = mpi3mr_alloc_reply_sense_bufs(mrioc);
if (retval) {
@@ -4418,11 +4407,7 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
mrioc->admin_req_base, mrioc->admin_req_dma);
mrioc->admin_req_base = NULL;
}
- if (mrioc->cfg_page) {
- dma_free_coherent(&mrioc->pdev->dev, mrioc->cfg_page_sz,
- mrioc->cfg_page, mrioc->cfg_page_dma);
- mrioc->cfg_page = NULL;
- }
+
if (mrioc->pel_seqnum_virt) {
dma_free_coherent(&mrioc->pdev->dev, mrioc->pel_seqnum_sz,
mrioc->pel_seqnum_virt, mrioc->pel_seqnum_dma);
@@ -5007,55 +4992,6 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
return retval;
}
-
-/**
- * mpi3mr_free_config_dma_memory - free memory for config page
- * @mrioc: Adapter instance reference
- * @mem_desc: memory descriptor structure
- *
- * Check whether the size of the buffer specified by the memory
- * descriptor is greater than the default page size if so then
- * free the memory pointed by the descriptor.
- *
- * Return: Nothing.
- */
-static void mpi3mr_free_config_dma_memory(struct mpi3mr_ioc *mrioc,
- struct dma_memory_desc *mem_desc)
-{
- if ((mem_desc->size > mrioc->cfg_page_sz) && mem_desc->addr) {
- dma_free_coherent(&mrioc->pdev->dev, mem_desc->size,
- mem_desc->addr, mem_desc->dma_addr);
- mem_desc->addr = NULL;
- }
-}
-
-/**
- * mpi3mr_alloc_config_dma_memory - Alloc memory for config page
- * @mrioc: Adapter instance reference
- * @mem_desc: Memory descriptor to hold dma memory info
- *
- * This function allocates new dmaable memory or provides the
- * default config page dmaable memory based on the memory size
- * described by the descriptor.
- *
- * Return: 0 on success, non-zero on failure.
- */
-static int mpi3mr_alloc_config_dma_memory(struct mpi3mr_ioc *mrioc,
- struct dma_memory_desc *mem_desc)
-{
- if (mem_desc->size > mrioc->cfg_page_sz) {
- mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev,
- mem_desc->size, &mem_desc->dma_addr, GFP_KERNEL);
- if (!mem_desc->addr)
- return -ENOMEM;
- } else {
- mem_desc->addr = mrioc->cfg_page;
- mem_desc->dma_addr = mrioc->cfg_page_dma;
- memset(mem_desc->addr, 0, mrioc->cfg_page_sz);
- }
- return 0;
-}
-
/**
* mpi3mr_post_cfg_req - Issue config requests and wait
* @mrioc: Adapter instance reference
@@ -5211,8 +5147,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
cfg_req->page_length = cfg_hdr->page_length;
cfg_req->page_version = cfg_hdr->page_version;
}
- if (mpi3mr_alloc_config_dma_memory(mrioc, &mem_desc))
- goto out;
+
+ mem_desc.addr = dma_alloc_coherent(&mrioc->pdev->dev,
+ mem_desc.size, &mem_desc.dma_addr, GFP_KERNEL);
+
+ if (!mem_desc.addr)
+ return retval;
mpi3mr_add_sg_single(&cfg_req->sgl, sgl_flags, mem_desc.size,
mem_desc.dma_addr);
@@ -5241,7 +5181,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
}
out:
- mpi3mr_free_config_dma_memory(mrioc, &mem_desc);
+ if (mem_desc.addr) {
+ dma_free_coherent(&mrioc->pdev->dev, mem_desc.size,
+ mem_desc.addr, mem_desc.dma_addr);
+ mem_desc.addr = NULL;
+ }
+
return retval;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0723/1887] workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (721 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0722/1887] scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs Greg Kroah-Hartman
@ 2026-10-28 16:46 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0724/1887] udp: Deal with race between UDP socket address change and rehash Greg Kroah-Hartman
` (275 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tvrtko Ursulin, Tejun Heo,
Peter Zijlstra, Lai Jiangshan, Alex Deucher, Matthew Brost,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
[ Upstream commit de35994ecd2dd6148ab5a6c5050a1670a04dec77 ]
After commit
746ae46c1113 ("drm/sched: Mark scheduler work queues with WQ_MEM_RECLAIM")
amdgpu started seeing the following warning:
[ ] workqueue: WQ_MEM_RECLAIM sdma0:drm_sched_run_job_work [gpu_sched] is flushing !WQ_MEM_RECLAIM events:amdgpu_device_delay_enable_gfx_off [amdgpu]
...
[ ] Workqueue: sdma0 drm_sched_run_job_work [gpu_sched]
...
[ ] Call Trace:
[ ] <TASK>
...
[ ] ? check_flush_dependency+0xf5/0x110
...
[ ] cancel_delayed_work_sync+0x6e/0x80
[ ] amdgpu_gfx_off_ctrl+0xab/0x140 [amdgpu]
[ ] amdgpu_ring_alloc+0x40/0x50 [amdgpu]
[ ] amdgpu_ib_schedule+0xf4/0x810 [amdgpu]
[ ] ? drm_sched_run_job_work+0x22c/0x430 [gpu_sched]
[ ] amdgpu_job_run+0xaa/0x1f0 [amdgpu]
[ ] drm_sched_run_job_work+0x257/0x430 [gpu_sched]
[ ] process_one_work+0x217/0x720
...
[ ] </TASK>
The intent of the verifcation done in check_flush_depedency is to ensure
forward progress during memory reclaim, by flagging cases when either a
memory reclaim process, or a memory reclaim work item is flushed from a
context not marked as memory reclaim safe.
This is correct when flushing, but when called from the
cancel(_delayed)_work_sync() paths it is a false positive because work is
either already running, or will not be running at all. Therefore
cancelling it is safe and we can relax the warning criteria by letting the
helper know of the calling context.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fixes: fca839c00a12 ("workqueue: warn if memory reclaim tries to flush !WQ_MEM_RECLAIM workqueue")
References: 746ae46c1113 ("drm/sched: Mark scheduler work queues with WQ_MEM_RECLAIM")
Cc: Tejun Heo <tj@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <stable@vger.kernel.org> # v4.5+
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/workqueue.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 0e6aa523ef557..70d6e7779c2e6 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2607,23 +2607,27 @@ static int rescuer_thread(void *__rescuer)
* check_flush_dependency - check for flush dependency sanity
* @target_wq: workqueue being flushed
* @target_work: work item being flushed (NULL for workqueue flushes)
+ * @from_cancel: are we called from the work cancel path
*
* %current is trying to flush the whole @target_wq or @target_work on it.
- * If @target_wq doesn't have %WQ_MEM_RECLAIM, verify that %current is not
- * reclaiming memory or running on a workqueue which doesn't have
- * %WQ_MEM_RECLAIM as that can break forward-progress guarantee leading to
- * a deadlock.
+ * If this is not the cancel path (which implies work being flushed is either
+ * already running, or will not be at all), check if @target_wq doesn't have
+ * %WQ_MEM_RECLAIM and verify that %current is not reclaiming memory or running
+ * on a workqueue which doesn't have %WQ_MEM_RECLAIM as that can break forward-
+ * progress guarantee leading to a deadlock.
*/
static void check_flush_dependency(struct workqueue_struct *target_wq,
- struct work_struct *target_work)
+ struct work_struct *target_work,
+ bool from_cancel)
{
- work_func_t target_func = target_work ? target_work->func : NULL;
+ work_func_t target_func;
struct worker *worker;
- if (target_wq->flags & WQ_MEM_RECLAIM)
+ if (from_cancel || target_wq->flags & WQ_MEM_RECLAIM)
return;
worker = current_wq_worker();
+ target_func = target_work ? target_work->func : NULL;
WARN_ONCE(current->flags & PF_MEMALLOC,
"workqueue: PF_MEMALLOC task %d(%s) is flushing !WQ_MEM_RECLAIM %s:%ps",
@@ -2857,7 +2861,7 @@ void __flush_workqueue(struct workqueue_struct *wq)
list_add_tail(&this_flusher.list, &wq->flusher_overflow);
}
- check_flush_dependency(wq, NULL);
+ check_flush_dependency(wq, NULL, false);
mutex_unlock(&wq->mutex);
@@ -3032,7 +3036,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
pwq = worker->current_pwq;
}
- check_flush_dependency(pwq->wq, work);
+ check_flush_dependency(pwq->wq, work, from_cancel);
insert_wq_barrier(pwq, barr, work, worker);
raw_spin_unlock_irq(&pool->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0724/1887] udp: Deal with race between UDP socket address change and rehash
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (722 preceding siblings ...)
2026-10-28 16:46 ` [PATCH 6.1 0723/1887] workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from !WQ_MEM_RECLAIM worker Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0725/1887] btrfs: do proper folio cleanup when cow_file_range() failed Greg Kroah-Hartman
` (274 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ed Santiago, Stefano Brivio,
Eric Dumazet, Willem de Bruijn, David S. Miller, Sasha Levin,
David Gibson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Brivio <sbrivio@redhat.com>
[ Upstream commit a502ea6fa94b1f7be72a24bcf9e3f5f6b7e6e90c ]
If a UDP socket changes its local address while it's receiving
datagrams, as a result of connect(), there is a period during which
a lookup operation might fail to find it, after the address is changed
but before the secondary hash (port and address) and the four-tuple
hash (local and remote ports and addresses) are updated.
Secondary hash chains were introduced by commit 30fff9231fad ("udp:
bind() optimisation") and, as a result, a rehash operation became
needed to make a bound socket reachable again after a connect().
This operation was introduced by commit 719f835853a9 ("udp: add
rehash on connect()") which isn't however a complete fix: the
socket will be found once the rehashing completes, but not while
it's pending.
This is noticeable with a socat(1) server in UDP4-LISTEN mode, and a
client sending datagrams to it. After the server receives the first
datagram (cf. _xioopen_ipdgram_listen()), it issues a connect() to
the address of the sender, in order to set up a directed flow.
Now, if the client, running on a different CPU thread, happens to
send a (subsequent) datagram while the server's socket changes its
address, but is not rehashed yet, this will result in a failed
lookup and a port unreachable error delivered to the client, as
apparent from the following reproducer:
LEN=$(($(cat /proc/sys/net/core/wmem_default) / 4))
dd if=/dev/urandom bs=1 count=${LEN} of=tmp.in
while :; do
taskset -c 1 socat UDP4-LISTEN:1337,null-eof OPEN:tmp.out,create,trunc &
sleep 0.1 || sleep 1
taskset -c 2 socat OPEN:tmp.in UDP4:localhost:1337,shut-null
wait
done
where the client will eventually get ECONNREFUSED on a write()
(typically the second or third one of a given iteration):
2024/11/13 21:28:23 socat[46901] E write(6, 0x556db2e3c000, 8192): Connection refused
This issue was first observed as a seldom failure in Podman's tests
checking UDP functionality while using pasta(1) to connect the
container's network namespace, which leads us to a reproducer with
the lookup error resulting in an ICMP packet on a tap device:
LOCAL_ADDR="$(ip -j -4 addr show|jq -rM '.[] | .addr_info[0] | select(.scope == "global").local')"
while :; do
./pasta --config-net -p pasta.pcap -u 1337 socat UDP4-LISTEN:1337,null-eof OPEN:tmp.out,create,trunc &
sleep 0.2 || sleep 1
socat OPEN:tmp.in UDP4:${LOCAL_ADDR}:1337,shut-null
wait
cmp tmp.in tmp.out
done
Once this fails:
tmp.in tmp.out differ: char 8193, line 29
we can finally have a look at what's going on:
$ tshark -r pasta.pcap
1 0.000000 :: ? ff02::16 ICMPv6 110 Multicast Listener Report Message v2
2 0.168690 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
3 0.168767 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
4 0.168806 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
5 0.168827 c6:47:05:8d:dc:04 ? Broadcast ARP 42 Who has 88.198.0.161? Tell 88.198.0.164
6 0.168851 9a:55:9a:55:9a:55 ? c6:47:05:8d:dc:04 ARP 42 88.198.0.161 is at 9a:55:9a:55:9a:55
7 0.168875 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
8 0.168896 88.198.0.164 ? 88.198.0.161 ICMP 590 Destination unreachable (Port unreachable)
9 0.168926 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
10 0.168959 88.198.0.161 ? 88.198.0.164 UDP 8234 60260 ? 1337 Len=8192
11 0.168989 88.198.0.161 ? 88.198.0.164 UDP 4138 60260 ? 1337 Len=4096
12 0.169010 88.198.0.161 ? 88.198.0.164 UDP 42 60260 ? 1337 Len=0
On the third datagram received, the network namespace of the container
initiates an ARP lookup to deliver the ICMP message.
In another variant of this reproducer, starting the client with:
strace -f pasta --config-net -u 1337 socat UDP4-LISTEN:1337,null-eof OPEN:tmp.out,create,trunc 2>strace.log &
and connecting to the socat server using a loopback address:
socat OPEN:tmp.in UDP4:localhost:1337,shut-null
we can more clearly observe a sendmmsg() call failing after the
first datagram is delivered:
[pid 278012] connect(173, 0x7fff96c95fc0, 16) = 0
[...]
[pid 278012] recvmmsg(173, 0x7fff96c96020, 1024, MSG_DONTWAIT, NULL) = -1 EAGAIN (Resource temporarily unavailable)
[pid 278012] sendmmsg(173, 0x561c5ad0a720, 1, MSG_NOSIGNAL) = 1
[...]
[pid 278012] sendmmsg(173, 0x561c5ad0a720, 1, MSG_NOSIGNAL) = -1 ECONNREFUSED (Connection refused)
and, somewhat confusingly, after a connect() on the same socket
succeeded.
Until commit 4cdeeee9252a ("net: udp: prefer listeners bound to an
address"), the race between receive address change and lookup didn't
actually cause visible issues, because, once the lookup based on the
secondary hash chain failed, we would still attempt a lookup based on
the primary hash (destination port only), and find the socket with the
outdated secondary hash.
That change, however, dropped port-only lookups altogether, as side
effect, making the race visible.
To fix this, while avoiding the need to make address changes and
rehash atomic against lookups, reintroduce primary hash lookups as
fallback, if lookups based on four-tuple and secondary hashes fail.
To this end, introduce a simplified lookup implementation, which
doesn't take care of SO_REUSEPORT groups: if we have one, there are
multiple sockets that would match the four-tuple or secondary hash,
meaning that we can't run into this race at all.
v2:
- instead of synchronising lookup operations against address change
plus rehash, reintroduce a simplified version of the original
primary hash lookup as fallback
v1:
- fix build with CONFIG_IPV6=n: add ifdef around sk_v6_rcv_saddr
usage (Kuniyuki Iwashima)
- directly use sk_rcv_saddr for IPv4 receive addresses instead of
fetching inet_rcv_saddr (Kuniyuki Iwashima)
- move inet_update_saddr() to inet_hashtables.h and use that
to set IPv4/IPv6 addresses as suitable (Kuniyuki Iwashima)
- rebase onto net-next, update commit message accordingly
Reported-by: Ed Santiago <santiago@redhat.com>
Link: https://github.com/containers/podman/issues/24147
Analysed-by: David Gibson <david@gibson.dropbear.id.au>
Fixes: 30fff9231fad ("udp: bind() optimisation")
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/udp.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/udp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6f745efa0db4b..271bf781fe54b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -414,6 +414,49 @@ u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport,
udp_ehash_secret + net_hash_mix(net));
}
+/**
+ * udp4_lib_lookup1() - Simplified lookup using primary hash (destination port)
+ * @net: Network namespace
+ * @saddr: Source address, network order
+ * @sport: Source port, network order
+ * @daddr: Destination address, network order
+ * @hnum: Destination port, host order
+ * @dif: Destination interface index
+ * @sdif: Destination bridge port index, if relevant
+ * @udptable: Set of UDP hash tables
+ *
+ * Simplified lookup to be used as fallback if no sockets are found due to a
+ * potential race between (receive) address change, and lookup happening before
+ * the rehash operation. This function ignores SO_REUSEPORT groups while scoring
+ * result sockets, because if we have one, we don't need the fallback at all.
+ *
+ * Called under rcu_read_lock().
+ *
+ * Return: socket with highest matching score if any, NULL if none
+ */
+static struct sock *udp4_lib_lookup1(struct net *net,
+ __be32 saddr, __be16 sport,
+ __be32 daddr, unsigned int hnum,
+ int dif, int sdif,
+ const struct udp_table *udptable)
+{
+ unsigned int slot = udp_hashfn(net, hnum, udptable->mask);
+ struct udp_hslot *hslot = &udptable->hash[slot];
+ struct sock *sk, *result = NULL;
+ int score, badness = 0;
+
+ sk_for_each_rcu(sk, &hslot->head) {
+ score = compute_score(sk, net,
+ saddr, sport, daddr, hnum, dif, sdif);
+ if (score > badness) {
+ result = sk;
+ badness = score;
+ }
+ }
+
+ return result;
+}
+
/* called with rcu_read_lock() */
static struct sock *udp4_lib_lookup2(struct net *net,
__be32 saddr, __be16 sport,
@@ -541,6 +584,19 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
result = udp4_lib_lookup2(net, saddr, sport,
htonl(INADDR_ANY), hnum, dif, sdif,
hslot2, skb);
+ if (!IS_ERR_OR_NULL(result))
+ goto done;
+
+ /* Primary hash (destination port) lookup as fallback for this race:
+ * 1. __ip4_datagram_connect() sets sk_rcv_saddr
+ * 2. lookup (this function): new sk_rcv_saddr, hashes not updated yet
+ * 3. rehash operation updating _secondary and four-tuple_ hashes
+ * The primary hash doesn't need an update after 1., so, thanks to this
+ * further step, 1. and 3. don't need to be atomic against the lookup.
+ */
+ result = udp4_lib_lookup1(net, saddr, sport, daddr, hnum, dif, sdif,
+ udptable);
+
done:
if (IS_ERR(result))
return NULL;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 96a46dc473360..8697f473357c2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -160,6 +160,49 @@ static int compute_score(struct sock *sk, struct net *net,
return score;
}
+/**
+ * udp6_lib_lookup1() - Simplified lookup using primary hash (destination port)
+ * @net: Network namespace
+ * @saddr: Source address, network order
+ * @sport: Source port, network order
+ * @daddr: Destination address, network order
+ * @hnum: Destination port, host order
+ * @dif: Destination interface index
+ * @sdif: Destination bridge port index, if relevant
+ * @udptable: Set of UDP hash tables
+ *
+ * Simplified lookup to be used as fallback if no sockets are found due to a
+ * potential race between (receive) address change, and lookup happening before
+ * the rehash operation. This function ignores SO_REUSEPORT groups while scoring
+ * result sockets, because if we have one, we don't need the fallback at all.
+ *
+ * Called under rcu_read_lock().
+ *
+ * Return: socket with highest matching score if any, NULL if none
+ */
+static struct sock *udp6_lib_lookup1(struct net *net,
+ const struct in6_addr *saddr, __be16 sport,
+ const struct in6_addr *daddr,
+ unsigned int hnum, int dif, int sdif,
+ const struct udp_table *udptable)
+{
+ unsigned int slot = udp_hashfn(net, hnum, udptable->mask);
+ struct udp_hslot *hslot = &udptable->hash[slot];
+ struct sock *sk, *result = NULL;
+ int score, badness = 0;
+
+ sk_for_each_rcu(sk, &hslot->head) {
+ score = compute_score(sk, net,
+ saddr, sport, daddr, hnum, dif, sdif);
+ if (score > badness) {
+ result = sk;
+ badness = score;
+ }
+ }
+
+ return result;
+}
+
/* called with rcu_read_lock() */
static struct sock *udp6_lib_lookup2(struct net *net,
const struct in6_addr *saddr, __be16 sport,
@@ -288,6 +331,13 @@ struct sock *__udp6_lib_lookup(struct net *net,
result = udp6_lib_lookup2(net, saddr, sport,
&in6addr_any, hnum, dif, sdif,
hslot2, skb);
+ if (!IS_ERR_OR_NULL(result))
+ goto done;
+
+ /* Cover address change/lookup/rehash race: see __udp4_lib_lookup() */
+ result = udp6_lib_lookup1(net, saddr, sport, daddr, hnum, dif, sdif,
+ udptable);
+
done:
if (IS_ERR(result))
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0725/1887] btrfs: do proper folio cleanup when cow_file_range() failed
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (723 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0724/1887] udp: Deal with race between UDP socket address change and rehash Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0726/1887] xfrm: state: fix out-of-bounds read during lookup Greg Kroah-Hartman
` (273 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Boris Burkov, Qu Wenruo,
David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit 06f364284794f149d2abc167c11d556cf20c954b ]
[BUG]
When testing with COW fixup marked as BUG_ON() (this is involved with the
new pin_user_pages*() change, which should not result new out-of-band
dirty pages), I hit a crash triggered by the BUG_ON() from hitting COW
fixup path.
This BUG_ON() happens just after a failed btrfs_run_delalloc_range():
BTRFS error (device dm-2): failed to run delalloc range, root 348 ino 405 folio 65536 submit_bitmap 6-15 start 90112 len 106496: -28
------------[ cut here ]------------
kernel BUG at fs/btrfs/extent_io.c:1444!
Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
CPU: 0 UID: 0 PID: 434621 Comm: kworker/u24:8 Tainted: G OE 6.12.0-rc7-custom+ #86
Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs]
pc : extent_writepage_io+0x2d4/0x308 [btrfs]
lr : extent_writepage_io+0x2d4/0x308 [btrfs]
Call trace:
extent_writepage_io+0x2d4/0x308 [btrfs]
extent_writepage+0x218/0x330 [btrfs]
extent_write_cache_pages+0x1d4/0x4b0 [btrfs]
btrfs_writepages+0x94/0x150 [btrfs]
do_writepages+0x74/0x190
filemap_fdatawrite_wbc+0x88/0xc8
start_delalloc_inodes+0x180/0x3b0 [btrfs]
btrfs_start_delalloc_roots+0x174/0x280 [btrfs]
shrink_delalloc+0x114/0x280 [btrfs]
flush_space+0x250/0x2f8 [btrfs]
btrfs_async_reclaim_data_space+0x180/0x228 [btrfs]
process_one_work+0x164/0x408
worker_thread+0x25c/0x388
kthread+0x100/0x118
ret_from_fork+0x10/0x20
Code: aa1403e1 9402f3ef aa1403e0 9402f36f (d4210000)
---[ end trace 0000000000000000 ]---
[CAUSE]
That failure is mostly from cow_file_range(), where we can hit -ENOSPC.
Although the -ENOSPC is already a bug related to our space reservation
code, let's just focus on the error handling.
For example, we have the following dirty range [0, 64K) of an inode,
with 4K sector size and 4K page size:
0 16K 32K 48K 64K
|///////////////////////////////////////|
|#######################################|
Where |///| means page are still dirty, and |###| means the extent io
tree has EXTENT_DELALLOC flag.
- Enter extent_writepage() for page 0
- Enter btrfs_run_delalloc_range() for range [0, 64K)
- Enter cow_file_range() for range [0, 64K)
- Function btrfs_reserve_extent() only reserved one 16K extent
So we created extent map and ordered extent for range [0, 16K)
0 16K 32K 48K 64K
|////////|//////////////////////////////|
|<- OE ->|##############################|
And range [0, 16K) has its delalloc flag cleared.
But since we haven't yet submit any bio, involved 4 pages are still
dirty.
- Function btrfs_reserve_extent() returns with -ENOSPC
Now we have to run error cleanup, which will clear all
EXTENT_DELALLOC* flags and clear the dirty flags for the remaining
ranges:
0 16K 32K 48K 64K
|////////| |
| | |
Note that range [0, 16K) still has its pages dirty.
- Some time later, writeback is triggered again for the range [0, 16K)
since the page range still has dirty flags.
- btrfs_run_delalloc_range() will do nothing because there is no
EXTENT_DELALLOC flag.
- extent_writepage_io() finds page 0 has no ordered flag
Which falls into the COW fixup path, triggering the BUG_ON().
Unfortunately this error handling bug dates back to the introduction of
btrfs. Thankfully with the abuse of COW fixup, at least it won't crash
the kernel.
[FIX]
Instead of immediately unlocking the extent and folios, we keep the extent
and folios locked until either erroring out or the whole delalloc range
finished.
When the whole delalloc range finished without error, we just unlock the
whole range with PAGE_SET_ORDERED (and PAGE_UNLOCK for !keep_locked
cases), with EXTENT_DELALLOC and EXTENT_LOCKED cleared.
And the involved folios will be properly submitted, with their dirty
flags cleared during submission.
For the error path, it will be a little more complex:
- The range with ordered extent allocated (range (1))
We only clear the EXTENT_DELALLOC and EXTENT_LOCKED, as the remaining
flags are cleaned up by
btrfs_mark_ordered_io_finished()->btrfs_finish_one_ordered().
For folios we finish the IO (clear dirty, start writeback and
immediately finish the writeback) and unlock the folios.
- The range with reserved extent but no ordered extent (range(2))
- The range we never touched (range(3))
For both range (2) and range(3) the behavior is not changed.
Now even if cow_file_range() failed halfway with some successfully
reserved extents/ordered extents, we will keep all folios clean, so
there will be no future writeback triggered on them.
CC: stable@vger.kernel.org
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/inode.c | 63 ++++++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 29 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e53b42a047e8b..7d1eab71f17b4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1265,6 +1265,17 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
alloc_hint = get_extent_allocation_hint(inode, start, num_bytes);
+ /*
+ * We're not doing compressed IO, don't unlock the first page (which
+ * the caller expects to stay locked), don't clear any dirty bits and
+ * don't set any writeback bits.
+ *
+ * Do set the Ordered (Private2) bit so we know this page was properly
+ * setup for writepage.
+ */
+ page_ops = unlock ? PAGE_UNLOCK : 0;
+ page_ops |= PAGE_SET_ORDERED;
+
/*
* Relocation relies on the relocated extents to have exactly the same
* size as the original extents. Normally writeback for relocation data
@@ -1335,21 +1346,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
- /*
- * We're not doing compressed IO, don't unlock the first page
- * (which the caller expects to stay locked), don't clear any
- * dirty bits and don't set any writeback bits
- *
- * Do set the Ordered (Private2) bit so we know this page was
- * properly setup for writepage.
- */
- page_ops = unlock ? PAGE_UNLOCK : 0;
- page_ops |= PAGE_SET_ORDERED;
-
- extent_clear_unlock_delalloc(inode, start, start + ram_size - 1,
- locked_page,
- EXTENT_LOCKED | EXTENT_DELALLOC,
- page_ops);
if (num_bytes < cur_alloc_size)
num_bytes = 0;
else
@@ -1366,6 +1362,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
if (ret)
goto out_unlock;
}
+ extent_clear_unlock_delalloc(inode, orig_start, end, locked_page,
+ EXTENT_LOCKED | EXTENT_DELALLOC, page_ops);
out:
return ret;
@@ -1380,10 +1378,15 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
* caller to write out the successfully allocated region and retry.
*/
if (done_offset && ret == -EAGAIN) {
- if (orig_start < start)
+ if (orig_start < start) {
+ extent_clear_unlock_delalloc(inode, orig_start, start - 1,
+ locked_page,
+ EXTENT_LOCKED | EXTENT_DELALLOC,
+ page_ops);
*done_offset = start - 1;
- else
+ } else {
*done_offset = start;
+ }
return ret;
} else if (ret == -EAGAIN) {
/* Convert to -ENOSPC since the caller cannot retry. */
@@ -1399,29 +1402,31 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
* We process each region below.
*/
- clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
- EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV;
- page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
-
/*
* For the range (1). We have already instantiated the ordered extents
* for this region. They are cleaned up by
* btrfs_cleanup_ordered_extents() in e.g,
- * btrfs_run_delalloc_range(). EXTENT_LOCKED | EXTENT_DELALLOC are
- * already cleared in the above loop. And, EXTENT_DELALLOC_NEW |
- * EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV are handled by the cleanup
- * function.
+ * btrfs_run_delalloc_range().
+ * EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV
+ * are also handled by the cleanup function.
*
- * However, in case of unlock == 0, we still need to unlock the pages
- * (except @locked_page) to ensure all the pages are unlocked.
+ * So here we only clear EXTENT_LOCKED and EXTENT_DELALLOC flag, and
+ * finish the writeback of the involved folios, which will be never submitted.
*/
- if (!unlock && orig_start < start) {
+ if (orig_start < start) {
+ clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC;
+ page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
+
if (!locked_page)
mapping_set_error(inode->vfs_inode.i_mapping, ret);
extent_clear_unlock_delalloc(inode, orig_start, start - 1,
- locked_page, 0, page_ops);
+ locked_page, clear_bits, page_ops);
}
+ clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
+ EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV;
+ page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
+
/*
* For the range (2). If we reserved an extent for our delalloc range
* (or a subrange) and failed to create the respective ordered extent,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0726/1887] xfrm: state: fix out-of-bounds read during lookup
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (724 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0725/1887] btrfs: do proper folio cleanup when cow_file_range() failed Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0727/1887] powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW Greg Kroah-Hartman
` (272 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5f9f31cb7d985f584d8e,
Florian Westphal, Steffen Klassert, Sasha Levin, Dmitry Vyukov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit e952837f3ddb0ff726d5b582aa1aad9aa38d024d ]
lookup and resize can run in parallel.
The xfrm_state_hash_generation seqlock ensures a retry, but the hash
functions can observe a hmask value that is too large for the new hlist
array.
rehash does:
rcu_assign_pointer(net->xfrm.state_bydst, ndst) [..]
net->xfrm.state_hmask = nhashmask;
While state lookup does:
h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) {
This is only safe in case the update to state_bydst is larger than
net->xfrm.xfrm_state_hmask (or if the lookup function gets
serialized via state spinlock again).
Fix this by prefetching state_hmask and the associated pointers.
The xfrm_state_hash_generation seqlock retry will ensure that the pointer
and the hmask will be consistent.
The existing helpers, like xfrm_dst_hash(), are now unsafe for RCU side,
add lockdep assertions to document that they are only safe for insert
side.
xfrm_state_lookup_byaddr() uses the spinlock rather than RCU.
AFAICS this is an oversight from back when state lookup was converted to
RCU, this lock should be replaced with RCU in a future patch.
Reported-by: syzbot+5f9f31cb7d985f584d8e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/CACT4Y+azwfrE3uz6A5ZErov5YN2LYBN5KrsymBerT36VU8qzBA@mail.gmail.com/
Diagnosed-by: Dmitry Vyukov <dvyukov@google.com>
Fixes: c2f672fc9464 ("xfrm: state lookup can be lockless")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_state.c | 77 ++++++++++++++++++++++++++++++++++---------
1 file changed, 62 insertions(+), 15 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 4b0835cb58f5d..ecafa6950139f 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -34,6 +34,8 @@
#define xfrm_state_deref_prot(table, net) \
rcu_dereference_protected((table), lockdep_is_held(&(net)->xfrm.xfrm_state_lock))
+#define xfrm_state_deref_check(table, net) \
+ rcu_dereference_check((table), lockdep_is_held(&(net)->xfrm.xfrm_state_lock))
static void xfrm_state_gc_task(struct work_struct *work);
@@ -61,6 +63,8 @@ static inline unsigned int xfrm_dst_hash(struct net *net,
u32 reqid,
unsigned short family)
{
+ lockdep_assert_held(&net->xfrm.xfrm_state_lock);
+
return __xfrm_dst_hash(daddr, saddr, reqid, family, net->xfrm.state_hmask);
}
@@ -69,6 +73,8 @@ static inline unsigned int xfrm_src_hash(struct net *net,
const xfrm_address_t *saddr,
unsigned short family)
{
+ lockdep_assert_held(&net->xfrm.xfrm_state_lock);
+
return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask);
}
@@ -76,11 +82,15 @@ static inline unsigned int
xfrm_spi_hash(struct net *net, const xfrm_address_t *daddr,
__be32 spi, u8 proto, unsigned short family)
{
+ lockdep_assert_held(&net->xfrm.xfrm_state_lock);
+
return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask);
}
static unsigned int xfrm_seq_hash(struct net *net, u32 seq)
{
+ lockdep_assert_held(&net->xfrm.xfrm_state_lock);
+
return __xfrm_seq_hash(seq, net->xfrm.state_hmask);
}
@@ -944,15 +954,37 @@ xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
x->props.family = tmpl->encap_family;
}
-static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
+struct xfrm_hash_state_ptrs {
+ const struct hlist_head *bydst;
+ const struct hlist_head *bysrc;
+ const struct hlist_head *byspi;
+ unsigned int hmask;
+};
+
+static void xfrm_hash_ptrs_get(const struct net *net, struct xfrm_hash_state_ptrs *ptrs)
+{
+ unsigned int sequence;
+
+ do {
+ sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation);
+
+ ptrs->bydst = xfrm_state_deref_check(net->xfrm.state_bydst, net);
+ ptrs->bysrc = xfrm_state_deref_check(net->xfrm.state_bysrc, net);
+ ptrs->byspi = xfrm_state_deref_check(net->xfrm.state_byspi, net);
+ ptrs->hmask = net->xfrm.state_hmask;
+ } while (read_seqcount_retry(&net->xfrm.xfrm_state_hash_generation, sequence));
+}
+
+static struct xfrm_state *__xfrm_state_lookup(const struct xfrm_hash_state_ptrs *state_ptrs,
+ u32 mark,
const xfrm_address_t *daddr,
__be32 spi, u8 proto,
unsigned short family)
{
- unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
+ unsigned int h = __xfrm_spi_hash(daddr, spi, proto, family, state_ptrs->hmask);
struct xfrm_state *x;
- hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) {
+ hlist_for_each_entry_rcu(x, state_ptrs->byspi + h, byspi) {
if (x->props.family != family ||
x->id.spi != spi ||
x->id.proto != proto ||
@@ -969,15 +1001,16 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
return NULL;
}
-static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark,
+static struct xfrm_state *__xfrm_state_lookup_byaddr(const struct xfrm_hash_state_ptrs *state_ptrs,
+ u32 mark,
const xfrm_address_t *daddr,
const xfrm_address_t *saddr,
u8 proto, unsigned short family)
{
- unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
+ unsigned int h = __xfrm_src_hash(daddr, saddr, family, state_ptrs->hmask);
struct xfrm_state *x;
- hlist_for_each_entry_rcu(x, net->xfrm.state_bysrc + h, bysrc) {
+ hlist_for_each_entry_rcu(x, state_ptrs->bysrc + h, bysrc) {
if (x->props.family != family ||
x->id.proto != proto ||
!xfrm_addr_equal(&x->id.daddr, daddr, family) ||
@@ -997,14 +1030,17 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark,
static inline struct xfrm_state *
__xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
{
+ struct xfrm_hash_state_ptrs state_ptrs;
struct net *net = xs_net(x);
u32 mark = x->mark.v & x->mark.m;
+ xfrm_hash_ptrs_get(net, &state_ptrs);
+
if (use_spi)
- return __xfrm_state_lookup(net, mark, &x->id.daddr,
+ return __xfrm_state_lookup(&state_ptrs, mark, &x->id.daddr,
x->id.spi, x->id.proto, family);
else
- return __xfrm_state_lookup_byaddr(net, mark,
+ return __xfrm_state_lookup_byaddr(&state_ptrs, mark,
&x->id.daddr,
&x->props.saddr,
x->id.proto, family);
@@ -1067,6 +1103,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
unsigned short family, u32 if_id)
{
static xfrm_address_t saddr_wildcard = { };
+ struct xfrm_hash_state_ptrs state_ptrs;
struct net *net = xp_net(pol);
unsigned int h, h_wildcard;
struct xfrm_state *x, *x0, *to_put;
@@ -1083,8 +1120,10 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation);
rcu_read_lock();
- h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
- hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) {
+ xfrm_hash_ptrs_get(net, &state_ptrs);
+
+ h = __xfrm_dst_hash(daddr, saddr, tmpl->reqid, encap_family, state_ptrs.hmask);
+ hlist_for_each_entry_rcu(x, state_ptrs.bydst + h, bydst) {
if (x->props.family == encap_family &&
x->props.reqid == tmpl->reqid &&
(mark & x->mark.m) == x->mark.v &&
@@ -1100,8 +1139,9 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
if (best || acquire_in_progress)
goto found;
- h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family);
- hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h_wildcard, bydst) {
+ h_wildcard = __xfrm_dst_hash(daddr, &saddr_wildcard, tmpl->reqid,
+ encap_family, state_ptrs.hmask);
+ hlist_for_each_entry_rcu(x, state_ptrs.bydst + h_wildcard, bydst) {
if (x->props.family == encap_family &&
x->props.reqid == tmpl->reqid &&
(mark & x->mark.m) == x->mark.v &&
@@ -1119,7 +1159,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
x = best;
if (!x && !error && !acquire_in_progress) {
if (tmpl->id.spi &&
- (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
+ (x0 = __xfrm_state_lookup(&state_ptrs, mark, daddr, tmpl->id.spi,
tmpl->id.proto, encap_family)) != NULL) {
to_put = x0;
error = -EEXIST;
@@ -1807,10 +1847,13 @@ struct xfrm_state *
xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi,
u8 proto, unsigned short family)
{
+ struct xfrm_hash_state_ptrs state_ptrs;
struct xfrm_state *x;
rcu_read_lock();
- x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
+ xfrm_hash_ptrs_get(net, &state_ptrs);
+
+ x = __xfrm_state_lookup(&state_ptrs, mark, daddr, spi, proto, family);
rcu_read_unlock();
return x;
}
@@ -1821,10 +1864,14 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark,
const xfrm_address_t *daddr, const xfrm_address_t *saddr,
u8 proto, unsigned short family)
{
+ struct xfrm_hash_state_ptrs state_ptrs;
struct xfrm_state *x;
spin_lock_bh(&net->xfrm.xfrm_state_lock);
- x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
+
+ xfrm_hash_ptrs_get(net, &state_ptrs);
+
+ x = __xfrm_state_lookup_byaddr(&state_ptrs, mark, daddr, saddr, proto, family);
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
return x;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0727/1887] powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (725 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0726/1887] xfrm: state: fix out-of-bounds read during lookup Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0728/1887] PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar() Greg Kroah-Hartman
` (271 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gaurav Batra, Nilay Shroff,
Madhavan Srinivasan, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaurav Batra <gbatra@linux.ibm.com>
[ Upstream commit 8f70caad82e9c088ed93b4fea48d941ab6441886 ]
Power Hypervisor can possibily allocate MMIO window intersecting with
Dynamic DMA Window (DDW) range, which is over 32-bit addressing.
These MMIO pages needs to be marked as reserved so that IOMMU doesn't map
DMA buffers in this range.
The current code is not marking these pages correctly which is resulting
in LPAR to OOPS while booting. The stack is at below
BUG: Unable to handle kernel data access on read at 0xc00800005cd40000
Faulting instruction address: 0xc00000000005cdac
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
Modules linked in: af_packet rfkill ibmveth(X) lpfc(+) nvmet_fc nvmet nvme_keyring crct10dif_vpmsum nvme_fc nvme_fabrics nvme_core be2net(+) nvme_auth rtc_generic nfsd auth_rpcgss nfs_acl lockd grace sunrpc fuse configfs ip_tables x_tables xfs libcrc32c dm_service_time ibmvfc(X) scsi_transport_fc vmx_crypto gf128mul crc32c_vpmsum dm_mirror dm_region_hash dm_log dm_multipath dm_mod sd_mod scsi_dh_emc scsi_dh_rdac scsi_dh_alua t10_pi crc64_rocksoft_generic crc64_rocksoft sg crc64 scsi_mod
Supported: Yes, External
CPU: 8 PID: 241 Comm: kworker/8:1 Kdump: loaded Not tainted 6.4.0-150600.23.14-default #1 SLE15-SP6 b44ee71c81261b9e4bab5e0cde1f2ed891d5359b
Hardware name: IBM,9080-M9S POWER9 (raw) 0x4e2103 0xf000005 of:IBM,FW950.B0 (VH950_149) hv:phyp pSeries
Workqueue: events work_for_cpu_fn
NIP: c00000000005cdac LR: c00000000005e830 CTR: 0000000000000000
REGS: c00001400c9ff770 TRAP: 0300 Not tainted (6.4.0-150600.23.14-default)
MSR: 800000000280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24228448 XER: 00000001
CFAR: c00000000005cdd4 DAR: c00800005cd40000 DSISR: 40000000 IRQMASK: 0
GPR00: c00000000005e830 c00001400c9ffa10 c000000001987d00 c00001400c4fe800
GPR04: 0000080000000000 0000000000000001 0000000004000000 0000000000800000
GPR08: 0000000004000000 0000000000000001 c00800005cd40000 ffffffffffffffff
GPR12: 0000000084228882 c00000000a4c4f00 0000000000000010 0000080000000000
GPR16: c00001400c4fe800 0000000004000000 0800000000000000 c00000006088b800
GPR20: c00001401a7be980 c00001400eff3800 c000000002a2da68 000000000000002b
GPR24: c0000000026793a8 c000000002679368 000000000000002a c0000000026793c8
GPR28: 000008007effffff 0000080000000000 0000000000800000 c00001400c4fe800
NIP [c00000000005cdac] iommu_table_reserve_pages+0xac/0x100
LR [c00000000005e830] iommu_init_table+0x80/0x1e0
Call Trace:
[c00001400c9ffa10] [c00000000005e810] iommu_init_table+0x60/0x1e0 (unreliable)
[c00001400c9ffa90] [c00000000010356c] iommu_bypass_supported_pSeriesLP+0x9cc/0xe40
[c00001400c9ffc30] [c00000000005c300] dma_iommu_dma_supported+0xf0/0x230
[c00001400c9ffcb0] [c00000000024b0c4] dma_supported+0x44/0x90
[c00001400c9ffcd0] [c00000000024b14c] dma_set_mask+0x3c/0x80
[c00001400c9ffd00] [c0080000555b715c] be_probe+0xc4/0xb90 [be2net]
[c00001400c9ffdc0] [c000000000986f3c] local_pci_probe+0x6c/0x110
[c00001400c9ffe40] [c000000000188f28] work_for_cpu_fn+0x38/0x60
[c00001400c9ffe70] [c00000000018e454] process_one_work+0x314/0x620
[c00001400c9fff10] [c00000000018f280] worker_thread+0x2b0/0x620
[c00001400c9fff90] [c00000000019bb18] kthread+0x148/0x150
[c00001400c9fffe0] [c00000000000ded8] start_kernel_thread+0x14/0x18
There are 2 issues in the code
1. The index is "int" while the address is "unsigned long". This results in
negative value when setting the bitmap.
2. The DMA offset is page shifted but the MMIO range is used as-is (64-bit
address). MMIO address needs to be page shifted as well.
Fixes: 3c33066a2190 ("powerpc/kernel/iommu: Add new iommu_table_in_use() helper")
Signed-off-by: Gaurav Batra <gbatra@linux.ibm.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20241206210039.93172-1-gbatra@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/iommu.c | 2 +-
arch/powerpc/platforms/pseries/iommu.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 81bd60c8094c1..e10df1b5b6309 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -685,7 +685,7 @@ static void iommu_table_clear(struct iommu_table *tbl)
static void iommu_table_reserve_pages(struct iommu_table *tbl,
unsigned long res_start, unsigned long res_end)
{
- int i;
+ unsigned long i;
WARN_ON_ONCE(res_end < res_start);
/*
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d5b5d1a4ec166..41e7400bc3194 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1510,7 +1510,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
iommu_table_setparms_common(newtbl, pci->phb->bus->number, create.liobn, win_addr,
1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops);
- iommu_init_table(newtbl, pci->phb->node, start, end);
+ iommu_init_table(newtbl, pci->phb->node,
+ start >> page_shift, end >> page_shift);
pci->table_group->tables[1] = newtbl;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0728/1887] PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (726 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0727/1887] powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0729/1887] ASoC: SOF: Intel: hda-dai: Ensure DAI widget is valid during params Greg Kroah-Hartman
` (270 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Niklas Cassel,
Krzysztof Wilczyński, Manivannan Sadhasivam, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <cassel@kernel.org>
[ Upstream commit 3708acbd5f169ebafe1faa519cb28adc56295546 ]
In commit 4284c88fff0e ("PCI: designware-ep: Allow pci_epc_set_bar() update
inbound map address") set_bar() was modified to support dynamically
changing the backing physical address of a BAR that was already configured.
This means that set_bar() can be called twice, without ever calling
clear_bar() (as calling clear_bar() would clear the BAR's PCI address
assigned by the host).
This can only be done if the new BAR size/flags does not differ from the
existing BAR configuration. Add these missing checks.
If we allow set_bar() to set e.g. a new BAR size that differs from the
existing BAR size, the new address translation range will be smaller than
the BAR size already determined by the host, which would mean that a read
past the new BAR size would pass the iATU untranslated, which could allow
the host to read memory not belonging to the new struct pci_epf_bar.
While at it, add comments which clarifies the support for dynamically
changing the physical address of a BAR. (Which was also missing.)
Fixes: 4284c88fff0e ("PCI: designware-ep: Allow pci_epc_set_bar() update inbound map address")
Link: https://lore.kernel.org/r/20241213143301.4158431-10-cassel@kernel.org
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 3b3f079d0d2dd..32a04ff86c5c5 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -247,6 +247,23 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
func_offset = dw_pcie_ep_func_select(ep, func_no);
+ /*
+ * Certain EPF drivers dynamically change the physical address of a BAR
+ * (i.e. they call set_bar() twice, without ever calling clear_bar(), as
+ * calling clear_bar() would clear the BAR's PCI address assigned by the
+ * host).
+ */
+ if (ep->epf_bar[bar]) {
+ /*
+ * We can only dynamically change a BAR if the new BAR size and
+ * BAR flags do not differ from the existing configuration.
+ */
+ if (ep->epf_bar[bar]->barno != bar ||
+ ep->epf_bar[bar]->size != size ||
+ ep->epf_bar[bar]->flags != flags)
+ return -EINVAL;
+ }
+
reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
if (!(flags & PCI_BASE_ADDRESS_SPACE))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0729/1887] ASoC: SOF: Intel: hda-dai: Ensure DAI widget is valid during params
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (727 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0728/1887] PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0730/1887] rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy Greg Kroah-Hartman
` (269 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bard Liao, Ranjani Sridharan,
Péter Ujfalusi, Liam Girdwood, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <yung-chuan.liao@linux.intel.com>
[ Upstream commit 569922b82ca660f8b24e705f6cf674e6b1f99cc7 ]
Each cpu DAI should associate with a widget. However, the topology might
not create the right number of DAI widgets for aggregated amps. And it
will cause NULL pointer deference.
Check that the DAI widget associated with the CPU DAI is valid to prevent
NULL pointer deference due to missing DAI widgets in topologies with
aggregated amps.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Link: https://patch.msgid.link/20241203104853.56956-1-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sof/intel/hda.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index b7d6a54bbb634..4ba7c4be670dd 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -128,6 +128,11 @@ static int sdw_params_stream(struct device *dev,
struct snd_soc_dapm_widget *w;
w = snd_soc_dai_get_widget(d, params_data->stream);
+ if (!w) {
+ dev_err(dev, "%s widget not found, check amp link num in the topology\n",
+ d->name);
+ return -EINVAL;
+ }
data.dai_index = (params_data->link_id << 8) | d->id;
data.dai_data = params_data->alh_stream_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0730/1887] rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (728 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0729/1887] ASoC: SOF: Intel: hda-dai: Ensure DAI widget is valid during params Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0731/1887] smb: client: fix double free of TCP_Server_Info::hostname Greg Kroah-Hartman
` (268 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Al Viro, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
[ Upstream commit 7f5611cbc4871c7fb1ad36c2e5a9edad63dca95c ]
As mentioned in a previous commit of this series, using the 'net'
structure via 'current' is not recommended for different reasons:
- Inconsistency: getting info from the reader's/writer's netns vs only
from the opener's netns.
- current->nsproxy can be NULL in some cases, resulting in an 'Oops'
(null-ptr-deref), e.g. when the current task is exiting, as spotted by
syzbot [1] using acct(2).
The per-netns structure can be obtained from the table->data using
container_of(), then the 'net' one can be retrieved from the listen
socket (if available).
Fixes: c6a58ffed536 ("RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/67769ecb.050a0220.3a8527.003f.GAE@google.com [1]
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250108-net-sysctl-current-nsproxy-v1-9-5df34b2083e8@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/tcp.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index ef7cf0a6cb134..020baff6ad514 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -53,8 +53,10 @@ static atomic_t rds_tcp_unloading = ATOMIC_INIT(0);
static struct kmem_cache *rds_tcp_conn_slab;
-static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
- void *buffer, size_t *lenp, loff_t *fpos);
+static int rds_tcp_sndbuf_handler(struct ctl_table *ctl, int write,
+ void *buffer, size_t *lenp, loff_t *fpos);
+static int rds_tcp_rcvbuf_handler(struct ctl_table *ctl, int write,
+ void *buffer, size_t *lenp, loff_t *fpos);
static int rds_tcp_min_sndbuf = SOCK_MIN_SNDBUF;
static int rds_tcp_min_rcvbuf = SOCK_MIN_RCVBUF;
@@ -66,7 +68,7 @@ static struct ctl_table rds_tcp_sysctl_table[] = {
/* data is per-net pointer */
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = rds_tcp_skbuf_handler,
+ .proc_handler = rds_tcp_sndbuf_handler,
.extra1 = &rds_tcp_min_sndbuf,
},
#define RDS_TCP_RCVBUF 1
@@ -75,7 +77,7 @@ static struct ctl_table rds_tcp_sysctl_table[] = {
/* data is per-net pointer */
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = rds_tcp_skbuf_handler,
+ .proc_handler = rds_tcp_rcvbuf_handler,
.extra1 = &rds_tcp_min_rcvbuf,
},
{ }
@@ -752,10 +754,10 @@ static void rds_tcp_sysctl_reset(struct net *net)
spin_unlock_irq(&rds_tcp_conn_lock);
}
-static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
+static int rds_tcp_skbuf_handler(struct rds_tcp_net *rtn,
+ struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *fpos)
{
- struct net *net = current->nsproxy->net_ns;
int err;
err = proc_dointvec_minmax(ctl, write, buffer, lenp, fpos);
@@ -764,11 +766,34 @@ static int rds_tcp_skbuf_handler(struct ctl_table *ctl, int write,
*(int *)(ctl->extra1));
return err;
}
- if (write)
+
+ if (write && rtn->rds_tcp_listen_sock && rtn->rds_tcp_listen_sock->sk) {
+ struct net *net = sock_net(rtn->rds_tcp_listen_sock->sk);
+
rds_tcp_sysctl_reset(net);
+ }
+
return 0;
}
+static int rds_tcp_sndbuf_handler(struct ctl_table *ctl, int write,
+ void *buffer, size_t *lenp, loff_t *fpos)
+{
+ struct rds_tcp_net *rtn = container_of(ctl->data, struct rds_tcp_net,
+ sndbuf_size);
+
+ return rds_tcp_skbuf_handler(rtn, ctl, write, buffer, lenp, fpos);
+}
+
+static int rds_tcp_rcvbuf_handler(struct ctl_table *ctl, int write,
+ void *buffer, size_t *lenp, loff_t *fpos)
+{
+ struct rds_tcp_net *rtn = container_of(ctl->data, struct rds_tcp_net,
+ rcvbuf_size);
+
+ return rds_tcp_skbuf_handler(rtn, ctl, write, buffer, lenp, fpos);
+}
+
static void rds_tcp_exit(void)
{
rds_tcp_set_unloading();
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0731/1887] smb: client: fix double free of TCP_Server_Info::hostname
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (729 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0730/1887] rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0732/1887] mm: clear uffd-wp PTE/PMD state on mremap() Greg Kroah-Hartman
` (267 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jay Shin, Paulo Alcantara (Red Hat),
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.com>
[ Upstream commit fa2f9906a7b333ba757a7dbae0713d8a5396186e ]
When shutting down the server in cifs_put_tcp_session(), cifsd thread
might be reconnecting to multiple DFS targets before it realizes it
should exit the loop, so @server->hostname can't be freed as long as
cifsd thread isn't done. Otherwise the following can happen:
RIP: 0010:__slab_free+0x223/0x3c0
Code: 5e 41 5f c3 cc cc cc cc 4c 89 de 4c 89 cf 44 89 44 24 08 4c 89
1c 24 e8 fb cf 8e 00 44 8b 44 24 08 4c 8b 1c 24 e9 5f fe ff ff <0f>
0b 41 f7 45 08 00 0d 21 00 0f 85 2d ff ff ff e9 1f ff ff ff 80
RSP: 0018:ffffb26180dbfd08 EFLAGS: 00010246
RAX: ffff8ea34728e510 RBX: ffff8ea34728e500 RCX: 0000000000800068
RDX: 0000000000800068 RSI: 0000000000000000 RDI: ffff8ea340042400
RBP: ffffe112041ca380 R08: 0000000000000001 R09: 0000000000000000
R10: 6170732e31303000 R11: 70726f632e786563 R12: ffff8ea34728e500
R13: ffff8ea340042400 R14: ffff8ea34728e500 R15: 0000000000800068
FS: 0000000000000000(0000) GS:ffff8ea66fd80000(0000)
000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffc25376080 CR3: 000000012a2ba001 CR4:
PKRU: 55555554
Call Trace:
<TASK>
? show_trace_log_lvl+0x1c4/0x2df
? show_trace_log_lvl+0x1c4/0x2df
? __reconnect_target_unlocked+0x3e/0x160 [cifs]
? __die_body.cold+0x8/0xd
? die+0x2b/0x50
? do_trap+0xce/0x120
? __slab_free+0x223/0x3c0
? do_error_trap+0x65/0x80
? __slab_free+0x223/0x3c0
? exc_invalid_op+0x4e/0x70
? __slab_free+0x223/0x3c0
? asm_exc_invalid_op+0x16/0x20
? __slab_free+0x223/0x3c0
? extract_hostname+0x5c/0xa0 [cifs]
? extract_hostname+0x5c/0xa0 [cifs]
? __kmalloc+0x4b/0x140
__reconnect_target_unlocked+0x3e/0x160 [cifs]
reconnect_dfs_server+0x145/0x430 [cifs]
cifs_handle_standard+0x1ad/0x1d0 [cifs]
cifs_demultiplex_thread+0x592/0x730 [cifs]
? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs]
kthread+0xdd/0x100
? __pfx_kthread+0x10/0x10
ret_from_fork+0x29/0x50
</TASK>
Fixes: 7be3248f3139 ("cifs: To match file servers, make sure the server hostname matches")
Reported-by: Jay Shin <jaeshin@redhat.com>
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/connect.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 1661f6135e417..9172b4136a925 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1088,6 +1088,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
kfree(server->origin_fullpath);
kfree(server->leaf_fullpath);
#endif
+ kfree(server->hostname);
kfree(server);
length = atomic_dec_return(&tcpSesAllocCount);
@@ -1708,8 +1709,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
kfree_sensitive(server->session_key.response);
server->session_key.response = NULL;
server->session_key.len = 0;
- kfree(server->hostname);
- server->hostname = NULL;
task = xchg(&server->tsk, NULL);
if (task)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0732/1887] mm: clear uffd-wp PTE/PMD state on mremap()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (730 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0731/1887] smb: client: fix double free of TCP_Server_Info::hostname Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0733/1887] RDMA/mlx5: Fix implicit ODP use after free Greg Kroah-Hartman
` (266 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikołaj Lenczewski,
Ryan Roberts, David Hildenbrand, Jann Horn, Liam R. Howlett,
Lorenzo Stoakes, Mark Rutland, Muchun Song, Peter Xu, Shuah Khan,
Vlastimil Babka, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Roberts <ryan.roberts@arm.com>
[ Upstream commit 0cef0bb836e3cfe00f08f9606c72abd72fe78ca3 ]
When mremap()ing a memory region previously registered with userfaultfd as
write-protected but without UFFD_FEATURE_EVENT_REMAP, an inconsistency in
flag clearing leads to a mismatch between the vma flags (which have
uffd-wp cleared) and the pte/pmd flags (which do not have uffd-wp
cleared). This mismatch causes a subsequent mprotect(PROT_WRITE) to
trigger a warning in page_table_check_pte_flags() due to setting the pte
to writable while uffd-wp is still set.
Fix this by always explicitly clearing the uffd-wp pte/pmd flags on any
such mremap() so that the values are consistent with the existing clearing
of VM_UFFD_WP. Be careful to clear the logical flag regardless of its
physical form; a PTE bit, a swap PTE bit, or a PTE marker. Cover PTE,
huge PMD and hugetlb paths.
Link: https://lkml.kernel.org/r/20250107144755.1871363-2-ryan.roberts@arm.com
Co-developed-by: Mikołaj Lenczewski <miko.lenczewski@arm.com>
Signed-off-by: Mikołaj Lenczewski <miko.lenczewski@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Closes: https://lore.kernel.org/linux-mm/810b44a8-d2ae-4107-b665-5a42eae2d948@arm.com/
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc: David Hildenbrand <david@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <Liam.Howlett@Oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Peter Xu <peterx@redhat.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/userfaultfd.c | 7 +++++++
include/linux/userfaultfd_k.h | 7 +++++++
mm/huge_memory.c | 12 ++++++++++++
mm/hugetlb.c | 14 +++++++++++++-
mm/mremap.c | 32 +++++++++++++++++++++++++++++++-
5 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 79b0f22eedd71..59c4fd41a35aa 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -108,6 +108,13 @@ static bool userfaultfd_is_initialized(struct userfaultfd_ctx *ctx)
return ctx->features & UFFD_FEATURE_INITIALIZED;
}
+bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma)
+{
+ struct userfaultfd_ctx *uffd_ctx = vma->vm_userfaultfd_ctx.ctx;
+
+ return uffd_ctx && (uffd_ctx->features & UFFD_FEATURE_EVENT_REMAP) == 0;
+}
+
static void userfaultfd_set_vm_flags(struct vm_area_struct *vma,
vm_flags_t flags)
{
diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index 9df0b9a762cc9..87f3d6e17a67c 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -162,6 +162,8 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma,
vma_is_shmem(vma);
}
+bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma);
+
extern int dup_userfaultfd(struct vm_area_struct *, struct list_head *);
extern void dup_userfaultfd_complete(struct list_head *);
@@ -274,6 +276,11 @@ static inline bool uffd_disable_fault_around(struct vm_area_struct *vma)
return false;
}
+static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma)
+{
+ return false;
+}
+
#endif /* CONFIG_USERFAULTFD */
static inline bool pte_marker_entry_uffd_wp(swp_entry_t entry)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 483cdc373a20c..c9584bdd1ffca 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1736,6 +1736,16 @@ static pmd_t move_soft_dirty_pmd(pmd_t pmd)
return pmd;
}
+static pmd_t clear_uffd_wp_pmd(pmd_t pmd)
+{
+ if (pmd_present(pmd))
+ pmd = pmd_clear_uffd_wp(pmd);
+ else if (is_swap_pmd(pmd))
+ pmd = pmd_swp_clear_uffd_wp(pmd);
+
+ return pmd;
+}
+
bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
unsigned long new_addr, pmd_t *old_pmd, pmd_t *new_pmd)
{
@@ -1773,6 +1783,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
pgtable_trans_huge_deposit(mm, new_pmd, pgtable);
}
pmd = move_soft_dirty_pmd(pmd);
+ if (vma_has_uffd_without_event_remap(vma))
+ pmd = clear_uffd_wp_pmd(pmd);
set_pmd_at(mm, new_addr, new_pmd, pmd);
if (force_flush)
flush_pmd_tlb_range(vma, old_addr, old_addr + PMD_SIZE);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index cfe083798f3b4..ee2685d5a6e1c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5208,6 +5208,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte)
{
+ bool need_clear_uffd_wp = vma_has_uffd_without_event_remap(vma);
struct hstate *h = hstate_vma(vma);
struct mm_struct *mm = vma->vm_mm;
spinlock_t *src_ptl, *dst_ptl;
@@ -5224,7 +5225,18 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
pte = huge_ptep_get_and_clear(mm, old_addr, src_pte);
- set_huge_pte_at(mm, new_addr, dst_pte, pte);
+
+ if (need_clear_uffd_wp && pte_marker_uffd_wp(pte))
+ huge_pte_clear(mm, new_addr, dst_pte, huge_page_size(h));
+ else {
+ if (need_clear_uffd_wp) {
+ if (pte_present(pte))
+ pte = huge_pte_clear_uffd_wp(pte);
+ else if (is_swap_pte(pte))
+ pte = pte_swp_clear_uffd_wp(pte);
+ }
+ set_huge_pte_at(mm, new_addr, dst_pte, pte);
+ }
if (src_ptl != dst_ptl)
spin_unlock(src_ptl);
diff --git a/mm/mremap.c b/mm/mremap.c
index 5eca7534e8706..ec66e7be8afea 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -138,6 +138,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
struct vm_area_struct *new_vma, pmd_t *new_pmd,
unsigned long new_addr, bool need_rmap_locks)
{
+ bool need_clear_uffd_wp = vma_has_uffd_without_event_remap(vma);
struct mm_struct *mm = vma->vm_mm;
pte_t *old_pte, *new_pte, pte;
spinlock_t *old_ptl, *new_ptl;
@@ -198,7 +199,18 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
force_flush = true;
pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
pte = move_soft_dirty_pte(pte);
- set_pte_at(mm, new_addr, new_pte, pte);
+
+ if (need_clear_uffd_wp && pte_marker_uffd_wp(pte))
+ pte_clear(mm, new_addr, new_pte);
+ else {
+ if (need_clear_uffd_wp) {
+ if (pte_present(pte))
+ pte = pte_clear_uffd_wp(pte);
+ else if (is_swap_pte(pte))
+ pte = pte_swp_clear_uffd_wp(pte);
+ }
+ set_pte_at(mm, new_addr, new_pte, pte);
+ }
}
arch_leave_lazy_mmu_mode();
@@ -257,6 +269,15 @@ static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
return false;
+ /* If this pmd belongs to a uffd vma with remap events disabled, we need
+ * to ensure that the uffd-wp state is cleared from all pgtables. This
+ * means recursing into lower page tables in move_page_tables(), and we
+ * can reuse the existing code if we simply treat the entry as "not
+ * moved".
+ */
+ if (vma_has_uffd_without_event_remap(vma))
+ return false;
+
/*
* We don't have to worry about the ordering of src and dst
* ptlocks because exclusive mmap_lock prevents deadlock.
@@ -306,6 +327,15 @@ static bool move_normal_pud(struct vm_area_struct *vma, unsigned long old_addr,
if (WARN_ON_ONCE(!pud_none(*new_pud)))
return false;
+ /* If this pud belongs to a uffd vma with remap events disabled, we need
+ * to ensure that the uffd-wp state is cleared from all pgtables. This
+ * means recursing into lower page tables in move_page_tables(), and we
+ * can reuse the existing code if we simply treat the entry as "not
+ * moved".
+ */
+ if (vma_has_uffd_without_event_remap(vma))
+ return false;
+
/*
* We don't have to worry about the ordering of src and dst
* ptlocks because exclusive mmap_lock prevents deadlock.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0733/1887] RDMA/mlx5: Fix implicit ODP use after free
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (731 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0732/1887] mm: clear uffd-wp PTE/PMD state on mremap() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0734/1887] scsi: mpi3mr: Fix possible crash when setting up bsg fails Greg Kroah-Hartman
` (265 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Patrisious Haddad, Leon Romanovsky,
Jason Gunthorpe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <phaddad@nvidia.com>
[ Upstream commit d3d930411ce390e532470194296658a960887773 ]
Prevent double queueing of implicit ODP mr destroy work by using
__xa_cmpxchg() to make sure this is the only time we are destroying this
specific mr.
Without this change, we could try to invalidate this mr twice, which in
turn could result in queuing a MR work destroy twice, and eventually the
second work could execute after the MR was freed due to the first work,
causing a user after free and trace below.
refcount_t: underflow; use-after-free.
WARNING: CPU: 2 PID: 12178 at lib/refcount.c:28 refcount_warn_saturate+0x12b/0x130
Modules linked in: bonding ib_ipoib vfio_pci ip_gre geneve nf_tables ip6_gre gre ip6_tunnel tunnel6 ipip tunnel4 ib_umad rdma_ucm mlx5_vfio_pci vfio_pci_core vfio_iommu_type1 mlx5_ib vfio ib_uverbs mlx5_core iptable_raw openvswitch nsh rpcrdma ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_cm ib_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry overlay zram zsmalloc fuse [last unloaded: ib_uverbs]
CPU: 2 PID: 12178 Comm: kworker/u20:5 Not tainted 6.5.0-rc1_net_next_mlx5_58c644e #1
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Workqueue: events_unbound free_implicit_child_mr_work [mlx5_ib]
RIP: 0010:refcount_warn_saturate+0x12b/0x130
Code: 48 c7 c7 38 95 2a 82 c6 05 bc c6 fe 00 01 e8 0c 66 aa ff 0f 0b 5b c3 48 c7 c7 e0 94 2a 82 c6 05 a7 c6 fe 00 01 e8 f5 65 aa ff <0f> 0b 5b c3 90 8b 07 3d 00 00 00 c0 74 12 83 f8 01 74 13 8d 50 ff
RSP: 0018:ffff8881008e3e40 EFLAGS: 00010286
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000027
RDX: ffff88852c91b5c8 RSI: 0000000000000001 RDI: ffff88852c91b5c0
RBP: ffff8881dacd4e00 R08: 00000000ffffffff R09: 0000000000000019
R10: 000000000000072e R11: 0000000063666572 R12: ffff88812bfd9e00
R13: ffff8881c792d200 R14: ffff88810011c005 R15: ffff8881002099c0
FS: 0000000000000000(0000) GS:ffff88852c900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f5694b5e000 CR3: 00000001153f6003 CR4: 0000000000370ea0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
? refcount_warn_saturate+0x12b/0x130
free_implicit_child_mr_work+0x180/0x1b0 [mlx5_ib]
process_one_work+0x1cc/0x3c0
worker_thread+0x218/0x3c0
kthread+0xc6/0xf0
ret_from_fork+0x1f/0x30
</TASK>
Fixes: 5256edcb98a1 ("RDMA/mlx5: Rework implicit ODP destroy")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/r/c96b8645a81085abff739e6b06e286a350d1283d.1737274283.git.leon@kernel.org
Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/odp.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 89682fe0747ff..1b5492b75b7d8 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -213,10 +213,24 @@ static void destroy_unused_implicit_child_mr(struct mlx5_ib_mr *mr)
unsigned long idx = ib_umem_start(odp) >> MLX5_IMR_MTT_SHIFT;
struct mlx5_ib_mr *imr = mr->parent;
+ /*
+ * If userspace is racing freeing the parent implicit ODP MR then we can
+ * loose the race with parent destruction. In this case
+ * mlx5_ib_free_odp_mr() will free everything in the implicit_children
+ * xarray so NOP is fine. This child MR cannot be destroyed here because
+ * we are under its umem_mutex.
+ */
if (!refcount_inc_not_zero(&imr->mmkey.usecount))
return;
- xa_erase(&imr->implicit_children, idx);
+ xa_lock(&imr->implicit_children);
+ if (__xa_cmpxchg(&imr->implicit_children, idx, mr, NULL, GFP_KERNEL) !=
+ mr) {
+ xa_unlock(&imr->implicit_children);
+ return;
+ }
+
+ xa_unlock(&imr->implicit_children);
/* Freeing a MR is a sleeping operation, so bounce to a work queue */
INIT_WORK(&mr->odp_destroy.work, free_implicit_child_mr_work);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0734/1887] scsi: mpi3mr: Fix possible crash when setting up bsg fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (732 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0733/1887] RDMA/mlx5: Fix implicit ODP use after free Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0735/1887] wifi: rtw89: fix race between cancel_hw_scan and hw_scan completion Greg Kroah-Hartman
` (264 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guixin Liu, Bart Van Assche,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixin Liu <kanie@linux.alibaba.com>
[ Upstream commit 295006f6e8c17212d3098811166e29627d19e05c ]
If bsg_setup_queue() fails, the bsg_queue is assigned a non-NULL value.
Consequently, in mpi3mr_bsg_exit(), the condition "if(!mrioc->bsg_queue)"
will not be satisfied, preventing execution from entering
bsg_remove_queue(), which could lead to the following crash:
BUG: kernel NULL pointer dereference, address: 000000000000041c
Call Trace:
<TASK>
mpi3mr_bsg_exit+0x1f/0x50 [mpi3mr]
mpi3mr_remove+0x6f/0x340 [mpi3mr]
pci_device_remove+0x3f/0xb0
device_release_driver_internal+0x19d/0x220
unbind_store+0xa4/0xb0
kernfs_fop_write_iter+0x11f/0x200
vfs_write+0x1fc/0x3e0
ksys_write+0x67/0xe0
do_syscall_64+0x38/0x80
entry_SYSCALL_64_after_hwframe+0x78/0xe2
Fixes: 4268fa751365 ("scsi: mpi3mr: Add bsg device support")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Link: https://lore.kernel.org/r/20250107022032.24006-1-kanie@linux.alibaba.com
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpi3mr/mpi3mr_app.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index c77803bd9b009..28f19209c58db 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -1531,6 +1531,7 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
{
struct device *bsg_dev = &mrioc->bsg_dev;
struct device *parent = &mrioc->shost->shost_gendev;
+ struct request_queue *q;
device_initialize(bsg_dev);
@@ -1546,9 +1547,9 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
return;
}
- mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev),
+ q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev),
mpi3mr_bsg_request, NULL, 0);
- if (IS_ERR(mrioc->bsg_queue)) {
+ if (IS_ERR(q)) {
ioc_err(mrioc, "%s: bsg registration failed\n",
dev_name(bsg_dev));
device_del(bsg_dev);
@@ -1556,8 +1557,10 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
return;
}
- blk_queue_max_segments(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SEGMENTS);
- blk_queue_max_hw_sectors(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SECTORS);
+ mrioc->bsg_queue = q;
+
+ blk_queue_max_segments(q, MPI3MR_MAX_APP_XFER_SEGMENTS);
+ blk_queue_max_hw_sectors(q, MPI3MR_MAX_APP_XFER_SECTORS);
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0735/1887] wifi: rtw89: fix race between cancel_hw_scan and hw_scan completion
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (733 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0734/1887] scsi: mpi3mr: Fix possible crash when setting up bsg fails Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0736/1887] RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error Greg Kroah-Hartman
` (263 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ping-Ke Shih <pkshih@realtek.com>
[ Upstream commit ba4bb0402c60e945c4c396c51f0acac3c3e3ea5c ]
The rtwdev->scanning flag isn't protected by mutex originally, so
cancel_hw_scan can pass the condition, but suddenly hw_scan completion
unset the flag and calls ieee80211_scan_completed() that will free
local->hw_scan_req. Then, cancel_hw_scan raises null-ptr-deref and
use-after-free. Fix it by moving the check condition to where
protected by mutex.
KASAN: null-ptr-deref in range [0x0000000000000088-0x000000000000008f]
CPU: 2 PID: 6922 Comm: kworker/2:2 Tainted: G OE
Hardware name: LENOVO 2356AD1/2356AD1, BIOS G7ETB6WW (2.76 ) 09/10/2019
Workqueue: events cfg80211_conn_work [cfg80211]
RIP: 0010:rtw89_fw_h2c_scan_offload_be+0xc33/0x13c3 [rtw89_core]
Code: 00 45 89 6c 24 1c 0f 85 23 01 00 00 48 8b 85 20 ff ff ff 48 8d
RSP: 0018:ffff88811fd9f068 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: ffff88811fd9f258 RCX: 0000000000000001
RDX: 0000000000000011 RSI: 0000000000000001 RDI: 0000000000000089
RBP: ffff88811fd9f170 R08: 0000000000000000 R09: 0000000000000000
R10: ffff88811fd9f108 R11: 0000000000000000 R12: ffff88810e47f960
R13: 0000000000000000 R14: 000000000000ffff R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff8881d6f00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007531dfca55b0 CR3: 00000001be296004 CR4: 00000000001706e0
Call Trace:
<TASK>
? show_regs+0x61/0x73
? __die_body+0x20/0x73
? die_addr+0x4f/0x7b
? exc_general_protection+0x191/0x1db
? asm_exc_general_protection+0x27/0x30
? rtw89_fw_h2c_scan_offload_be+0xc33/0x13c3 [rtw89_core]
? rtw89_fw_h2c_scan_offload_be+0x458/0x13c3 [rtw89_core]
? __pfx_rtw89_fw_h2c_scan_offload_be+0x10/0x10 [rtw89_core]
? do_raw_spin_lock+0x75/0xdb
? __pfx_do_raw_spin_lock+0x10/0x10
rtw89_hw_scan_offload+0xb5e/0xbf7 [rtw89_core]
? _raw_spin_unlock+0xe/0x24
? __mutex_lock.constprop.0+0x40c/0x471
? __pfx_rtw89_hw_scan_offload+0x10/0x10 [rtw89_core]
? __mutex_lock_slowpath+0x13/0x1f
? mutex_lock+0xa2/0xdc
? __pfx_mutex_lock+0x10/0x10
rtw89_hw_scan_abort+0x58/0xb7 [rtw89_core]
rtw89_ops_cancel_hw_scan+0x120/0x13b [rtw89_core]
ieee80211_scan_cancel+0x468/0x4d0 [mac80211]
ieee80211_prep_connection+0x858/0x899 [mac80211]
ieee80211_mgd_auth+0xbea/0xdde [mac80211]
? __pfx_ieee80211_mgd_auth+0x10/0x10 [mac80211]
? cfg80211_find_elem+0x15/0x29 [cfg80211]
? is_bss+0x1b7/0x1d7 [cfg80211]
ieee80211_auth+0x18/0x27 [mac80211]
cfg80211_mlme_auth+0x3bb/0x3e7 [cfg80211]
cfg80211_conn_do_work+0x410/0xb81 [cfg80211]
? __pfx_cfg80211_conn_do_work+0x10/0x10 [cfg80211]
? __kasan_check_read+0x11/0x1f
? psi_group_change+0x8bc/0x944
? __kasan_check_write+0x14/0x22
? mutex_lock+0x8e/0xdc
? __pfx_mutex_lock+0x10/0x10
? __pfx___radix_tree_lookup+0x10/0x10
cfg80211_conn_work+0x245/0x34d [cfg80211]
? __pfx_cfg80211_conn_work+0x10/0x10 [cfg80211]
? update_cfs_rq_load_avg+0x3bc/0x3d7
? sched_clock_noinstr+0x9/0x1a
? sched_clock+0x10/0x24
? sched_clock_cpu+0x7e/0x42e
? newidle_balance+0x796/0x937
? __pfx_sched_clock_cpu+0x10/0x10
? __pfx_newidle_balance+0x10/0x10
? __kasan_check_read+0x11/0x1f
? psi_group_change+0x8bc/0x944
? _raw_spin_unlock+0xe/0x24
? raw_spin_rq_unlock+0x47/0x54
? raw_spin_rq_unlock_irq+0x9/0x1f
? finish_task_switch.isra.0+0x347/0x586
? __schedule+0x27bf/0x2892
? mutex_unlock+0x80/0xd0
? do_raw_spin_lock+0x75/0xdb
? __pfx___schedule+0x10/0x10
process_scheduled_works+0x58c/0x821
worker_thread+0x4c7/0x586
? __kasan_check_read+0x11/0x1f
kthread+0x285/0x294
? __pfx_worker_thread+0x10/0x10
? __pfx_kthread+0x10/0x10
ret_from_fork+0x29/0x6f
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1b/0x30
</TASK>
Fixes: 895907779752 ("rtw89: 8852a: add ieee80211_ops::hw_scan")
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250107114254.6769-1-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw89/mac80211.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 2c3a72900b9fb..7827f90d5bdcf 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -808,11 +808,14 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return;
+ mutex_lock(&rtwdev->mutex);
+
if (!rtwdev->scanning)
- return;
+ goto out;
- mutex_lock(&rtwdev->mutex);
rtw89_hw_scan_abort(rtwdev, vif);
+
+out:
mutex_unlock(&rtwdev->mutex);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0736/1887] RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (734 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0735/1887] wifi: rtw89: fix race between cancel_hw_scan and hw_scan completion Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0737/1887] net: ipv6: fix dst ref loops in rpl, seg6 and ioam6 lwtunnels Greg Kroah-Hartman
` (262 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yishai Hadas, Artemy Kovalyov,
Leon Romanovsky, Jason Gunthorpe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <yishaih@nvidia.com>
[ Upstream commit abb604a1a9c87255c7a6f3b784410a9707baf467 ]
This patch addresses a race condition for an ODP MR that can result in a
CQE with an error on the UMR QP.
During the __mlx5_ib_dereg_mr() flow, the following sequence of calls
occurs:
mlx5_revoke_mr()
mlx5r_umr_revoke_mr()
mlx5r_umr_post_send_wait()
At this point, the lkey is freed from the hardware's perspective.
However, concurrently, mlx5_ib_invalidate_range() might be triggered by
another task attempting to invalidate a range for the same freed lkey.
This task will:
- Acquire the umem_odp->umem_mutex lock.
- Call mlx5r_umr_update_xlt() on the UMR QP.
- Since the lkey has already been freed, this can lead to a CQE error,
causing the UMR QP to enter an error state [1].
To resolve this race condition, the umem_odp->umem_mutex lock is now also
acquired as part of the mlx5_revoke_mr() scope. Upon successful revoke,
we set umem_odp->private which points to that MR to NULL, preventing any
further invalidation attempts on its lkey.
[1] From dmesg:
infiniband rocep8s0f0: dump_cqe:277:(pid 0): WC error: 6, Message: memory bind operation error
cqe_dump: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
cqe_dump: 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
cqe_dump: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
cqe_dump: 00000030: 00 00 00 00 08 00 78 06 25 00 11 b9 00 0e dd d2
WARNING: CPU: 15 PID: 1506 at drivers/infiniband/hw/mlx5/umr.c:394 mlx5r_umr_post_send_wait+0x15a/0x2b0 [mlx5_ib]
Modules linked in: ip6table_mangle ip6table_natip6table_filter ip6_tables iptable_mangle xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry overlay rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_umad ib_ipoib ib_cm mlx5_ib ib_uverbs ib_core fuse mlx5_core
CPU: 15 UID: 0 PID: 1506 Comm: ibv_rc_pingpong Not tainted 6.12.0-rc7+ #1626
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:mlx5r_umr_post_send_wait+0x15a/0x2b0 [mlx5_ib]
[..]
Call Trace:
<TASK>
mlx5r_umr_update_xlt+0x23c/0x3e0 [mlx5_ib]
mlx5_ib_invalidate_range+0x2e1/0x330 [mlx5_ib]
__mmu_notifier_invalidate_range_start+0x1e1/0x240
zap_page_range_single+0xf1/0x1a0
madvise_vma_behavior+0x677/0x6e0
do_madvise+0x1a2/0x4b0
__x64_sys_madvise+0x25/0x30
do_syscall_64+0x6b/0x140
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fixes: e6fb246ccafb ("RDMA/mlx5: Consolidate MR destruction to mlx5_ib_dereg_mr()")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/r/68a1e007c25b2b8fe5d625f238cc3b63e5341f77.1737290229.git.leon@kernel.org
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Artemy Kovalyov <artemyko@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/mr.c | 31 +++++++++++++++++++++++++------
drivers/infiniband/hw/mlx5/odp.c | 2 ++
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 2cb4310cc3d68..60a67a77cd910 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1587,6 +1587,8 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
{
struct mlx5_ib_mr *mr = to_mmr(ibmr);
struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
+ bool is_odp = is_odp_mr(mr);
+ bool odp_locked = is_odp;
int rc;
/*
@@ -1628,25 +1630,42 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
}
/* Stop DMA */
+ if (odp_locked)
+ mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+
if (mr->mmkey.cache_ent) {
xa_lock_irq(&mr->mmkey.cache_ent->mkeys);
mr->mmkey.cache_ent->in_use--;
xa_unlock_irq(&mr->mmkey.cache_ent->mkeys);
- if (mlx5r_umr_revoke_mr(mr) ||
- push_mkey(mr->mmkey.cache_ent, false,
- xa_mk_value(mr->mmkey.key)))
+ if (mlx5r_umr_revoke_mr(mr)) {
mr->mmkey.cache_ent = NULL;
+ } else {
+ if (odp_locked) {
+ to_ib_umem_odp(mr->umem)->private = NULL;
+ mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+ odp_locked = false;
+ }
+ if (push_mkey(mr->mmkey.cache_ent, false,
+ xa_mk_value(mr->mmkey.key)))
+ mr->mmkey.cache_ent = NULL;
+ }
}
if (!mr->mmkey.cache_ent) {
rc = destroy_mkey(to_mdev(mr->ibmr.device), mr);
- if (rc)
+ if (rc) {
+ if (odp_locked)
+ mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
return rc;
+ }
}
- if (mr->umem) {
- bool is_odp = is_odp_mr(mr);
+ if (odp_locked) {
+ to_ib_umem_odp(mr->umem)->private = NULL;
+ mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+ }
+ if (mr->umem) {
if (!is_odp)
atomic_sub(ib_umem_num_pages(mr->umem),
&dev->mdev->priv.reg_pages);
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 1b5492b75b7d8..aa24d395a2dc8 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -265,6 +265,8 @@ static bool mlx5_ib_invalidate_range(struct mmu_interval_notifier *mni,
if (!umem_odp->npages)
goto out;
mr = umem_odp->private;
+ if (!mr)
+ goto out;
start = max_t(u64, ib_umem_start(umem_odp), range->start);
end = min_t(u64, ib_umem_end(umem_odp), range->end);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0737/1887] net: ipv6: fix dst ref loops in rpl, seg6 and ioam6 lwtunnels
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (735 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0736/1887] RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0738/1887] net: ravb: Fix missing rtnl lock in suspend/resume path Greg Kroah-Hartman
` (261 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Simon Horman, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 92191dd1073088753821b862b791dcc83e558e07 ]
Some lwtunnels have a dst cache for post-transformation dst.
If the packet destination did not change we may end up recording
a reference to the lwtunnel in its own cache, and the lwtunnel
state will never be freed.
Discovered by the ioam6.sh test, kmemleak was recently fixed
to catch per-cpu memory leaks. I'm not sure if rpl and seg6
can actually hit this, but in principle I don't see why not.
Fixes: 8cb3bf8bff3c ("ipv6: ioam: Add support for the ip6ip6 encapsulation")
Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250130031519.2716843-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ioam6_iptunnel.c | 9 ++++++---
net/ipv6/rpl_iptunnel.c | 9 ++++++---
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c
index 3a6065faaf9bf..b536eae433d79 100644
--- a/net/ipv6/ioam6_iptunnel.c
+++ b/net/ipv6/ioam6_iptunnel.c
@@ -365,9 +365,12 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
goto drop;
}
- local_bh_disable();
- dst_cache_set_ip6(&ilwt->cache, dst, &fl6.saddr);
- local_bh_enable();
+ /* cache only if we don't create a dst reference loop */
+ if (skb_dst(skb)->lwtstate != dst->lwtstate) {
+ local_bh_disable();
+ dst_cache_set_ip6(&ilwt->cache, dst, &fl6.saddr);
+ local_bh_enable();
+ }
}
skb_dst_drop(skb);
diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c
index cde14e180a85c..be38d40188ec0 100644
--- a/net/ipv6/rpl_iptunnel.c
+++ b/net/ipv6/rpl_iptunnel.c
@@ -236,9 +236,12 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb)
goto drop;
}
- local_bh_disable();
- dst_cache_set_ip6(&rlwt->cache, dst, &fl6.saddr);
- local_bh_enable();
+ /* cache only if we don't create a dst reference loop */
+ if (orig_dst->lwtstate != dst->lwtstate) {
+ local_bh_disable();
+ dst_cache_set_ip6(&rlwt->cache, dst, &fl6.saddr);
+ local_bh_enable();
+ }
err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev));
if (unlikely(err))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0738/1887] net: ravb: Fix missing rtnl lock in suspend/resume path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (736 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0737/1887] net: ipv6: fix dst ref loops in rpl, seg6 and ioam6 lwtunnels Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0739/1887] x86/PCI: Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4 Greg Kroah-Hartman
` (260 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Claudiu Beznea, Kory Maincent,
Niklas Söderlund, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <kory.maincent@bootlin.com>
[ Upstream commit 2c2ebb2b49573e5f8726112ad06b1dffc3c9ea03 ]
Fix the suspend/resume path by ensuring the rtnl lock is held where
required. Calls to ravb_open, ravb_close and wol operations must be
performed under the rtnl lock to prevent conflicts with ongoing ndo
operations.
Without this fix, the following warning is triggered:
[ 39.032969] =============================
[ 39.032983] WARNING: suspicious RCU usage
[ 39.033019] -----------------------------
[ 39.033033] drivers/net/phy/phy_device.c:2004 suspicious
rcu_dereference_protected() usage!
...
[ 39.033597] stack backtrace:
[ 39.033613] CPU: 0 UID: 0 PID: 174 Comm: python3 Not tainted
6.13.0-rc7-next-20250116-arm64-renesas-00002-g35245dfdc62c #7
[ 39.033623] Hardware name: Renesas SMARC EVK version 2 based on
r9a08g045s33 (DT)
[ 39.033628] Call trace:
[ 39.033633] show_stack+0x14/0x1c (C)
[ 39.033652] dump_stack_lvl+0xb4/0xc4
[ 39.033664] dump_stack+0x14/0x1c
[ 39.033671] lockdep_rcu_suspicious+0x16c/0x22c
[ 39.033682] phy_detach+0x160/0x190
[ 39.033694] phy_disconnect+0x40/0x54
[ 39.033703] ravb_close+0x6c/0x1cc
[ 39.033714] ravb_suspend+0x48/0x120
[ 39.033721] dpm_run_callback+0x4c/0x14c
[ 39.033731] device_suspend+0x11c/0x4dc
[ 39.033740] dpm_suspend+0xdc/0x214
[ 39.033748] dpm_suspend_start+0x48/0x60
[ 39.033758] suspend_devices_and_enter+0x124/0x574
[ 39.033769] pm_suspend+0x1ac/0x274
[ 39.033778] state_store+0x88/0x124
[ 39.033788] kobj_attr_store+0x14/0x24
[ 39.033798] sysfs_kf_write+0x48/0x6c
[ 39.033808] kernfs_fop_write_iter+0x118/0x1a8
[ 39.033817] vfs_write+0x27c/0x378
[ 39.033825] ksys_write+0x64/0xf4
[ 39.033833] __arm64_sys_write+0x18/0x20
[ 39.033841] invoke_syscall+0x44/0x104
[ 39.033852] el0_svc_common.constprop.0+0xb4/0xd4
[ 39.033862] do_el0_svc+0x18/0x20
[ 39.033870] el0_svc+0x3c/0xf0
[ 39.033880] el0t_64_sync_handler+0xc0/0xc4
[ 39.033888] el0t_64_sync+0x154/0x158
[ 39.041274] ravb 11c30000.ethernet eth0: Link is Down
Reported-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Closes: https://lore.kernel.org/netdev/4c6419d8-c06b-495c-b987-d66c2e1ff848@tuxon.dev/
Fixes: 0184165b2f42 ("ravb: add sleep PM suspend/resume support")
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/renesas/ravb_main.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index dcacd691b2efd..40b82f00e6e55 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -3028,10 +3028,12 @@ static int __maybe_unused ravb_suspend(struct device *dev)
netif_device_detach(ndev);
+ rtnl_lock();
if (priv->wol_enabled)
ret = ravb_wol_setup(ndev);
else
ret = ravb_close(ndev);
+ rtnl_unlock();
if (priv->info->ccc_gac)
ravb_ptp_stop(ndev);
@@ -3083,12 +3085,16 @@ static int __maybe_unused ravb_resume(struct device *dev)
ravb_ptp_init(ndev, priv->pdev);
if (netif_running(ndev)) {
+ rtnl_lock();
if (priv->wol_enabled) {
ret = ravb_wol_restore(ndev);
- if (ret)
+ if (ret) {
+ rtnl_unlock();
return ret;
+ }
}
ret = ravb_open(ndev);
+ rtnl_unlock();
if (ret < 0)
return ret;
ravb_set_rx_mode(ndev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0739/1887] x86/PCI: Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (737 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0738/1887] net: ravb: Fix missing rtnl lock in suspend/resume path Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0740/1887] PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1 Greg Kroah-Hartman
` (259 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iain Lane, Mario Limonciello,
Bjorn Helgaas, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <mario.limonciello@amd.com>
[ Upstream commit 7d08f21f8c6307cb05cabb8d86e90ff6ccba57e9 ]
Iain reports that USB devices can't be used to wake a Lenovo Z13 from
suspend. This occurs because on some AMD platforms, even though the Root
Ports advertise PME_Support for D3hot and D3cold, wakeup events from
devices on a USB4 controller don't result in wakeup interrupts from the
Root Port when amd-pmc has put the platform in a hardware sleep state.
If amd-pmc will be involved in the suspend, remove D3hot and D3cold from
the PME_Support mask of Root Ports above USB4 controllers so we avoid those
states if we need wakeups.
Restore D3 support at resume so that it can be used by runtime suspend.
This affects both AMD Rembrandt and Phoenix SoCs.
"pm_suspend_target_state == PM_SUSPEND_ON" means we're doing runtime
suspend, and amd-pmc will not be involved. In that case PMEs work as
advertised in D3hot/D3cold, so we don't need to do anything.
Note that amd-pmc is technically optional, and there's no need for this
quirk if it's not present, but we assume it's always present because power
consumption is so high without it.
Fixes: 9d26d3a8f1b0 ("PCI: Put PCIe ports into D3 during suspend")
Link: https://lore.kernel.org/r/20231004144959.158840-1-mario.limonciello@amd.com
Reported-by: Iain Lane <iain@orangesquash.org.uk>
Closes: https://forums.lenovo.com/t5/Ubuntu/Z13-can-t-resume-from-suspend-with-external-USB-keyboard/m-p/5217121
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
[bhelgaas: commit log, move to arch/x86/pci/fixup.c, add #includes]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Stable-dep-of: b1049f2d6869 ("PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/pci/fixup.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 6ea3a64764b9a..0e9f26e236d48 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -3,9 +3,11 @@
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
*/
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/pci.h>
+#include <linux/suspend.h>
#include <linux/vgaarb.h>
#include <asm/amd_nb.h>
#include <asm/hpet.h>
@@ -944,3 +946,60 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1122,
quirk_amd_nbio_7_11_disable_enhanced_atomic);
#endif
+
+#ifdef CONFIG_SUSPEND
+/*
+ * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
+ * if the SoC is put into a hardware sleep state by the amd-pmc driver, the
+ * Root Ports don't generate wakeup interrupts for USB devices.
+ *
+ * When suspending, remove D3hot and D3cold from the PME_Support advertised
+ * by the Root Port so we don't use those states if we're expecting wakeup
+ * interrupts. Restore the advertised PME_Support when resuming.
+ */
+static void amd_rp_pme_suspend(struct pci_dev *dev)
+{
+ struct pci_dev *rp;
+
+ /*
+ * PM_SUSPEND_ON means we're doing runtime suspend, which means
+ * amd-pmc will not be involved so PMEs during D3 work as advertised.
+ *
+ * The PMEs *do* work if amd-pmc doesn't put the SoC in the hardware
+ * sleep state, but we assume amd-pmc is always present.
+ */
+ if (pm_suspend_target_state == PM_SUSPEND_ON)
+ return;
+
+ rp = pcie_find_root_port(dev);
+ if (!rp->pm_cap)
+ return;
+
+ rp->pme_support &= ~((PCI_PM_CAP_PME_D3hot|PCI_PM_CAP_PME_D3cold) >>
+ PCI_PM_CAP_PME_SHIFT);
+ dev_info_once(&rp->dev, "quirk: disabling D3cold for suspend\n");
+}
+
+static void amd_rp_pme_resume(struct pci_dev *dev)
+{
+ struct pci_dev *rp;
+ u16 pmc;
+
+ rp = pcie_find_root_port(dev);
+ if (!rp->pm_cap)
+ return;
+
+ pci_read_config_word(rp, rp->pm_cap + PCI_PM_PMC, &pmc);
+ rp->pme_support = FIELD_GET(PCI_PM_CAP_PME_MASK, pmc);
+}
+/* Rembrandt (yellow_carp) */
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x162e, amd_rp_pme_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x162e, amd_rp_pme_resume);
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x162f, amd_rp_pme_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x162f, amd_rp_pme_resume);
+/* Phoenix (pink_sardine) */
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume);
+DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume);
+#endif /* CONFIG_SUSPEND */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0740/1887] PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (738 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0739/1887] x86/PCI: Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4 Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0741/1887] ASoC: SOF: ipc4-topology: Harden loops for looking up ALH copiers Greg Kroah-Hartman
` (258 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Georg Gottleuber,
Werner Sembach, Krzysztof Wilczyński, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <wse@tuxedocomputers.com>
[ Upstream commit b1049f2d68693c80a576c4578d96774a68df2bad ]
commit 9d26d3a8f1b0 ("PCI: Put PCIe ports into D3 during suspend") sets the
policy that all PCIe ports are allowed to use D3. When the system is
suspended if the port is not power manageable by the platform and won't be
used for wakeup via a PME this sets up the policy for these ports to go
into D3hot.
This policy generally makes sense from an OSPM perspective but it leads to
problems with wakeup from suspend on the TUXEDO Sirius 16 Gen 1 with a
specific old BIOS. This manifests as a system hang.
On the affected Device + BIOS combination, add a quirk for the root port of
the problematic controller to ensure that these root ports are not put into
D3hot at suspend.
This patch is based on
https://lore.kernel.org/linux-pci/20230708214457.1229-2-mario.limonciello@amd.com
but with the added condition both in the documentation and in the code to
apply only to the TUXEDO Sirius 16 Gen 1 with a specific old BIOS and only
the affected root ports.
Fixes: 9d26d3a8f1b0 ("PCI: Put PCIe ports into D3 during suspend")
Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20250114222436.1075456-1-wse@tuxedocomputers.com
Co-developed-by: Georg Gottleuber <ggo@tuxedocomputers.com>
Signed-off-by: Georg Gottleuber <ggo@tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Cc: <stable@vger.kernel.org> # 6.1+
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/pci/fixup.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 0e9f26e236d48..7d06107ab9826 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -1002,4 +1002,34 @@ DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_suspend);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume);
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume);
+
+/*
+ * Putting PCIe root ports on Ryzen SoCs with USB4 controllers into D3hot
+ * may cause problems when the system attempts wake up from s2idle.
+ *
+ * On the TUXEDO Sirius 16 Gen 1 with a specific old BIOS this manifests as
+ * a system hang.
+ */
+static const struct dmi_system_id quirk_tuxeo_rp_d3_dmi_table[] = {
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "APX958"),
+ DMI_EXACT_MATCH(DMI_BIOS_VERSION, "V1.00A00_20240108"),
+ },
+ },
+ {}
+};
+
+static void quirk_tuxeo_rp_d3(struct pci_dev *pdev)
+{
+ struct pci_dev *root_pdev;
+
+ if (dmi_check_system(quirk_tuxeo_rp_d3_dmi_table)) {
+ root_pdev = pcie_find_root_port(pdev);
+ if (root_pdev)
+ root_pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3);
#endif /* CONFIG_SUSPEND */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0741/1887] ASoC: SOF: ipc4-topology: Harden loops for looking up ALH copiers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (739 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0740/1887] PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1 Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0742/1887] efi: Dont map the entire mokvar table to determine its size Greg Kroah-Hartman
` (257 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Seppo Ingalsuo, Peter Ujfalusi,
Liam Girdwood, Ranjani Sridharan, Bard Liao, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
[ Upstream commit 6fd60136d256b3b948333ebdb3835f41a95ab7ef ]
Other, non DAI copier widgets could have the same stream name (sname) as
the ALH copier and in that case the copier->data is NULL, no alh_data is
attached, which could lead to NULL pointer dereference.
We could check for this NULL pointer in sof_ipc4_prepare_copier_module()
and avoid the crash, but a similar loop in sof_ipc4_widget_setup_comp_dai()
will miscalculate the ALH device count, causing broken audio.
The correct fix is to harden the matching logic by making sure that the
1. widget is a DAI widget - so dai = w->private is valid
2. the dai (and thus the copier) is ALH copier
Fixes: a150345aa758 ("ASoC: SOF: ipc4-topology: add SoundWire/ALH aggregation support")
Reported-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Link: https://github.com/thesofproject/sof/pull/9652
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20250206084642.14988-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sof/ipc4-topology.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index ee6f6edec970c..413dc2d8afb65 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -515,7 +515,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
}
list_for_each_entry(w, &sdev->widget_list, list) {
- if (w->widget->sname &&
+ if (!WIDGET_IS_DAI(w->id) || !w->widget->sname ||
strcmp(w->widget->sname, swidget->widget->sname))
continue;
@@ -1237,17 +1237,20 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
*/
i = 0;
list_for_each_entry(w, &sdev->widget_list, list) {
- if (w->widget->sname &&
+ if (!WIDGET_IS_DAI(w->id) || !w->widget->sname ||
strcmp(w->widget->sname, swidget->widget->sname))
continue;
dai = w->private;
alh_copier = (struct sof_ipc4_copier *)dai->private;
+ if (alh_copier->dai_type != SOF_DAI_INTEL_ALH)
+ continue;
alh_data = &alh_copier->data;
blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
blob->alh_cfg.mapping[i].channel_mask = ch_mask;
i++;
}
+ blob->alh_cfg.count = i;
if (blob->alh_cfg.count > 1) {
int group_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0742/1887] efi: Dont map the entire mokvar table to determine its size
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (740 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0741/1887] ASoC: SOF: ipc4-topology: Harden loops for looking up ALH copiers Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0743/1887] RDMA/bnxt_re: Fix the page details for the srq created by kernel consumers Greg Kroah-Hartman
` (256 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peter Jones, Ard Biesheuvel,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Jones <pjones@redhat.com>
[ Upstream commit 2b90e7ace79774a3540ce569e000388f8d22c9e0 ]
Currently, when validating the mokvar table, we (re)map the entire table
on each iteration of the loop, adding space as we discover new entries.
If the table grows over a certain size, this fails due to limitations of
early_memmap(), and we get a failure and traceback:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:139 __early_ioremap+0xef/0x220
...
Call Trace:
<TASK>
? __early_ioremap+0xef/0x220
? __warn.cold+0x93/0xfa
? __early_ioremap+0xef/0x220
? report_bug+0xff/0x140
? early_fixup_exception+0x5d/0xb0
? early_idt_handler_common+0x2f/0x3a
? __early_ioremap+0xef/0x220
? efi_mokvar_table_init+0xce/0x1d0
? setup_arch+0x864/0xc10
? start_kernel+0x6b/0xa10
? x86_64_start_reservations+0x24/0x30
? x86_64_start_kernel+0xed/0xf0
? common_startup_64+0x13e/0x141
</TASK>
---[ end trace 0000000000000000 ]---
mokvar: Failed to map EFI MOKvar config table pa=0x7c4c3000, size=265187.
Mapping the entire structure isn't actually necessary, as we don't ever
need more than one entry header mapped at once.
Changes efi_mokvar_table_init() to only map each entry header, not the
entire table, when determining the table size. Since we're not mapping
any data past the variable name, it also changes the code to enforce
that each variable name is NUL terminated, rather than attempting to
verify it in place.
Cc: <stable@vger.kernel.org>
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/efi/mokvar-table.c | 42 +++++++++--------------------
1 file changed, 13 insertions(+), 29 deletions(-)
diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c
index 37e1fe7a2f2b3..bd84a22805b56 100644
--- a/drivers/firmware/efi/mokvar-table.c
+++ b/drivers/firmware/efi/mokvar-table.c
@@ -103,9 +103,7 @@ void __init efi_mokvar_table_init(void)
void *va = NULL;
unsigned long cur_offset = 0;
unsigned long offset_limit;
- unsigned long map_size = 0;
unsigned long map_size_needed = 0;
- unsigned long size;
struct efi_mokvar_table_entry *mokvar_entry;
int err;
@@ -134,48 +132,34 @@ void __init efi_mokvar_table_init(void)
*/
err = -EINVAL;
while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
- mokvar_entry = va + cur_offset;
- map_size_needed = cur_offset + sizeof(*mokvar_entry);
- if (map_size_needed > map_size) {
- if (va)
- early_memunmap(va, map_size);
- /*
- * Map a little more than the fixed size entry
- * header, anticipating some data. It's safe to
- * do so as long as we stay within current memory
- * descriptor.
- */
- map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
- offset_limit);
- va = early_memremap(efi.mokvar_table, map_size);
- if (!va) {
- pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
- efi.mokvar_table, map_size);
- return;
- }
- mokvar_entry = va + cur_offset;
+ if (va)
+ early_memunmap(va, sizeof(*mokvar_entry));
+ va = early_memremap(efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
+ if (!va) {
+ pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%zu.\n",
+ efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
+ return;
}
+ mokvar_entry = va;
/* Check for last sentinel entry */
if (mokvar_entry->name[0] == '\0') {
if (mokvar_entry->data_size != 0)
break;
err = 0;
+ map_size_needed = cur_offset + sizeof(*mokvar_entry);
break;
}
- /* Sanity check that the name is null terminated */
- size = strnlen(mokvar_entry->name,
- sizeof(mokvar_entry->name));
- if (size >= sizeof(mokvar_entry->name))
- break;
+ /* Enforce that the name is NUL terminated */
+ mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
/* Advance to the next entry */
- cur_offset = map_size_needed + mokvar_entry->data_size;
+ cur_offset += sizeof(*mokvar_entry) + mokvar_entry->data_size;
}
if (va)
- early_memunmap(va, map_size);
+ early_memunmap(va, sizeof(*mokvar_entry));
if (err) {
pr_err("EFI MOKvar config table is not valid\n");
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0743/1887] RDMA/bnxt_re: Fix the page details for the srq created by kernel consumers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (741 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0742/1887] efi: Dont map the entire mokvar table to determine its size Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0744/1887] RDMA/mlx5: Fix a WARN during dereg_mr for DM type Greg Kroah-Hartman
` (255 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kashyap Desai, Selvin Xavier,
Leon Romanovsky, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <kashyap.desai@broadcom.com>
[ Upstream commit b66535356a4834a234f99e16a97eb51f2c6c5a7d ]
While using nvme target with use_srq on, below kernel panic is noticed.
[ 549.698111] bnxt_en 0000:41:00.0 enp65s0np0: FEC autoneg off encoding: Clause 91 RS(544,514)
[ 566.393619] Oops: divide error: 0000 [#1] PREEMPT SMP NOPTI
..
[ 566.393799] <TASK>
[ 566.393807] ? __die_body+0x1a/0x60
[ 566.393823] ? die+0x38/0x60
[ 566.393835] ? do_trap+0xe4/0x110
[ 566.393847] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
[ 566.393867] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
[ 566.393881] ? do_error_trap+0x7c/0x120
[ 566.393890] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
[ 566.393911] ? exc_divide_error+0x34/0x50
[ 566.393923] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
[ 566.393939] ? asm_exc_divide_error+0x16/0x20
[ 566.393966] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
[ 566.393997] bnxt_qplib_create_srq+0xc9/0x340 [bnxt_re]
[ 566.394040] bnxt_re_create_srq+0x335/0x3b0 [bnxt_re]
[ 566.394057] ? srso_return_thunk+0x5/0x5f
[ 566.394068] ? __init_swait_queue_head+0x4a/0x60
[ 566.394090] ib_create_srq_user+0xa7/0x150 [ib_core]
[ 566.394147] nvmet_rdma_queue_connect+0x7d0/0xbe0 [nvmet_rdma]
[ 566.394174] ? lock_release+0x22c/0x3f0
[ 566.394187] ? srso_return_thunk+0x5/0x5f
Page size and shift info is set only for the user space SRQs.
Set page size and page shift for kernel space SRQs also.
Fixes: 0c4dcd602817 ("RDMA/bnxt_re: Refactor hardware queue memory allocation")
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Link: https://patch.msgid.link/1740237621-29291-1-git-send-email-selvin.xavier@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 63fae7263c89c..9db0d824d4627 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1659,6 +1659,8 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
srq->qplib_srq.threshold = srq_init_attr->attr.srq_limit;
srq->srq_limit = srq_init_attr->attr.srq_limit;
srq->qplib_srq.eventq_hw_ring_id = rdev->nq[0].ring_id;
+ srq->qplib_srq.sg_info.pgsize = PAGE_SIZE;
+ srq->qplib_srq.sg_info.pgshft = PAGE_SHIFT;
nq = &rdev->nq[0];
if (udata) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0744/1887] RDMA/mlx5: Fix a WARN during dereg_mr for DM type
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (742 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0743/1887] RDMA/bnxt_re: Fix the page details for the srq created by kernel consumers Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0745/1887] RDMA/mlx5: Dont keep umrable page_shift in cache entries Greg Kroah-Hartman
` (254 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yishai Hadas, Leon Romanovsky,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <yishaih@nvidia.com>
[ Upstream commit abc7b3f1f056d69a8f11d6dceecc0c9549ace770 ]
Memory regions (MR) of type DM (device memory) do not have an associated
umem.
In the __mlx5_ib_dereg_mr() -> mlx5_free_priv_descs() flow, the code
incorrectly takes the wrong branch, attempting to call
dma_unmap_single() on a DMA address that is not mapped.
This results in a WARN [1], as shown below.
The issue is resolved by properly accounting for the DM type and
ensuring the correct branch is selected in mlx5_free_priv_descs().
[1]
WARNING: CPU: 12 PID: 1346 at drivers/iommu/dma-iommu.c:1230 iommu_dma_unmap_page+0x79/0x90
Modules linked in: ip6table_mangle ip6table_nat ip6table_filter ip6_tables iptable_mangle xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry ovelay rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm mlx5_ib ib_uverbs ib_core fuse mlx5_core
CPU: 12 UID: 0 PID: 1346 Comm: ibv_rc_pingpong Not tainted 6.12.0-rc7+ #1631
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:iommu_dma_unmap_page+0x79/0x90
Code: 2b 49 3b 29 72 26 49 3b 69 08 73 20 4d 89 f0 44 89 e9 4c 89 e2 48 89 ee 48 89 df 5b 5d 41 5c 41 5d 41 5e 41 5f e9 07 b8 88 ff <0f> 0b 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 66 0f 1f 44 00
RSP: 0018:ffffc90001913a10 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff88810194b0a8 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001
RBP: ffff88810194b0a8 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000
FS: 00007f537abdd740(0000) GS:ffff88885fb00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f537aeb8000 CR3: 000000010c248001 CR4: 0000000000372eb0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
? __warn+0x84/0x190
? iommu_dma_unmap_page+0x79/0x90
? report_bug+0xf8/0x1c0
? handle_bug+0x55/0x90
? exc_invalid_op+0x13/0x60
? asm_exc_invalid_op+0x16/0x20
? iommu_dma_unmap_page+0x79/0x90
dma_unmap_page_attrs+0xe6/0x290
mlx5_free_priv_descs+0xb0/0xe0 [mlx5_ib]
__mlx5_ib_dereg_mr+0x37e/0x520 [mlx5_ib]
? _raw_spin_unlock_irq+0x24/0x40
? wait_for_completion+0xfe/0x130
? rdma_restrack_put+0x63/0xe0 [ib_core]
ib_dereg_mr_user+0x5f/0x120 [ib_core]
? lock_release+0xc6/0x280
destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
uobj_destroy+0x3f/0x70 [ib_uverbs]
ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
? lock_acquire+0xc1/0x2f0
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
? ib_uverbs_ioctl+0x116/0x170 [ib_uverbs]
? lock_release+0xc6/0x280
ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
__x64_sys_ioctl+0x1b0/0xa70
do_syscall_64+0x6b/0x140
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f537adaf17b
Code: 0f 1e fa 48 8b 05 1d ad 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ed ac 0c 00 f7 d8 64 89 01 48
RSP: 002b:00007ffff218f0b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007ffff218f1d8 RCX: 00007f537adaf17b
RDX: 00007ffff218f1c0 RSI: 00000000c0181b01 RDI: 0000000000000003
RBP: 00007ffff218f1a0 R08: 00007f537aa8d010 R09: 0000561ee2e4f270
R10: 00007f537aace3a8 R11: 0000000000000246 R12: 00007ffff218f190
R13: 000000000000001c R14: 0000561ee2e4d7c0 R15: 00007ffff218f450
</TASK>
Fixes: f18ec4223117 ("RDMA/mlx5: Use a union inside mlx5_ib_mr")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Link: https://patch.msgid.link/2039c22cfc3df02378747ba4d623a558b53fc263.1738587076.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/mr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 60a67a77cd910..6dfd425e28c1a 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1571,7 +1571,7 @@ mlx5_alloc_priv_descs(struct ib_device *device,
static void
mlx5_free_priv_descs(struct mlx5_ib_mr *mr)
{
- if (!mr->umem && mr->descs) {
+ if (!mr->umem && mr->ibmr.type != IB_MR_TYPE_DM && mr->descs) {
struct ib_device *device = mr->ibmr.device;
int size = mr->max_descs * mr->desc_size;
struct mlx5_ib_dev *dev = to_mdev(device);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0745/1887] RDMA/mlx5: Dont keep umrable page_shift in cache entries
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (743 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0744/1887] RDMA/mlx5: Fix a WARN during dereg_mr for DM type Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0746/1887] RDMA/mlx5: Remove implicit ODP cache entry Greg Kroah-Hartman
` (253 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aharon Landau, Jason Gunthorpe,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aharon Landau <aharonl@nvidia.com>
[ Upstream commit a2a88b8e22d1b202225d0e40b02ad068afab2ccb ]
mkc.log_page_size can be changed using UMR. Therefore, don't treat it as a
cache entry property.
Removing it from struct mlx5_cache_ent.
All cache mkeys will be created with default PAGE_SHIFT, and updated with
the needed page_shift using UMR when passing them to a user.
Link: https://lore.kernel.org/r/20230125222807.6921-2-michaelgur@nvidia.com
Signed-off-by: Aharon Landau <aharonl@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 -
drivers/infiniband/hw/mlx5/mr.c | 3 +--
drivers/infiniband/hw/mlx5/odp.c | 2 --
3 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index e8e285233b355..3f805e935943c 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -759,7 +759,6 @@ struct mlx5_cache_ent {
char name[4];
u32 order;
u32 access_mode;
- u32 page;
unsigned int ndescs;
u8 disabled:1;
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 6dfd425e28c1a..58f2d645404e6 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -297,7 +297,7 @@ static void set_cache_mkc(struct mlx5_cache_ent *ent, void *mkc)
MLX5_SET(mkc, mkc, translations_octword_size,
get_mkc_octo_size(ent->access_mode, ent->ndescs));
- MLX5_SET(mkc, mkc, log_page_size, ent->page);
+ MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT);
}
/* Asynchronously schedule new MRs to be populated in the cache. */
@@ -765,7 +765,6 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
if (ent->order > mkey_cache_max_order(dev))
continue;
- ent->page = PAGE_SHIFT;
ent->ndescs = 1 << ent->order;
ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) &&
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index aa24d395a2dc8..6eb86a475ce91 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -1616,14 +1616,12 @@ void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent)
switch (ent->order - 2) {
case MLX5_IMR_MTT_CACHE_ENTRY:
- ent->page = PAGE_SHIFT;
ent->ndescs = MLX5_IMR_MTT_ENTRIES;
ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
ent->limit = 0;
break;
case MLX5_IMR_KSM_CACHE_ENTRY:
- ent->page = MLX5_KSM_PAGE_SHIFT;
ent->ndescs = mlx5_imr_ksm_entries;
ent->access_mode = MLX5_MKC_ACCESS_MODE_KSM;
ent->limit = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0746/1887] RDMA/mlx5: Remove implicit ODP cache entry
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (744 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0745/1887] RDMA/mlx5: Dont keep umrable page_shift in cache entries Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0747/1887] RDMA/mlx5: Change the cache structure to an RB-tree Greg Kroah-Hartman
` (252 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aharon Landau, Jason Gunthorpe,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aharon Landau <aharonl@nvidia.com>
[ Upstream commit 18b1746bddf5e7f6b2618966596d9517172a5cd7 ]
Implicit ODP mkey doesn't have unique properties. It shares the same
properties as the order 18 cache entry. There is no need to devote a
special entry for that.
Link: https://lore.kernel.org/r/20230125222807.6921-3-michaelgur@nvidia.com
Signed-off-by: Aharon Landau <aharonl@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/odp.c | 20 +++++---------------
include/linux/mlx5/driver.h | 1 -
2 files changed, 5 insertions(+), 16 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 6eb86a475ce91..27bde04ebc1df 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -424,6 +424,7 @@ static void mlx5_ib_page_fault_resume(struct mlx5_ib_dev *dev,
static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
unsigned long idx)
{
+ int order = order_base_2(MLX5_IMR_MTT_ENTRIES);
struct mlx5_ib_dev *dev = mr_to_mdev(imr);
struct ib_umem_odp *odp;
struct mlx5_ib_mr *mr;
@@ -436,7 +437,8 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
if (IS_ERR(odp))
return ERR_CAST(odp);
- mr = mlx5_mr_cache_alloc(dev, &dev->cache.ent[MLX5_IMR_MTT_CACHE_ENTRY],
+ BUILD_BUG_ON(order > MKEY_CACHE_LAST_STD_ENTRY);
+ mr = mlx5_mr_cache_alloc(dev, &dev->cache.ent[order],
imr->access_flags);
if (IS_ERR(mr)) {
ib_umem_odp_release(odp);
@@ -1613,20 +1615,8 @@ void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent)
{
if (!(ent->dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT))
return;
-
- switch (ent->order - 2) {
- case MLX5_IMR_MTT_CACHE_ENTRY:
- ent->ndescs = MLX5_IMR_MTT_ENTRIES;
- ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
- ent->limit = 0;
- break;
-
- case MLX5_IMR_KSM_CACHE_ENTRY:
- ent->ndescs = mlx5_imr_ksm_entries;
- ent->access_mode = MLX5_MKC_ACCESS_MODE_KSM;
- ent->limit = 0;
- break;
- }
+ ent->ndescs = mlx5_imr_ksm_entries;
+ ent->access_mode = MLX5_MKC_ACCESS_MODE_KSM;
}
static const struct ib_device_ops mlx5_ib_dev_odp_ops = {
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 0e8705c3a460d..6948767d52522 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -747,7 +747,6 @@ enum {
enum {
MKEY_CACHE_LAST_STD_ENTRY = 20,
- MLX5_IMR_MTT_CACHE_ENTRY,
MLX5_IMR_KSM_CACHE_ENTRY,
MAX_MKEY_CACHE_ENTRIES
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0747/1887] RDMA/mlx5: Change the cache structure to an RB-tree
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (745 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0746/1887] RDMA/mlx5: Remove implicit ODP cache entry Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0748/1887] RDMA/mlx5: Introduce mlx5r_cache_rb_key Greg Kroah-Hartman
` (251 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Guralnik, Jason Gunthorpe,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <michaelgur@nvidia.com>
[ Upstream commit b9584517832858a0f78d6851d09b697a829514cd ]
Currently, the cache structure is a static linear array. Therefore, his
size is limited to the number of entries in it and is not expandable. The
entries are dedicated to mkeys of size 2^x and no access_flags. Mkeys with
different properties are not cacheable.
In this patch, we change the cache structure to an RB-tree. This will
allow to extend the cache to support more entries with different mkey
properties.
Link: https://lore.kernel.org/r/20230125222807.6921-4-michaelgur@nvidia.com
Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/mlx5_ib.h | 11 +-
drivers/infiniband/hw/mlx5/mr.c | 160 ++++++++++++++++++++-------
drivers/infiniband/hw/mlx5/odp.c | 8 +-
3 files changed, 132 insertions(+), 47 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 3f805e935943c..8482ac9224b0a 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -761,6 +761,8 @@ struct mlx5_cache_ent {
u32 access_mode;
unsigned int ndescs;
+ struct rb_node node;
+
u8 disabled:1;
u8 fill_to_high_water:1;
@@ -790,8 +792,9 @@ struct mlx5r_async_create_mkey {
struct mlx5_mkey_cache {
struct workqueue_struct *wq;
- struct mlx5_cache_ent ent[MAX_MKEY_CACHE_ENTRIES];
- struct dentry *root;
+ struct rb_root rb_root;
+ struct mutex rb_lock;
+ struct dentry *fs_root;
unsigned long last_add;
};
@@ -1336,11 +1339,15 @@ void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num);
int mlx5_ib_get_cqe_size(struct ib_cq *ibcq);
int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev);
int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev);
+struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
+ int order);
struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
struct mlx5_cache_ent *ent,
int access_flags);
+struct mlx5_ib_mr *mlx5_mr_cache_alloc_order(struct mlx5_ib_dev *dev, u32 order,
+ int access_flags);
int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
struct ib_mr_status *mr_status);
struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 58f2d645404e6..d97bf49688ca8 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -515,18 +515,22 @@ static const struct file_operations limit_fops = {
static bool someone_adding(struct mlx5_mkey_cache *cache)
{
- unsigned int i;
-
- for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- struct mlx5_cache_ent *ent = &cache->ent[i];
- bool ret;
+ struct mlx5_cache_ent *ent;
+ struct rb_node *node;
+ bool ret;
+ mutex_lock(&cache->rb_lock);
+ for (node = rb_first(&cache->rb_root); node; node = rb_next(node)) {
+ ent = rb_entry(node, struct mlx5_cache_ent, node);
xa_lock_irq(&ent->mkeys);
ret = ent->stored < ent->limit;
xa_unlock_irq(&ent->mkeys);
- if (ret)
+ if (ret) {
+ mutex_unlock(&cache->rb_lock);
return true;
+ }
}
+ mutex_unlock(&cache->rb_lock);
return false;
}
@@ -637,6 +641,59 @@ static void delayed_cache_work_func(struct work_struct *work)
__cache_work_func(ent);
}
+static int mlx5_cache_ent_insert(struct mlx5_mkey_cache *cache,
+ struct mlx5_cache_ent *ent)
+{
+ struct rb_node **new = &cache->rb_root.rb_node, *parent = NULL;
+ struct mlx5_cache_ent *cur;
+
+ mutex_lock(&cache->rb_lock);
+ /* Figure out where to put new node */
+ while (*new) {
+ cur = rb_entry(*new, struct mlx5_cache_ent, node);
+ parent = *new;
+ if (ent->order < cur->order)
+ new = &((*new)->rb_left);
+ if (ent->order > cur->order)
+ new = &((*new)->rb_right);
+ if (ent->order == cur->order) {
+ mutex_unlock(&cache->rb_lock);
+ return -EEXIST;
+ }
+ }
+
+ /* Add new node and rebalance tree. */
+ rb_link_node(&ent->node, parent, new);
+ rb_insert_color(&ent->node, &cache->rb_root);
+
+ mutex_unlock(&cache->rb_lock);
+ return 0;
+}
+
+static struct mlx5_cache_ent *mkey_cache_ent_from_order(struct mlx5_ib_dev *dev,
+ unsigned int order)
+{
+ struct rb_node *node = dev->cache.rb_root.rb_node;
+ struct mlx5_cache_ent *cur, *smallest = NULL;
+
+ /*
+ * Find the smallest ent with order >= requested_order.
+ */
+ while (node) {
+ cur = rb_entry(node, struct mlx5_cache_ent, node);
+ if (cur->order > order) {
+ smallest = cur;
+ node = node->rb_left;
+ }
+ if (cur->order < order)
+ node = node->rb_right;
+ if (cur->order == order)
+ return cur;
+ }
+
+ return smallest;
+}
+
struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
struct mlx5_cache_ent *ent,
int access_flags)
@@ -677,10 +734,16 @@ struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
return mr;
}
-static void clean_keys(struct mlx5_ib_dev *dev, int c)
+struct mlx5_ib_mr *mlx5_mr_cache_alloc_order(struct mlx5_ib_dev *dev,
+ u32 order, int access_flags)
+{
+ struct mlx5_cache_ent *ent = mkey_cache_ent_from_order(dev, order);
+
+ return mlx5_mr_cache_alloc(dev, ent, access_flags);
+}
+
+static void clean_keys(struct mlx5_ib_dev *dev, struct mlx5_cache_ent *ent)
{
- struct mlx5_mkey_cache *cache = &dev->cache;
- struct mlx5_cache_ent *ent = &cache->ent[c];
u32 mkey;
cancel_delayed_work(&ent->dwork);
@@ -699,8 +762,8 @@ static void mlx5_mkey_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
if (!mlx5_debugfs_root || dev->is_rep)
return;
- debugfs_remove_recursive(dev->cache.root);
- dev->cache.root = NULL;
+ debugfs_remove_recursive(dev->cache.fs_root);
+ dev->cache.fs_root = NULL;
}
static void mlx5_mkey_cache_debugfs_init(struct mlx5_ib_dev *dev)
@@ -713,12 +776,13 @@ static void mlx5_mkey_cache_debugfs_init(struct mlx5_ib_dev *dev)
if (!mlx5_debugfs_root || dev->is_rep)
return;
- cache->root = debugfs_create_dir("mr_cache", mlx5_debugfs_get_dev_root(dev->mdev));
+ dir = mlx5_debugfs_get_dev_root(dev->mdev);
+ cache->fs_root = debugfs_create_dir("mr_cache", dir);
for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- ent = &cache->ent[i];
+ ent = mkey_cache_ent_from_order(dev, i);
sprintf(ent->name, "%d", ent->order);
- dir = debugfs_create_dir(ent->name, cache->root);
+ dir = debugfs_create_dir(ent->name, cache->fs_root);
debugfs_create_file("size", 0600, dir, ent, &size_fops);
debugfs_create_file("limit", 0600, dir, ent, &limit_fops);
debugfs_create_ulong("cur", 0400, dir, &ent->stored);
@@ -733,6 +797,30 @@ static void delay_time_func(struct timer_list *t)
WRITE_ONCE(dev->fill_delay, 0);
}
+struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
+ int order)
+{
+ struct mlx5_cache_ent *ent;
+ int ret;
+
+ ent = kzalloc(sizeof(*ent), GFP_KERNEL);
+ if (!ent)
+ return ERR_PTR(-ENOMEM);
+
+ xa_init_flags(&ent->mkeys, XA_FLAGS_LOCK_IRQ);
+ ent->order = order;
+ ent->dev = dev;
+
+ INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
+
+ ret = mlx5_cache_ent_insert(&dev->cache, ent);
+ if (ret) {
+ kfree(ent);
+ return ERR_PTR(ret);
+ }
+ return ent;
+}
+
int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
{
struct mlx5_mkey_cache *cache = &dev->cache;
@@ -740,6 +828,8 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
int i;
mutex_init(&dev->slow_path_mutex);
+ mutex_init(&dev->cache.rb_lock);
+ dev->cache.rb_root = RB_ROOT;
cache->wq = alloc_ordered_workqueue("mkey_cache", WQ_MEM_RECLAIM);
if (!cache->wq) {
mlx5_ib_warn(dev, "failed to create work queue\n");
@@ -749,13 +839,7 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
mlx5_cmd_init_async_ctx(dev->mdev, &dev->async_ctx);
timer_setup(&dev->delay_timer, delay_time_func, 0);
for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- ent = &cache->ent[i];
- xa_init_flags(&ent->mkeys, XA_FLAGS_LOCK_IRQ);
- ent->order = i + 2;
- ent->dev = dev;
- ent->limit = 0;
-
- INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
+ ent = mlx5r_cache_create_ent(dev, i);
if (i > MKEY_CACHE_LAST_STD_ENTRY) {
mlx5_odp_init_mkey_cache_entry(ent);
@@ -785,14 +869,16 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
{
- unsigned int i;
+ struct rb_root *root = &dev->cache.rb_root;
+ struct mlx5_cache_ent *ent;
+ struct rb_node *node;
if (!dev->cache.wq)
return 0;
- for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- struct mlx5_cache_ent *ent = &dev->cache.ent[i];
-
+ mutex_lock(&dev->cache.rb_lock);
+ for (node = rb_first(root); node; node = rb_next(node)) {
+ ent = rb_entry(node, struct mlx5_cache_ent, node);
xa_lock_irq(&ent->mkeys);
ent->disabled = true;
xa_unlock_irq(&ent->mkeys);
@@ -802,8 +888,15 @@ int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
mlx5_mkey_cache_debugfs_cleanup(dev);
mlx5_cmd_cleanup_async_ctx(&dev->async_ctx);
- for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++)
- clean_keys(dev, i);
+ node = rb_first(root);
+ while (node) {
+ ent = rb_entry(node, struct mlx5_cache_ent, node);
+ node = rb_next(node);
+ clean_keys(dev, ent);
+ rb_erase(&ent->node, root);
+ kfree(ent);
+ }
+ mutex_unlock(&dev->cache.rb_lock);
destroy_workqueue(dev->cache.wq);
del_timer_sync(&dev->delay_timer);
@@ -876,19 +969,6 @@ static int mkey_cache_max_order(struct mlx5_ib_dev *dev)
return MLX5_MAX_UMR_SHIFT;
}
-static struct mlx5_cache_ent *mkey_cache_ent_from_order(struct mlx5_ib_dev *dev,
- unsigned int order)
-{
- struct mlx5_mkey_cache *cache = &dev->cache;
-
- if (order < cache->ent[0].order)
- return &cache->ent[0];
- order = order - cache->ent[0].order;
- if (order > MKEY_CACHE_LAST_STD_ENTRY)
- return NULL;
- return &cache->ent[order];
-}
-
static void set_mr_fields(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr,
u64 length, int access_flags, u64 iova)
{
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 27bde04ebc1df..c9d93c318d37a 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -438,8 +438,7 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
return ERR_CAST(odp);
BUILD_BUG_ON(order > MKEY_CACHE_LAST_STD_ENTRY);
- mr = mlx5_mr_cache_alloc(dev, &dev->cache.ent[order],
- imr->access_flags);
+ mr = mlx5_mr_cache_alloc_order(dev, order, imr->access_flags);
if (IS_ERR(mr)) {
ib_umem_odp_release(odp);
return mr;
@@ -513,9 +512,8 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,
if (IS_ERR(umem_odp))
return ERR_CAST(umem_odp);
- imr = mlx5_mr_cache_alloc(dev,
- &dev->cache.ent[MLX5_IMR_KSM_CACHE_ENTRY],
- access_flags);
+ imr = mlx5_mr_cache_alloc_order(dev, MLX5_IMR_KSM_CACHE_ENTRY,
+ access_flags);
if (IS_ERR(imr)) {
ib_umem_odp_release(umem_odp);
return imr;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0748/1887] RDMA/mlx5: Introduce mlx5r_cache_rb_key
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (746 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0747/1887] RDMA/mlx5: Change the cache structure to an RB-tree Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0749/1887] RDMA/mlx5: Implement mkeys management via LIFO queue Greg Kroah-Hartman
` (250 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Guralnik, Jason Gunthorpe,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <michaelgur@nvidia.com>
[ Upstream commit 73d09b2fe8336f5f37935e46418666ddbcd3c343 ]
Switch from using the mkey order to using the new struct as the key to the
RB tree of cache entries.
The key is all the mkey properties that UMR operations can't modify.
Using this key to define the cache entries and to search and create cache
mkeys.
Link: https://lore.kernel.org/r/20230125222807.6921-5-michaelgur@nvidia.com
Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/mlx5_ib.h | 27 ++--
drivers/infiniband/hw/mlx5/mr.c | 228 +++++++++++++++++++--------
drivers/infiniband/hw/mlx5/odp.c | 30 ++--
3 files changed, 201 insertions(+), 84 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 8482ac9224b0a..9b6fa6b1c1cac 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -637,6 +637,13 @@ enum mlx5_mkey_type {
MLX5_MKEY_INDIRECT_DEVX,
};
+struct mlx5r_cache_rb_key {
+ u8 ats:1;
+ unsigned int access_mode;
+ unsigned int access_flags;
+ unsigned int ndescs;
+};
+
struct mlx5_ib_mkey {
u32 key;
enum mlx5_mkey_type type;
@@ -757,11 +764,9 @@ struct mlx5_cache_ent {
unsigned long reserved;
char name[4];
- u32 order;
- u32 access_mode;
- unsigned int ndescs;
struct rb_node node;
+ struct mlx5r_cache_rb_key rb_key;
u8 disabled:1;
u8 fill_to_high_water:1;
@@ -1340,14 +1345,13 @@ int mlx5_ib_get_cqe_size(struct ib_cq *ibcq);
int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev);
int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev);
struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
- int order);
+ struct mlx5r_cache_rb_key rb_key,
+ bool persistent_entry);
struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
- struct mlx5_cache_ent *ent,
- int access_flags);
+ int access_flags, int access_mode,
+ int ndescs);
-struct mlx5_ib_mr *mlx5_mr_cache_alloc_order(struct mlx5_ib_dev *dev, u32 order,
- int access_flags);
int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
struct ib_mr_status *mr_status);
struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
@@ -1370,7 +1374,7 @@ int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq);
void mlx5_ib_odp_cleanup_one(struct mlx5_ib_dev *ibdev);
int __init mlx5_ib_odp_init(void);
void mlx5_ib_odp_cleanup(void);
-void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent);
+int mlx5_odp_init_mkey_cache(struct mlx5_ib_dev *dev);
void mlx5_odp_populate_xlt(void *xlt, size_t idx, size_t nentries,
struct mlx5_ib_mr *mr, int flags);
@@ -1389,7 +1393,10 @@ static inline int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev,
static inline void mlx5_ib_odp_cleanup_one(struct mlx5_ib_dev *ibdev) {}
static inline int mlx5_ib_odp_init(void) { return 0; }
static inline void mlx5_ib_odp_cleanup(void) {}
-static inline void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent) {}
+static inline int mlx5_odp_init_mkey_cache(struct mlx5_ib_dev *dev)
+{
+ return 0;
+}
static inline void mlx5_odp_populate_xlt(void *xlt, size_t idx, size_t nentries,
struct mlx5_ib_mr *mr, int flags) {}
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index d97bf49688ca8..6d0ef4a5406ba 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -292,11 +292,13 @@ static void set_cache_mkc(struct mlx5_cache_ent *ent, void *mkc)
set_mkc_access_pd_addr_fields(mkc, 0, 0, ent->dev->umrc.pd);
MLX5_SET(mkc, mkc, free, 1);
MLX5_SET(mkc, mkc, umr_en, 1);
- MLX5_SET(mkc, mkc, access_mode_1_0, ent->access_mode & 0x3);
- MLX5_SET(mkc, mkc, access_mode_4_2, (ent->access_mode >> 2) & 0x7);
+ MLX5_SET(mkc, mkc, access_mode_1_0, ent->rb_key.access_mode & 0x3);
+ MLX5_SET(mkc, mkc, access_mode_4_2,
+ (ent->rb_key.access_mode >> 2) & 0x7);
MLX5_SET(mkc, mkc, translations_octword_size,
- get_mkc_octo_size(ent->access_mode, ent->ndescs));
+ get_mkc_octo_size(ent->rb_key.access_mode,
+ ent->rb_key.ndescs));
MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT);
}
@@ -594,8 +596,8 @@ static void __cache_work_func(struct mlx5_cache_ent *ent)
if (err != -EAGAIN) {
mlx5_ib_warn(
dev,
- "command failed order %d, err %d\n",
- ent->order, err);
+ "add keys command failed, err %d\n",
+ err);
queue_delayed_work(cache->wq, &ent->dwork,
msecs_to_jiffies(1000));
}
@@ -641,22 +643,49 @@ static void delayed_cache_work_func(struct work_struct *work)
__cache_work_func(ent);
}
+static int cache_ent_key_cmp(struct mlx5r_cache_rb_key key1,
+ struct mlx5r_cache_rb_key key2)
+{
+ int res;
+
+ res = key1.ats - key2.ats;
+ if (res)
+ return res;
+
+ res = key1.access_mode - key2.access_mode;
+ if (res)
+ return res;
+
+ res = key1.access_flags - key2.access_flags;
+ if (res)
+ return res;
+
+ /*
+ * keep ndescs the last in the compare table since the find function
+ * searches for an exact match on all properties and only closest
+ * match in size.
+ */
+ return key1.ndescs - key2.ndescs;
+}
+
static int mlx5_cache_ent_insert(struct mlx5_mkey_cache *cache,
struct mlx5_cache_ent *ent)
{
struct rb_node **new = &cache->rb_root.rb_node, *parent = NULL;
struct mlx5_cache_ent *cur;
+ int cmp;
mutex_lock(&cache->rb_lock);
/* Figure out where to put new node */
while (*new) {
cur = rb_entry(*new, struct mlx5_cache_ent, node);
parent = *new;
- if (ent->order < cur->order)
+ cmp = cache_ent_key_cmp(cur->rb_key, ent->rb_key);
+ if (cmp > 0)
new = &((*new)->rb_left);
- if (ent->order > cur->order)
+ if (cmp < 0)
new = &((*new)->rb_right);
- if (ent->order == cur->order) {
+ if (cmp == 0) {
mutex_unlock(&cache->rb_lock);
return -EEXIST;
}
@@ -670,40 +699,45 @@ static int mlx5_cache_ent_insert(struct mlx5_mkey_cache *cache,
return 0;
}
-static struct mlx5_cache_ent *mkey_cache_ent_from_order(struct mlx5_ib_dev *dev,
- unsigned int order)
+static struct mlx5_cache_ent *
+mkey_cache_ent_from_rb_key(struct mlx5_ib_dev *dev,
+ struct mlx5r_cache_rb_key rb_key)
{
struct rb_node *node = dev->cache.rb_root.rb_node;
struct mlx5_cache_ent *cur, *smallest = NULL;
+ int cmp;
/*
* Find the smallest ent with order >= requested_order.
*/
while (node) {
cur = rb_entry(node, struct mlx5_cache_ent, node);
- if (cur->order > order) {
+ cmp = cache_ent_key_cmp(cur->rb_key, rb_key);
+ if (cmp > 0) {
smallest = cur;
node = node->rb_left;
}
- if (cur->order < order)
+ if (cmp < 0)
node = node->rb_right;
- if (cur->order == order)
+ if (cmp == 0)
return cur;
}
- return smallest;
+ return (smallest &&
+ smallest->rb_key.access_mode == rb_key.access_mode &&
+ smallest->rb_key.access_flags == rb_key.access_flags &&
+ smallest->rb_key.ats == rb_key.ats) ?
+ smallest :
+ NULL;
}
-struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
- struct mlx5_cache_ent *ent,
- int access_flags)
+static struct mlx5_ib_mr *_mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
+ struct mlx5_cache_ent *ent,
+ int access_flags)
{
struct mlx5_ib_mr *mr;
int err;
- if (!mlx5r_umr_can_reconfig(dev, 0, access_flags))
- return ERR_PTR(-EOPNOTSUPP);
-
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
if (!mr)
return ERR_PTR(-ENOMEM);
@@ -734,12 +768,44 @@ struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
return mr;
}
-struct mlx5_ib_mr *mlx5_mr_cache_alloc_order(struct mlx5_ib_dev *dev,
- u32 order, int access_flags)
+static int get_unchangeable_access_flags(struct mlx5_ib_dev *dev,
+ int access_flags)
+{
+ int ret = 0;
+
+ if ((access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
+ MLX5_CAP_GEN(dev->mdev, atomic) &&
+ MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled))
+ ret |= IB_ACCESS_REMOTE_ATOMIC;
+
+ if ((access_flags & IB_ACCESS_RELAXED_ORDERING) &&
+ MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write) &&
+ !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write_umr))
+ ret |= IB_ACCESS_RELAXED_ORDERING;
+
+ if ((access_flags & IB_ACCESS_RELAXED_ORDERING) &&
+ MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read) &&
+ !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read_umr))
+ ret |= IB_ACCESS_RELAXED_ORDERING;
+
+ return ret;
+}
+
+struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
+ int access_flags, int access_mode,
+ int ndescs)
{
- struct mlx5_cache_ent *ent = mkey_cache_ent_from_order(dev, order);
+ struct mlx5r_cache_rb_key rb_key = {
+ .ndescs = ndescs,
+ .access_mode = access_mode,
+ .access_flags = get_unchangeable_access_flags(dev, access_flags)
+ };
+ struct mlx5_cache_ent *ent = mkey_cache_ent_from_rb_key(dev, rb_key);
- return mlx5_mr_cache_alloc(dev, ent, access_flags);
+ if (!ent)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ return _mlx5_mr_cache_alloc(dev, ent, access_flags);
}
static void clean_keys(struct mlx5_ib_dev *dev, struct mlx5_cache_ent *ent)
@@ -766,28 +832,32 @@ static void mlx5_mkey_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
dev->cache.fs_root = NULL;
}
+static void mlx5_mkey_cache_debugfs_add_ent(struct mlx5_ib_dev *dev,
+ struct mlx5_cache_ent *ent)
+{
+ int order = order_base_2(ent->rb_key.ndescs);
+ struct dentry *dir;
+
+ if (ent->rb_key.access_mode == MLX5_MKC_ACCESS_MODE_KSM)
+ order = MLX5_IMR_KSM_CACHE_ENTRY + 2;
+
+ sprintf(ent->name, "%d", order);
+ dir = debugfs_create_dir(ent->name, dev->cache.fs_root);
+ debugfs_create_file("size", 0600, dir, ent, &size_fops);
+ debugfs_create_file("limit", 0600, dir, ent, &limit_fops);
+ debugfs_create_ulong("cur", 0400, dir, &ent->stored);
+ debugfs_create_u32("miss", 0600, dir, &ent->miss);
+}
+
static void mlx5_mkey_cache_debugfs_init(struct mlx5_ib_dev *dev)
{
+ struct dentry *dbg_root = mlx5_debugfs_get_dev_root(dev->mdev);
struct mlx5_mkey_cache *cache = &dev->cache;
- struct mlx5_cache_ent *ent;
- struct dentry *dir;
- int i;
if (!mlx5_debugfs_root || dev->is_rep)
return;
- dir = mlx5_debugfs_get_dev_root(dev->mdev);
- cache->fs_root = debugfs_create_dir("mr_cache", dir);
-
- for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- ent = mkey_cache_ent_from_order(dev, i);
- sprintf(ent->name, "%d", ent->order);
- dir = debugfs_create_dir(ent->name, cache->fs_root);
- debugfs_create_file("size", 0600, dir, ent, &size_fops);
- debugfs_create_file("limit", 0600, dir, ent, &limit_fops);
- debugfs_create_ulong("cur", 0400, dir, &ent->stored);
- debugfs_create_u32("miss", 0600, dir, &ent->miss);
- }
+ cache->fs_root = debugfs_create_dir("mr_cache", dbg_root);
}
static void delay_time_func(struct timer_list *t)
@@ -798,9 +868,11 @@ static void delay_time_func(struct timer_list *t)
}
struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
- int order)
+ struct mlx5r_cache_rb_key rb_key,
+ bool persistent_entry)
{
struct mlx5_cache_ent *ent;
+ int order;
int ret;
ent = kzalloc(sizeof(*ent), GFP_KERNEL);
@@ -808,7 +880,7 @@ struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
return ERR_PTR(-ENOMEM);
xa_init_flags(&ent->mkeys, XA_FLAGS_LOCK_IRQ);
- ent->order = order;
+ ent->rb_key = rb_key;
ent->dev = dev;
INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
@@ -818,13 +890,36 @@ struct mlx5_cache_ent *mlx5r_cache_create_ent(struct mlx5_ib_dev *dev,
kfree(ent);
return ERR_PTR(ret);
}
+
+ if (persistent_entry) {
+ if (rb_key.access_mode == MLX5_MKC_ACCESS_MODE_KSM)
+ order = MLX5_IMR_KSM_CACHE_ENTRY;
+ else
+ order = order_base_2(rb_key.ndescs) - 2;
+
+ if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) &&
+ !dev->is_rep && mlx5_core_is_pf(dev->mdev) &&
+ mlx5r_umr_can_load_pas(dev, 0))
+ ent->limit = dev->mdev->profile.mr_cache[order].limit;
+ else
+ ent->limit = 0;
+
+ mlx5_mkey_cache_debugfs_add_ent(dev, ent);
+ }
+
return ent;
}
int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
{
struct mlx5_mkey_cache *cache = &dev->cache;
+ struct rb_root *root = &dev->cache.rb_root;
+ struct mlx5r_cache_rb_key rb_key = {
+ .access_mode = MLX5_MKC_ACCESS_MODE_MTT,
+ };
struct mlx5_cache_ent *ent;
+ struct rb_node *node;
+ int ret;
int i;
mutex_init(&dev->slow_path_mutex);
@@ -838,33 +933,32 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
mlx5_cmd_init_async_ctx(dev->mdev, &dev->async_ctx);
timer_setup(&dev->delay_timer, delay_time_func, 0);
- for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) {
- ent = mlx5r_cache_create_ent(dev, i);
-
- if (i > MKEY_CACHE_LAST_STD_ENTRY) {
- mlx5_odp_init_mkey_cache_entry(ent);
- continue;
+ mlx5_mkey_cache_debugfs_init(dev);
+ for (i = 0; i <= mkey_cache_max_order(dev); i++) {
+ rb_key.ndescs = 1 << (i + 2);
+ ent = mlx5r_cache_create_ent(dev, rb_key, true);
+ if (IS_ERR(ent)) {
+ ret = PTR_ERR(ent);
+ goto err;
}
+ }
- if (ent->order > mkey_cache_max_order(dev))
- continue;
+ ret = mlx5_odp_init_mkey_cache(dev);
+ if (ret)
+ goto err;
- ent->ndescs = 1 << ent->order;
- ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT;
- if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) &&
- !dev->is_rep && mlx5_core_is_pf(dev->mdev) &&
- mlx5r_umr_can_load_pas(dev, 0))
- ent->limit = dev->mdev->profile.mr_cache[i].limit;
- else
- ent->limit = 0;
+ for (node = rb_first(root); node; node = rb_next(node)) {
+ ent = rb_entry(node, struct mlx5_cache_ent, node);
xa_lock_irq(&ent->mkeys);
queue_adjust_cache_locked(ent);
xa_unlock_irq(&ent->mkeys);
}
- mlx5_mkey_cache_debugfs_init(dev);
-
return 0;
+
+err:
+ mlx5_ib_warn(dev, "failed to create mkey cache entry\n");
+ return ret;
}
int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
@@ -965,7 +1059,7 @@ static int get_octo_len(u64 addr, u64 len, int page_shift)
static int mkey_cache_max_order(struct mlx5_ib_dev *dev)
{
if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset))
- return MKEY_CACHE_LAST_STD_ENTRY + 2;
+ return MKEY_CACHE_LAST_STD_ENTRY;
return MLX5_MAX_UMR_SHIFT;
}
@@ -995,6 +1089,9 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd,
struct ib_umem *umem, u64 iova,
int access_flags)
{
+ struct mlx5r_cache_rb_key rb_key = {
+ .access_mode = MLX5_MKC_ACCESS_MODE_MTT,
+ };
struct mlx5_ib_dev *dev = to_mdev(pd->device);
struct mlx5_cache_ent *ent;
struct mlx5_ib_mr *mr;
@@ -1007,8 +1104,11 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd,
0, iova);
if (WARN_ON(!page_size))
return ERR_PTR(-EINVAL);
- ent = mkey_cache_ent_from_order(
- dev, order_base_2(ib_umem_num_dma_blocks(umem, page_size)));
+
+ rb_key.ndescs = ib_umem_num_dma_blocks(umem, page_size);
+ rb_key.ats = mlx5_umem_needs_ats(dev, umem, access_flags);
+ rb_key.access_flags = get_unchangeable_access_flags(dev, access_flags);
+ ent = mkey_cache_ent_from_rb_key(dev, rb_key);
/*
* Matches access in alloc_cache_mr(). If the MR can't come from the
* cache then synchronously create an uncached one.
@@ -1022,7 +1122,7 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd,
return mr;
}
- mr = mlx5_mr_cache_alloc(dev, ent, access_flags);
+ mr = _mlx5_mr_cache_alloc(dev, ent, access_flags);
if (IS_ERR(mr))
return mr;
@@ -1452,7 +1552,7 @@ static bool can_use_umr_rereg_pas(struct mlx5_ib_mr *mr,
mlx5_umem_find_best_pgsz(new_umem, mkc, log_page_size, 0, iova);
if (WARN_ON(!*page_size))
return false;
- return (1ULL << mr->mmkey.cache_ent->order) >=
+ return (mr->mmkey.cache_ent->rb_key.ndescs) >=
ib_umem_num_dma_blocks(new_umem, *page_size);
}
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index c9d93c318d37a..f0e8d5e11d121 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -424,7 +424,6 @@ static void mlx5_ib_page_fault_resume(struct mlx5_ib_dev *dev,
static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
unsigned long idx)
{
- int order = order_base_2(MLX5_IMR_MTT_ENTRIES);
struct mlx5_ib_dev *dev = mr_to_mdev(imr);
struct ib_umem_odp *odp;
struct mlx5_ib_mr *mr;
@@ -437,8 +436,9 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
if (IS_ERR(odp))
return ERR_CAST(odp);
- BUILD_BUG_ON(order > MKEY_CACHE_LAST_STD_ENTRY);
- mr = mlx5_mr_cache_alloc_order(dev, order, imr->access_flags);
+ mr = mlx5_mr_cache_alloc(dev, imr->access_flags,
+ MLX5_MKC_ACCESS_MODE_MTT,
+ MLX5_IMR_MTT_ENTRIES);
if (IS_ERR(mr)) {
ib_umem_odp_release(odp);
return mr;
@@ -512,8 +512,8 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,
if (IS_ERR(umem_odp))
return ERR_CAST(umem_odp);
- imr = mlx5_mr_cache_alloc_order(dev, MLX5_IMR_KSM_CACHE_ENTRY,
- access_flags);
+ imr = mlx5_mr_cache_alloc(dev, access_flags, MLX5_MKC_ACCESS_MODE_KSM,
+ mlx5_imr_ksm_entries);
if (IS_ERR(imr)) {
ib_umem_odp_release(umem_odp);
return imr;
@@ -1609,12 +1609,22 @@ mlx5_ib_odp_destroy_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq)
return err;
}
-void mlx5_odp_init_mkey_cache_entry(struct mlx5_cache_ent *ent)
+int mlx5_odp_init_mkey_cache(struct mlx5_ib_dev *dev)
{
- if (!(ent->dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT))
- return;
- ent->ndescs = mlx5_imr_ksm_entries;
- ent->access_mode = MLX5_MKC_ACCESS_MODE_KSM;
+ struct mlx5r_cache_rb_key rb_key = {
+ .access_mode = MLX5_MKC_ACCESS_MODE_KSM,
+ .ndescs = mlx5_imr_ksm_entries,
+ };
+ struct mlx5_cache_ent *ent;
+
+ if (!(dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT))
+ return 0;
+
+ ent = mlx5r_cache_create_ent(dev, rb_key, true);
+ if (IS_ERR(ent))
+ return PTR_ERR(ent);
+
+ return 0;
}
static const struct ib_device_ops mlx5_ib_dev_odp_ops = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0749/1887] RDMA/mlx5: Implement mkeys management via LIFO queue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (747 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0748/1887] RDMA/mlx5: Introduce mlx5r_cache_rb_key Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0750/1887] RDMA/mlx5: Fix the recovery flow of the UMR QP Greg Kroah-Hartman
` (249 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shay Drory, Leon Romanovsky,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <shayd@nvidia.com>
[ Upstream commit 57e7071683ef6148c9f5ea0ba84598d2ba681375 ]
Currently, mkeys are managed via xarray. This implementation leads to
a degradation in cases many MRs are unregistered in parallel, due to xarray
internal implementation, for example: deregistration 1M MRs via 64 threads
is taking ~15% more time[1].
Hence, implement mkeys management via LIFO queue, which solved the
degradation.
[1]
2.8us in kernel v5.19 compare to 3.2us in kernel v6.4
Signed-off-by: Shay Drory <shayd@nvidia.com>
Link: https://lore.kernel.org/r/fde3d4cfab0f32f0ccb231cd113298256e1502c5.1695283384.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Only the umr.c hunk is kept: the UMR failure warning now also prints
the mkey, which is the context the following UMR QP recovery fix
builds on. The mkey cache rework in mr.c and mlx5_ib.h is dropped as
the target fix does not depend on it.
Stable-dep-of: d97505baea64 ("RDMA/mlx5: Fix the recovery flow of the UMR QP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/umr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/umr.c b/drivers/infiniband/hw/mlx5/umr.c
index 219e89242d888..79557a25b55d7 100644
--- a/drivers/infiniband/hw/mlx5/umr.c
+++ b/drivers/infiniband/hw/mlx5/umr.c
@@ -333,8 +333,8 @@ static int mlx5r_umr_post_send_wait(struct mlx5_ib_dev *dev, u32 mkey,
WARN_ON_ONCE(1);
mlx5_ib_warn(dev,
- "reg umr failed (%u). Trying to recover and resubmit the flushed WQEs\n",
- umr_context.status);
+ "reg umr failed (%u). Trying to recover and resubmit the flushed WQEs, mkey = %u\n",
+ umr_context.status, mkey);
mutex_lock(&umrc->lock);
err = mlx5r_umr_recover(dev);
mutex_unlock(&umrc->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0750/1887] RDMA/mlx5: Fix the recovery flow of the UMR QP
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (748 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0749/1887] RDMA/mlx5: Implement mkeys management via LIFO queue Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0751/1887] net: enetc: VFs do not support HWTSTAMP_TX_ONESTEP_SYNC Greg Kroah-Hartman
` (248 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yishai Hadas, Michael Guralnik,
Leon Romanovsky, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <yishaih@nvidia.com>
[ Upstream commit d97505baea64d93538b16baf14ce7b8c1fbad746 ]
This patch addresses an issue in the recovery flow of the UMR QP,
ensuring tasks do not get stuck, as highlighted by the call trace [1].
During recovery, before transitioning the QP to the RESET state, the
software must wait for all outstanding WRs to complete.
Failing to do so can cause the firmware to skip sending some flushed
CQEs with errors and simply discard them upon the RESET, as per the IB
specification.
This race condition can result in lost CQEs and tasks becoming stuck.
To resolve this, the patch sends a final WR which serves only as a
barrier before moving the QP state to RESET.
Once a CQE is received for that final WR, it guarantees that no
outstanding WRs remain, making it safe to transition the QP to RESET and
subsequently back to RTS, restoring proper functionality.
Note:
For the barrier WR, we simply reuse the failed and ready WR.
Since the QP is in an error state, it will only receive
IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier we don't
care about its status.
[1]
INFO: task rdma_resource_l:1922 blocked for more than 120 seconds.
Tainted: G W 6.12.0-rc7+ #1626
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:rdma_resource_l state:D stack:0 pid:1922 tgid:1922 ppid:1369
flags:0x00004004
Call Trace:
<TASK>
__schedule+0x420/0xd30
schedule+0x47/0x130
schedule_timeout+0x280/0x300
? mark_held_locks+0x48/0x80
? lockdep_hardirqs_on_prepare+0xe5/0x1a0
wait_for_completion+0x75/0x130
mlx5r_umr_post_send_wait+0x3c2/0x5b0 [mlx5_ib]
? __pfx_mlx5r_umr_done+0x10/0x10 [mlx5_ib]
mlx5r_umr_revoke_mr+0x93/0xc0 [mlx5_ib]
__mlx5_ib_dereg_mr+0x299/0x520 [mlx5_ib]
? _raw_spin_unlock_irq+0x24/0x40
? wait_for_completion+0xfe/0x130
? rdma_restrack_put+0x63/0xe0 [ib_core]
ib_dereg_mr_user+0x5f/0x120 [ib_core]
? lock_release+0xc6/0x280
destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
uobj_destroy+0x3f/0x70 [ib_uverbs]
ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
? __lock_acquire+0x64e/0x2080
? mark_held_locks+0x48/0x80
? find_held_lock+0x2d/0xa0
? lock_acquire+0xc1/0x2f0
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
? __fget_files+0xc3/0x1b0
ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
__x64_sys_ioctl+0x1b0/0xa70
do_syscall_64+0x6b/0x140
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f99c918b17b
RSP: 002b:00007ffc766d0468 EFLAGS: 00000246 ORIG_RAX:
0000000000000010
RAX: ffffffffffffffda RBX: 00007ffc766d0578 RCX:
00007f99c918b17b
RDX: 00007ffc766d0560 RSI: 00000000c0181b01 RDI:
0000000000000003
RBP: 00007ffc766d0540 R08: 00007f99c8f99010 R09:
000000000000bd7e
R10: 00007f99c94c1c70 R11: 0000000000000246 R12:
00007ffc766d0530
R13: 000000000000001c R14: 0000000040246a80 R15:
0000000000000000
</TASK>
Fixes: 158e71bb69e3 ("RDMA/mlx5: Add a umr recovery flow")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
Link: https://patch.msgid.link/27b51b92ec42dfb09d8096fcbd51878f397ce6ec.1737290141.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/umr.c | 83 +++++++++++++++++++++-----------
1 file changed, 56 insertions(+), 27 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/umr.c b/drivers/infiniband/hw/mlx5/umr.c
index 79557a25b55d7..2e70291813822 100644
--- a/drivers/infiniband/hw/mlx5/umr.c
+++ b/drivers/infiniband/hw/mlx5/umr.c
@@ -200,30 +200,6 @@ void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev)
ib_dealloc_pd(dev->umrc.pd);
}
-static int mlx5r_umr_recover(struct mlx5_ib_dev *dev)
-{
- struct umr_common *umrc = &dev->umrc;
- struct ib_qp_attr attr;
- int err;
-
- attr.qp_state = IB_QPS_RESET;
- err = ib_modify_qp(umrc->qp, &attr, IB_QP_STATE);
- if (err) {
- mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
- goto err;
- }
-
- err = mlx5r_umr_qp_rst2rts(dev, umrc->qp);
- if (err)
- goto err;
-
- umrc->state = MLX5_UMR_STATE_ACTIVE;
- return 0;
-
-err:
- umrc->state = MLX5_UMR_STATE_ERR;
- return err;
-}
static int mlx5r_umr_post_send(struct ib_qp *ibqp, u32 mkey, struct ib_cqe *cqe,
struct mlx5r_umr_wqe *wqe, bool with_data)
@@ -271,6 +247,61 @@ static int mlx5r_umr_post_send(struct ib_qp *ibqp, u32 mkey, struct ib_cqe *cqe,
return err;
}
+static int mlx5r_umr_recover(struct mlx5_ib_dev *dev, u32 mkey,
+ struct mlx5r_umr_context *umr_context,
+ struct mlx5r_umr_wqe *wqe, bool with_data)
+{
+ struct umr_common *umrc = &dev->umrc;
+ struct ib_qp_attr attr;
+ int err;
+
+ mutex_lock(&umrc->lock);
+ /* Preventing any further WRs to be sent now */
+ if (umrc->state != MLX5_UMR_STATE_RECOVER) {
+ mlx5_ib_warn(dev, "UMR recovery encountered an unexpected state=%d\n",
+ umrc->state);
+ umrc->state = MLX5_UMR_STATE_RECOVER;
+ }
+ mutex_unlock(&umrc->lock);
+
+ /* Sending a final/barrier WR (the failed one) and wait for its completion.
+ * This will ensure that all the previous WRs got a completion before
+ * we set the QP state to RESET.
+ */
+ err = mlx5r_umr_post_send(umrc->qp, mkey, &umr_context->cqe, wqe,
+ with_data);
+ if (err) {
+ mlx5_ib_warn(dev, "UMR recovery post send failed, err %d\n", err);
+ goto err;
+ }
+
+ /* Since the QP is in an error state, it will only receive
+ * IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier
+ * we don't care about its status.
+ */
+ wait_for_completion(&umr_context->done);
+
+ attr.qp_state = IB_QPS_RESET;
+ err = ib_modify_qp(umrc->qp, &attr, IB_QP_STATE);
+ if (err) {
+ mlx5_ib_warn(dev, "Couldn't modify UMR QP to RESET, err=%d\n", err);
+ goto err;
+ }
+
+ err = mlx5r_umr_qp_rst2rts(dev, umrc->qp);
+ if (err) {
+ mlx5_ib_warn(dev, "Couldn't modify UMR QP to RTS, err=%d\n", err);
+ goto err;
+ }
+
+ umrc->state = MLX5_UMR_STATE_ACTIVE;
+ return 0;
+
+err:
+ umrc->state = MLX5_UMR_STATE_ERR;
+ return err;
+}
+
static void mlx5r_umr_done(struct ib_cq *cq, struct ib_wc *wc)
{
struct mlx5_ib_umr_context *context =
@@ -335,9 +366,7 @@ static int mlx5r_umr_post_send_wait(struct mlx5_ib_dev *dev, u32 mkey,
mlx5_ib_warn(dev,
"reg umr failed (%u). Trying to recover and resubmit the flushed WQEs, mkey = %u\n",
umr_context.status, mkey);
- mutex_lock(&umrc->lock);
- err = mlx5r_umr_recover(dev);
- mutex_unlock(&umrc->lock);
+ err = mlx5r_umr_recover(dev, mkey, &umr_context, wqe, with_data);
if (err)
mlx5_ib_warn(dev, "couldn't recover UMR, err %d\n",
err);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0751/1887] net: enetc: VFs do not support HWTSTAMP_TX_ONESTEP_SYNC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (749 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0750/1887] RDMA/mlx5: Fix the recovery flow of the UMR QP Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0752/1887] nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu() Greg Kroah-Hartman
` (247 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wei Fang, Vladimir Oltean,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <wei.fang@nxp.com>
[ Upstream commit a562d0c4a893eae3ea51d512c4d90ab858a6b7ec ]
Actually ENETC VFs do not support HWTSTAMP_TX_ONESTEP_SYNC because only
ENETC PF can access PMa_SINGLE_STEP registers. And there will be a crash
if VFs are used to test one-step timestamp, the crash log as follows.
[ 129.110909] Unable to handle kernel paging request at virtual address 00000000000080c0
[ 129.287769] Call trace:
[ 129.290219] enetc_port_mac_wr+0x30/0xec (P)
[ 129.294504] enetc_start_xmit+0xda4/0xe74
[ 129.298525] enetc_xmit+0x70/0xec
[ 129.301848] dev_hard_start_xmit+0x98/0x118
Fixes: 41514737ecaa ("enetc: add get_ts_info interface for ethtool")
Cc: stable@vger.kernel.org
Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20250224111251.1061098-5-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/freescale/enetc/enetc.c | 3 +++
drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 10 ++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 80eec93f99870..ce15034234392 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -2713,6 +2713,9 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
priv->active_offloads |= ENETC_F_TX_TSTAMP;
break;
case HWTSTAMP_TX_ONESTEP_SYNC:
+ if (!enetc_si_is_pf(priv->si))
+ return -EOPNOTSUPP;
+
priv->active_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
priv->active_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP;
break;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index d4623a41f0137..71c64317c5b85 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -772,6 +772,9 @@ static int enetc_set_coalesce(struct net_device *ndev,
static int enetc_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+#endif
int *phc_idx;
phc_idx = symbol_get(enetc_phc_index);
@@ -791,8 +794,11 @@ static int enetc_get_ts_info(struct net_device *ndev,
SOF_TIMESTAMPING_SOFTWARE;
info->tx_types = (1 << HWTSTAMP_TX_OFF) |
- (1 << HWTSTAMP_TX_ON) |
- (1 << HWTSTAMP_TX_ONESTEP_SYNC);
+ (1 << HWTSTAMP_TX_ON);
+
+ if (enetc_si_is_pf(priv->si))
+ info->tx_types |= (1 << HWTSTAMP_TX_ONESTEP_SYNC);
+
info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_ALL);
#else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0752/1887] nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (750 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0751/1887] net: enetc: VFs do not support HWTSTAMP_TX_ONESTEP_SYNC Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0753/1887] ksmbd: prevent connection release during oplock break notification Greg Kroah-Hartman
` (246 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maurizio Lombardi, Sagi Grimberg,
Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi <mlombard@redhat.com>
[ Upstream commit ad95bab0cd28ed77c2c0d0b6e76e03e031391064 ]
nvme_tcp_recv_pdu() doesn't check the validity of the header length.
When header digests are enabled, a target might send a packet with an
invalid header length (e.g. 255), causing nvme_tcp_verify_hdgst()
to access memory outside the allocated area and cause memory corruptions
by overwriting it with the calculated digest.
Fix this by rejecting packets with an unexpected header length.
Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/tcp.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index e139f567a8535..19aed2125a18b 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -189,6 +189,19 @@ static inline int nvme_tcp_queue_id(struct nvme_tcp_queue *queue)
return queue - queue->ctrl->queues;
}
+static inline bool nvme_tcp_recv_pdu_supported(enum nvme_tcp_pdu_type type)
+{
+ switch (type) {
+ case nvme_tcp_c2h_term:
+ case nvme_tcp_c2h_data:
+ case nvme_tcp_r2t:
+ case nvme_tcp_rsp:
+ return true;
+ default:
+ return false;
+ }
+}
+
static inline struct blk_mq_tags *nvme_tcp_tagset(struct nvme_tcp_queue *queue)
{
u32 queue_idx = nvme_tcp_queue_id(queue);
@@ -792,6 +805,16 @@ static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb,
return 0;
hdr = queue->pdu;
+ if (unlikely(hdr->hlen != sizeof(struct nvme_tcp_rsp_pdu))) {
+ if (!nvme_tcp_recv_pdu_supported(hdr->type))
+ goto unsupported_pdu;
+
+ dev_err(queue->ctrl->ctrl.device,
+ "pdu type %d has unexpected header length (%d)\n",
+ hdr->type, hdr->hlen);
+ return -EPROTO;
+ }
+
if (unlikely(hdr->type == nvme_tcp_c2h_term)) {
/*
* C2HTermReq never includes Header or Data digests.
@@ -824,10 +847,13 @@ static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb,
nvme_tcp_init_recv_ctx(queue);
return nvme_tcp_handle_r2t(queue, (void *)queue->pdu);
default:
- dev_err(queue->ctrl->ctrl.device,
- "unsupported pdu type (%d)\n", hdr->type);
- return -EINVAL;
+ goto unsupported_pdu;
}
+
+unsupported_pdu:
+ dev_err(queue->ctrl->ctrl.device,
+ "unsupported pdu type (%d)\n", hdr->type);
+ return -EINVAL;
}
static inline void nvme_tcp_end_request(struct request *rq, u16 status)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0753/1887] ksmbd: prevent connection release during oplock break notification
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (751 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0752/1887] nvme-tcp: fix potential memory corruption in nvme_tcp_recv_pdu() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0754/1887] eth: bnxt: fix truesize for mb-xdp-pass case Greg Kroah-Hartman
` (245 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 3aa660c059240e0c795217182cf7df32909dd917 ]
ksmbd_work could be freed when after connection release.
Increment r_count of ksmbd_conn to indicate that requests
are not finished yet and to not release the connection.
Cc: stable@vger.kernel.org
Reported-by: Norbert Szetei <norbert@doyensec.com>
Tested-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 19 +++++++++++++++++++
fs/smb/server/connection.h | 2 ++
fs/smb/server/oplock.c | 6 ++++++
fs/smb/server/server.c | 10 ++--------
4 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index d99e1343955a3..a0c548447c2af 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -442,6 +442,25 @@ void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops)
default_conn_ops.terminate_fn = ops->terminate_fn;
}
+void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn)
+{
+ atomic_inc(&conn->r_count);
+}
+
+void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn)
+{
+ /*
+ * Checking waitqueue to dropping pending requests on
+ * disconnection. waitqueue_active is safe because it
+ * uses atomic operation for condition.
+ */
+ atomic_inc(&conn->refcnt);
+ if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
+ wake_up(&conn->r_count_q);
+
+ ksmbd_conn_put(conn);
+}
+
int ksmbd_conn_transport_init(void)
{
int ret;
diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h
index a38e264889eea..2a6628bb312d9 100644
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -176,6 +176,8 @@ int ksmbd_conn_transport_init(void);
void ksmbd_conn_transport_destroy(void);
void ksmbd_conn_lock(struct ksmbd_conn *conn);
void ksmbd_conn_unlock(struct ksmbd_conn *conn);
+void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn);
+void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn);
/*
* WARNING
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 0b71399af50cc..31f84f59e40a7 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -657,6 +657,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
{
struct smb2_oplock_break *rsp = NULL;
struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
+ struct ksmbd_conn *conn = work->conn;
struct oplock_break_info *br_info = work->request_buf;
struct smb2_hdr *rsp_hdr;
struct ksmbd_file *fp;
@@ -712,6 +713,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
out:
ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
}
/**
@@ -746,6 +748,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
work->sess = opinfo->sess;
if (opinfo->op_state == OPLOCK_ACK_WAIT) {
+ ksmbd_conn_r_count_inc(conn);
INIT_WORK(&work->work, __smb2_oplock_break_noti);
ksmbd_queue_work(work);
@@ -767,6 +770,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
{
struct smb2_lease_break *rsp = NULL;
struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
+ struct ksmbd_conn *conn = work->conn;
struct lease_break_info *br_info = work->request_buf;
struct smb2_hdr *rsp_hdr;
@@ -813,6 +817,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
out:
ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
}
/**
@@ -863,6 +868,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
list_del_init(&in_work->interim_entry);
release_async_work(in_work);
}
+ ksmbd_conn_r_count_inc(conn);
INIT_WORK(&work->work, __smb2_lease_break_noti);
ksmbd_queue_work(work);
wait_for_break_ack(opinfo);
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index a61488b6b5904..08fe608ac75a2 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -291,13 +291,7 @@ static void handle_ksmbd_work(struct work_struct *wk)
ksmbd_conn_try_dequeue_request(work);
ksmbd_free_work_struct(work);
atomic_dec(&conn->mux_smb_requests);
- /*
- * Checking waitqueue to dropping pending requests on
- * disconnection. waitqueue_active is safe because it
- * uses atomic operation for condition.
- */
- if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
- wake_up(&conn->r_count_q);
+ ksmbd_conn_r_count_dec(conn);
}
/**
@@ -332,7 +326,7 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
conn->request_buf = NULL;
ksmbd_conn_enqueue_request(work);
- atomic_inc(&conn->r_count);
+ ksmbd_conn_r_count_inc(conn);
/* update activity on connection */
conn->last_active = jiffies;
INIT_WORK(&work->work, handle_ksmbd_work);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0754/1887] eth: bnxt: fix truesize for mb-xdp-pass case
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (752 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0753/1887] ksmbd: prevent connection release during oplock break notification Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0755/1887] ksmbd: fix use-after-free in ksmbd_free_work_struct Greg Kroah-Hartman
` (244 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Taehee Yoo, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <ap420073@gmail.com>
[ Upstream commit 9f7b2aa5034e24d3c49db73d5f760c0435fe31c2 ]
When mb-xdp is set and return is XDP_PASS, packet is converted from
xdp_buff to sk_buff with xdp_update_skb_shared_info() in
bnxt_xdp_build_skb().
bnxt_xdp_build_skb() passes incorrect truesize argument to
xdp_update_skb_shared_info().
The truesize is calculated as BNXT_RX_PAGE_SIZE * sinfo->nr_frags but
the skb_shared_info was wiped by napi_build_skb() before.
So it stores sinfo->nr_frags before bnxt_xdp_build_skb() and use it
instead of getting skb_shared_info from xdp_get_shared_info_from_buff().
Splat looks like:
------------[ cut here ]------------
WARNING: CPU: 2 PID: 0 at net/core/skbuff.c:6072 skb_try_coalesce+0x504/0x590
Modules linked in: xt_nat xt_tcpudp veth af_packet xt_conntrack nft_chain_nat xt_MASQUERADE nf_conntrack_netlink xfrm_user xt_addrtype nft_coms
CPU: 2 UID: 0 PID: 0 Comm: swapper/2 Not tainted 6.14.0-rc2+ #3
RIP: 0010:skb_try_coalesce+0x504/0x590
Code: 4b fd ff ff 49 8b 34 24 40 80 e6 40 0f 84 3d fd ff ff 49 8b 74 24 48 40 f6 c6 01 0f 84 2e fd ff ff 48 8d 4e ff e9 25 fd ff ff <0f> 0b e99
RSP: 0018:ffffb62c4120caa8 EFLAGS: 00010287
RAX: 0000000000000003 RBX: ffffb62c4120cb14 RCX: 0000000000000ec0
RDX: 0000000000001000 RSI: ffffa06e5d7dc000 RDI: 0000000000000003
RBP: ffffa06e5d7ddec0 R08: ffffa06e6120a800 R09: ffffa06e7a119900
R10: 0000000000002310 R11: ffffa06e5d7dcec0 R12: ffffe4360575f740
R13: ffffe43600000000 R14: 0000000000000002 R15: 0000000000000002
FS: 0000000000000000(0000) GS:ffffa0755f700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f147b76b0f8 CR3: 00000001615d4000 CR4: 00000000007506f0
PKRU: 55555554
Call Trace:
<IRQ>
? __warn+0x84/0x130
? skb_try_coalesce+0x504/0x590
? report_bug+0x18a/0x1a0
? handle_bug+0x53/0x90
? exc_invalid_op+0x14/0x70
? asm_exc_invalid_op+0x16/0x20
? skb_try_coalesce+0x504/0x590
inet_frag_reasm_finish+0x11f/0x2e0
ip_defrag+0x37a/0x900
ip_local_deliver+0x51/0x120
ip_sublist_rcv_finish+0x64/0x70
ip_sublist_rcv+0x179/0x210
ip_list_rcv+0xf9/0x130
How to reproduce:
<Node A>
ip link set $interface1 xdp obj xdp_pass.o
ip link set $interface1 mtu 9000 up
ip a a 10.0.0.1/24 dev $interface1
<Node B>
ip link set $interfac2 mtu 9000 up
ip a a 10.0.0.2/24 dev $interface2
ping 10.0.0.1 -s 65000
Following ping.py patch adds xdp-mb-pass case. so ping.py is going to be
able to reproduce this issue.
Fixes: 1dc4c557bfed ("bnxt: adding bnxt_xdp_build_skb to build skb from multibuffer xdp_buff")
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Link: https://patch.msgid.link/20250309134219.91670-2-ap420073@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++++
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 3179412d7b33b..321504790948f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -1833,6 +1833,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
struct rx_cmp_ext *rxcmp1;
u32 tmp_raw_cons = *raw_cons;
u16 cfa_code, cons, prod, cp_cons = RING_CMP(tmp_raw_cons);
+ struct skb_shared_info *sinfo;
struct bnxt_sw_rx_bd *rx_buf;
unsigned int len;
u8 *data_ptr, agg_bufs, cmp_type;
@@ -1957,6 +1958,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
false);
if (!frag_len)
goto oom_next_rx;
+
}
xdp_active = true;
}
@@ -1966,6 +1968,12 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
rc = 1;
goto next_rx;
}
+ if (xdp_buff_has_frags(&xdp)) {
+ sinfo = xdp_get_shared_info_from_buff(&xdp);
+ agg_bufs = sinfo->nr_frags;
+ } else {
+ agg_bufs = 0;
+ }
}
if (len <= bp->rx_copy_thresh) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 1b35805627c59..0d787e105b6ae 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -464,7 +464,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
xdp_update_skb_shared_info(skb, num_frags,
sinfo->xdp_frags_size,
- BNXT_RX_PAGE_SIZE * sinfo->nr_frags,
+ BNXT_RX_PAGE_SIZE * num_frags,
xdp_buff_is_frag_pfmemalloc(xdp));
return skb;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0755/1887] ksmbd: fix use-after-free in ksmbd_free_work_struct
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (753 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0754/1887] eth: bnxt: fix truesize for mb-xdp-pass case Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0756/1887] Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd Greg Kroah-Hartman
` (243 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit bb39ed47065455604729404729d9116868638d31 ]
->interim_entry of ksmbd_work could be deleted after oplock is freed.
We don't need to manage it with linked list. The interim request could be
immediately sent whenever a oplock break wait is needed.
Cc: stable@vger.kernel.org
Reported-by: Norbert Szetei <norbert@doyensec.com>
Tested-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/ksmbd_work.c | 3 ---
fs/smb/server/ksmbd_work.h | 1 -
fs/smb/server/oplock.c | 37 +++++++++++++++----------------------
fs/smb/server/oplock.h | 1 -
4 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c
index d7c676c151e20..544d8ccd29b0a 100644
--- a/fs/smb/server/ksmbd_work.c
+++ b/fs/smb/server/ksmbd_work.c
@@ -26,7 +26,6 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void)
INIT_LIST_HEAD(&work->request_entry);
INIT_LIST_HEAD(&work->async_request_entry);
INIT_LIST_HEAD(&work->fp_entry);
- INIT_LIST_HEAD(&work->interim_entry);
INIT_LIST_HEAD(&work->aux_read_list);
work->iov_alloc_cnt = 4;
work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec),
@@ -56,8 +55,6 @@ void ksmbd_free_work_struct(struct ksmbd_work *work)
kfree(work->tr_buf);
kvfree(work->request_buf);
kfree(work->iov);
- if (!list_empty(&work->interim_entry))
- list_del(&work->interim_entry);
if (work->async_id)
ksmbd_release_id(&work->conn->async_ida, work->async_id);
diff --git a/fs/smb/server/ksmbd_work.h b/fs/smb/server/ksmbd_work.h
index 9c3f834901e13..6372ba368e14a 100644
--- a/fs/smb/server/ksmbd_work.h
+++ b/fs/smb/server/ksmbd_work.h
@@ -96,7 +96,6 @@ struct ksmbd_work {
/* List head at conn->async_requests */
struct list_head async_request_entry;
struct list_head fp_entry;
- struct list_head interim_entry;
};
/**
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 31f84f59e40a7..58f351be5d905 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -45,7 +45,6 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
opinfo->fid = id;
opinfo->Tid = Tid;
INIT_LIST_HEAD(&opinfo->op_entry);
- INIT_LIST_HEAD(&opinfo->interim_list);
init_waitqueue_head(&opinfo->oplock_q);
init_waitqueue_head(&opinfo->oplock_brk);
atomic_set(&opinfo->refcount, 1);
@@ -830,7 +829,6 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
static int smb2_lease_break_noti(struct oplock_info *opinfo)
{
struct ksmbd_conn *conn = opinfo->conn;
- struct list_head *tmp, *t;
struct ksmbd_work *work;
struct lease_break_info *br_info;
struct lease *lease = opinfo->o_lease;
@@ -858,16 +856,6 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
work->sess = opinfo->sess;
if (opinfo->op_state == OPLOCK_ACK_WAIT) {
- list_for_each_safe(tmp, t, &opinfo->interim_list) {
- struct ksmbd_work *in_work;
-
- in_work = list_entry(tmp, struct ksmbd_work,
- interim_entry);
- setup_async_work(in_work, NULL, NULL);
- smb2_send_interim_resp(in_work, STATUS_PENDING);
- list_del_init(&in_work->interim_entry);
- release_async_work(in_work);
- }
ksmbd_conn_r_count_inc(conn);
INIT_WORK(&work->work, __smb2_lease_break_noti);
ksmbd_queue_work(work);
@@ -899,7 +887,8 @@ static void wait_lease_breaking(struct oplock_info *opinfo)
}
}
-static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
+static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level,
+ struct ksmbd_work *in_work)
{
int err = 0;
@@ -942,9 +931,15 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
}
if (lease->state & (SMB2_LEASE_WRITE_CACHING_LE |
- SMB2_LEASE_HANDLE_CACHING_LE))
+ SMB2_LEASE_HANDLE_CACHING_LE)) {
+ if (in_work) {
+ setup_async_work(in_work, NULL, NULL);
+ smb2_send_interim_resp(in_work, STATUS_PENDING);
+ release_async_work(in_work);
+ }
+
brk_opinfo->op_state = OPLOCK_ACK_WAIT;
- else
+ } else
atomic_dec(&brk_opinfo->breaking_cnt);
} else {
err = oplock_break_pending(brk_opinfo, req_op_level);
@@ -1151,7 +1146,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
}
read_unlock(&p_ci->m_lock);
- oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
opinfo_conn_put(opinfo);
read_lock(&p_ci->m_lock);
}
@@ -1192,7 +1187,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
continue;
}
read_unlock(&p_ci->m_lock);
- oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
opinfo_conn_put(opinfo);
read_lock(&p_ci->m_lock);
}
@@ -1293,8 +1288,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
goto op_break_not_needed;
}
- list_add(&work->interim_entry, &prev_opinfo->interim_list);
- err = oplock_break(prev_opinfo, SMB2_OPLOCK_LEVEL_II);
+ err = oplock_break(prev_opinfo, SMB2_OPLOCK_LEVEL_II, work);
opinfo_conn_put(prev_opinfo);
if (err == -ENOENT)
goto set_lev;
@@ -1363,8 +1357,7 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
}
brk_opinfo->open_trunc = is_trunc;
- list_add(&work->interim_entry, &brk_opinfo->interim_list);
- oplock_break(brk_opinfo, SMB2_OPLOCK_LEVEL_II);
+ oplock_break(brk_opinfo, SMB2_OPLOCK_LEVEL_II, work);
opinfo_conn_put(brk_opinfo);
}
@@ -1427,7 +1420,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
SMB2_LEASE_KEY_SIZE))
goto next;
brk_op->open_trunc = is_trunc;
- oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE);
+ oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE, NULL);
next:
opinfo_conn_put(brk_op);
rcu_read_lock();
diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h
index 0e2b1d63ca26b..1890e7f82427e 100644
--- a/fs/smb/server/oplock.h
+++ b/fs/smb/server/oplock.h
@@ -74,7 +74,6 @@ struct oplock_info {
bool is_lease;
bool open_trunc; /* truncate on open */
struct lease *o_lease;
- struct list_head interim_list;
struct list_head op_entry;
struct list_head lease_entry;
wait_queue_head_t oplock_q; /* Other server threads */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0756/1887] Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (754 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0755/1887] ksmbd: fix use-after-free in ksmbd_free_work_struct Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0757/1887] net: mctp: unshare packets when reassembling Greg Kroah-Hartman
` (242 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+31c2f641b850a348a734,
Edward Adam Davis, Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit b4f82f9ed43aefa79bec2504ae8c29be0c0f5d1d ]
After the hci sync command releases l2cap_conn, the hci receive data work
queue references the released l2cap_conn when sending to the upper layer.
Add hci dev lock to the hci receive data work queue to synchronize the two.
[1]
BUG: KASAN: slab-use-after-free in l2cap_send_cmd+0x187/0x8d0 net/bluetooth/l2cap_core.c:954
Read of size 8 at addr ffff8880271a4000 by task kworker/u9:2/5837
CPU: 0 UID: 0 PID: 5837 Comm: kworker/u9:2 Not tainted 6.13.0-rc5-syzkaller-00163-gab75170520d4 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Workqueue: hci1 hci_rx_work
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x169/0x550 mm/kasan/report.c:489
kasan_report+0x143/0x180 mm/kasan/report.c:602
l2cap_build_cmd net/bluetooth/l2cap_core.c:2964 [inline]
l2cap_send_cmd+0x187/0x8d0 net/bluetooth/l2cap_core.c:954
l2cap_sig_send_rej net/bluetooth/l2cap_core.c:5502 [inline]
l2cap_sig_channel net/bluetooth/l2cap_core.c:5538 [inline]
l2cap_recv_frame+0x221f/0x10db0 net/bluetooth/l2cap_core.c:6817
hci_acldata_packet net/bluetooth/hci_core.c:3797 [inline]
hci_rx_work+0x508/0xdb0 net/bluetooth/hci_core.c:4040
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa66/0x1840 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
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 5837:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:260 [inline]
__kmalloc_cache_noprof+0x243/0x390 mm/slub.c:4329
kmalloc_noprof include/linux/slab.h:901 [inline]
kzalloc_noprof include/linux/slab.h:1037 [inline]
l2cap_conn_add+0xa9/0x8e0 net/bluetooth/l2cap_core.c:6860
l2cap_connect_cfm+0x115/0x1090 net/bluetooth/l2cap_core.c:7239
hci_connect_cfm include/net/bluetooth/hci_core.h:2057 [inline]
hci_remote_features_evt+0x68e/0xac0 net/bluetooth/hci_event.c:3726
hci_event_func net/bluetooth/hci_event.c:7473 [inline]
hci_event_packet+0xac2/0x1540 net/bluetooth/hci_event.c:7525
hci_rx_work+0x3f3/0xdb0 net/bluetooth/hci_core.c:4035
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa66/0x1840 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
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
Freed by task 54:
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:582
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:233 [inline]
slab_free_hook mm/slub.c:2353 [inline]
slab_free mm/slub.c:4613 [inline]
kfree+0x196/0x430 mm/slub.c:4761
l2cap_connect_cfm+0xcc/0x1090 net/bluetooth/l2cap_core.c:7235
hci_connect_cfm include/net/bluetooth/hci_core.h:2057 [inline]
hci_conn_failed+0x287/0x400 net/bluetooth/hci_conn.c:1266
hci_abort_conn_sync+0x56c/0x11f0 net/bluetooth/hci_sync.c:5603
hci_cmd_sync_work+0x22b/0x400 net/bluetooth/hci_sync.c:332
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa66/0x1840 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
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
Reported-by: syzbot+31c2f641b850a348a734@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=31c2f641b850a348a734
Tested-by: syzbot+31c2f641b850a348a734@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 39 +++++++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index cdbb8dc3b7267..e570b44c16003 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -998,6 +998,16 @@ static int l2cap_get_ident(struct l2cap_conn *conn)
return ident;
}
+static void l2cap_send_acl(struct l2cap_conn *conn, struct sk_buff *skb,
+ u8 flags)
+{
+ /* Check if the hcon still valid before attempting to send */
+ if (hci_conn_valid(conn->hcon->hdev, conn->hcon))
+ hci_send_acl(conn->hchan, skb, flags);
+ else
+ kfree_skb(skb);
+}
+
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
void *data)
{
@@ -1020,7 +1030,7 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
skb->priority = HCI_PRIO_MAX;
- hci_send_acl(conn->hchan, skb, flags);
+ l2cap_send_acl(conn, skb, flags);
}
static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -1843,10 +1853,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
mutex_unlock(&conn->chan_lock);
- hci_chan_del(conn->hchan);
-
hcon->l2cap_data = NULL;
- conn->hchan = NULL;
l2cap_conn_put(conn);
}
@@ -1854,6 +1861,7 @@ static void l2cap_conn_free(struct kref *ref)
{
struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
+ hci_chan_del(conn->hchan);
hci_conn_put(conn->hcon);
kfree(conn);
}
@@ -7813,14 +7821,33 @@ static void l2cap_recv_reset(struct l2cap_conn *conn)
conn->rx_len = 0;
}
+static struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
+{
+ BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref));
+
+ if (!kref_get_unless_zero(&c->ref))
+ return NULL;
+
+ return c;
+}
+
void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
{
- struct l2cap_conn *conn = hcon->l2cap_data;
+ struct l2cap_conn *conn;
int len;
+ /* Lock hdev to access l2cap_data to avoid race with l2cap_conn_del */
+ hci_dev_lock(hcon->hdev);
+
+ conn = hcon->l2cap_data;
+
if (!conn)
conn = l2cap_conn_add(hcon);
+ conn = l2cap_conn_hold_unless_zero(conn);
+
+ hci_dev_unlock(hcon->hdev);
+
if (!conn)
goto drop;
@@ -7912,6 +7939,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
break;
}
+ l2cap_conn_put(conn);
+
drop:
kfree_skb(skb);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0757/1887] net: mctp: unshare packets when reassembling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (755 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0756/1887] Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0758/1887] ksmbd: fix null pointer dereference in alloc_preauth_hash() Greg Kroah-Hartman
` (241 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matt Johnston, Simon Horman,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Johnston <matt@codeconstruct.com.au>
[ Upstream commit f5d83cf0eeb90fade4d5c4d17d24b8bee9ceeecc ]
Ensure that the frag_list used for reassembly isn't shared with other
packets. This avoids incorrect reassembly when packets are cloned, and
prevents a memory leak due to circular references between fragments and
their skb_shared_info.
The upcoming MCTP-over-USB driver uses skb_clone which can trigger the
problem - other MCTP drivers don't share SKBs.
A kunit test is added to reproduce the issue.
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
Fixes: 4a992bbd3650 ("mctp: Implement message fragmentation & reassembly")
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250306-matt-mctp-usb-v1-1-085502b3dd28@codeconstruct.com.au
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mctp/route.c | 43 +++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/net/mctp/route.c b/net/mctp/route.c
index 4d649ba66cfdc..00fc79c05b4ac 100644
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -298,8 +298,14 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
& MCTP_HDR_SEQ_MASK;
if (!key->reasm_head) {
- key->reasm_head = skb;
- key->reasm_tailp = &(skb_shinfo(skb)->frag_list);
+ /* Since we're manipulating the shared frag_list, ensure it isn't
+ * shared with any other SKBs.
+ */
+ key->reasm_head = skb_unshare(skb, GFP_ATOMIC);
+ if (!key->reasm_head)
+ return -ENOMEM;
+
+ key->reasm_tailp = &(skb_shinfo(key->reasm_head)->frag_list);
key->last_seq = this_seq;
return 0;
}
@@ -429,18 +435,26 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
/* we can queue without the key lock here, as the
* key isn't observable yet
*/
- mctp_frag_queue(key, skb);
-
- /* if the key_add fails, we've raced with another
- * SOM packet with the same src, dest and tag. There's
- * no way to distinguish future packets, so all we
- * can do is drop; we'll free the skb on exit from
- * this function.
- */
- rc = mctp_key_add(key, msk);
- if (!rc) {
- trace_mctp_key_acquire(key);
+ rc = mctp_frag_queue(key, skb);
+ if (rc == -ENOMEM) {
+ /* skb_unshare() has already freed the skb */
+ skb = NULL;
+ } else if (!rc) {
+ /* reasm_head owns the (possibly copied) skb */
skb = NULL;
+
+ /* if the key_add fails, we've raced with
+ * another SOM packet with the same src, dest
+ * and tag. There's no way to distinguish
+ * future packets, so all we can do is drop.
+ */
+ rc = mctp_key_add(key, msk);
+ if (!rc) {
+ trace_mctp_key_acquire(key);
+ } else {
+ kfree_skb(key->reasm_head);
+ key->reasm_head = NULL;
+ }
}
/* we don't need to release key->lock on exit, so
@@ -459,7 +473,8 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
key = NULL;
} else {
rc = mctp_frag_queue(key, skb);
- if (!rc)
+ /* -ENOMEM: skb_unshare() already freed the skb */
+ if (!rc || rc == -ENOMEM)
skb = NULL;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0758/1887] ksmbd: fix null pointer dereference in alloc_preauth_hash()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (756 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0757/1887] net: mctp: unshare packets when reassembling Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0759/1887] LoongArch: BPF: Dont override subprogs return value Greg Kroah-Hartman
` (240 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Steve French, Namjae Jeon,
Sasha Levin, zdi-disclosures
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit c8b5b7c5da7d0c31c9b7190b4a7bba5281fc4780 ]
The Client send malformed smb2 negotiate request. ksmbd return error
response. Subsequently, the client can send smb2 session setup even
thought conn->preauth_info is not allocated.
This patch add KSMBD_SESS_NEED_SETUP status of connection to ignore
session setup request if smb2 negotiate phase is not complete.
Cc: stable@vger.kernel.org
Tested-by: Steve French <stfrench@microsoft.com>
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-26505
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.h | 11 +++++++++++
fs/smb/server/smb2pdu.c | 14 +++++++++++---
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h
index 2a6628bb312d9..29b32486242cc 100644
--- a/fs/smb/server/connection.h
+++ b/fs/smb/server/connection.h
@@ -27,6 +27,7 @@ enum {
KSMBD_SESS_EXITING,
KSMBD_SESS_NEED_RECONNECT,
KSMBD_SESS_NEED_NEGOTIATE,
+ KSMBD_SESS_NEED_SETUP,
KSMBD_SESS_RELEASING
};
@@ -200,6 +201,11 @@ static inline bool ksmbd_conn_need_negotiate(struct ksmbd_conn *conn)
return READ_ONCE(conn->status) == KSMBD_SESS_NEED_NEGOTIATE;
}
+static inline bool ksmbd_conn_need_setup(struct ksmbd_conn *conn)
+{
+ return READ_ONCE(conn->status) == KSMBD_SESS_NEED_SETUP;
+}
+
static inline bool ksmbd_conn_need_reconnect(struct ksmbd_conn *conn)
{
return READ_ONCE(conn->status) == KSMBD_SESS_NEED_RECONNECT;
@@ -230,6 +236,11 @@ static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_conn *conn)
WRITE_ONCE(conn->status, KSMBD_SESS_NEED_NEGOTIATE);
}
+static inline void ksmbd_conn_set_need_setup(struct ksmbd_conn *conn)
+{
+ WRITE_ONCE(conn->status, KSMBD_SESS_NEED_SETUP);
+}
+
static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_conn *conn)
{
WRITE_ONCE(conn->status, KSMBD_SESS_NEED_RECONNECT);
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index f30866efe2f4f..561581c0f26db 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1269,7 +1269,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
}
conn->srv_sec_mode = le16_to_cpu(rsp->SecurityMode);
- ksmbd_conn_set_need_negotiate(conn);
+ ksmbd_conn_set_need_setup(conn);
err_out:
if (rc && rsp->hdr.Status == STATUS_SUCCESS)
@@ -1290,6 +1290,9 @@ static int alloc_preauth_hash(struct ksmbd_session *sess,
if (sess->Preauth_HashValue)
return 0;
+ if (!conn->preauth_info)
+ return -ENOMEM;
+
sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue,
PREAUTH_HASHVALUE_SIZE, GFP_KERNEL);
if (!sess->Preauth_HashValue)
@@ -1704,6 +1707,11 @@ int smb2_sess_setup(struct ksmbd_work *work)
ksmbd_debug(SMB, "Received request for session setup\n");
+ if (!ksmbd_conn_need_setup(conn) && !ksmbd_conn_good(conn)) {
+ work->send_no_response = 1;
+ return rc;
+ }
+
WORK_BUFFERS(work, req, rsp);
rsp->StructureSize = cpu_to_le16(9);
@@ -1949,7 +1957,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
if (try_delay) {
ksmbd_conn_set_need_reconnect(conn);
ssleep(5);
- ksmbd_conn_set_need_negotiate(conn);
+ ksmbd_conn_set_need_setup(conn);
}
}
smb2_set_err_rsp(work);
@@ -2268,7 +2276,7 @@ int smb2_session_logoff(struct ksmbd_work *work)
sess->state = SMB2_SESSION_EXPIRED;
up_write(&conn->session_lock);
- ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_NEGOTIATE);
+ ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_SETUP);
rsp->StructureSize = cpu_to_le16(4);
err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp));
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0759/1887] LoongArch: BPF: Dont override subprogs return value
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (757 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0758/1887] ksmbd: fix null pointer dereference in alloc_preauth_hash() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0760/1887] ibmveth: Always stop tx queues during close Greg Kroah-Hartman
` (239 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hengqi Chen, Huacai Chen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <hengqi.chen@gmail.com>
[ Upstream commit 60f3caff1492e5b8616b9578c4bedb5c0a88ed14 ]
The verifier test `calls: div by 0 in subprog` triggers a panic at the
ld.bu instruction. The ld.bu insn is trying to load byte from memory
address returned by the subprog. The subprog actually set the correct
address at the a5 register (dedicated register for BPF return values).
But at commit 73c359d1d356 ("LoongArch: BPF: Sign-extend return values")
we also sign extended a5 to the a0 register (return value in LoongArch).
For function call insn, we later propagate the a0 register back to a5
register. This is right for native calls but wrong for bpf2bpf calls
which expect zero-extended return value in a5 register. So only move a0
to a5 for native calls (i.e. non-BPF_PSEUDO_CALL).
Cc: stable@vger.kernel.org
Fixes: 73c359d1d356 ("LoongArch: BPF: Sign-extend return values")
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/net/bpf_jit.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index bd601c269a944..88772302f952c 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -775,7 +775,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
move_addr(ctx, t1, func_addr);
emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0);
- move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
+
+ if (insn->src_reg != BPF_PSEUDO_CALL)
+ move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
+
break;
/* tail call */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0760/1887] ibmveth: Always stop tx queues during close
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (758 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0759/1887] LoongArch: BPF: Dont override subprogs return value Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0761/1887] net: ibmveth: make veth_pool_store stop hanging Greg Kroah-Hartman
` (238 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nick Child, David S. Miller,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Child <nnac123@linux.ibm.com>
[ Upstream commit 127b7218bfdd60205cfe2fa3f06d95e85a2650ed ]
netif_stop_all_queues must be called before calling H_FREE_LOGICAL_LAN.
As a result, we can remove the pool_config field from the ibmveth
adapter structure.
Some device configuration changes call ibmveth_close in order to free
the current resources held by the device. These functions then make
their changes and call ibmveth_open to reallocate and reserve resources
for the device.
Prior to this commit, the flag pool_config was used to tell ibmveth_close
that it should not halt the transmit queue. pool_config was introduced in
commit 860f242eb534 ("[PATCH] ibmveth change buffer pools dynamically")
to avoid interrupting the tx flow when making rx config changes. Since
then, other commits adopted this approach, even if making tx config
changes.
The issue with this approach was that the hypervisor freed all of
the devices control structures after the hcall H_FREE_LOGICAL_LAN
was performed but the transmit queues were never stopped. So the higher
layers in the network stack would continue transmission but any
H_SEND_LOGICAL_LAN hcall would fail with H_PARAMETER until the
hypervisor's structures for the device were allocated with the
H_REGISTER_LOGICAL_LAN hcall in ibmveth_open. This resulted in
no real networking harm but did cause several of these error
messages to be logged: "h_send_logical_lan failed with rc=-4"
So, instead of trying to keep the transmit queues alive during network
configuration changes, just stop the queues, make necessary changes then
restart the queues.
Signed-off-by: Nick Child <nnac123@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: 053f3ff67d7f ("net: ibmveth: make veth_pool_store stop hanging")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 18 +-----------------
drivers/net/ethernet/ibm/ibmveth.h | 1 -
2 files changed, 1 insertion(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 53ce857f9ec1c..468b3ac118af0 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -692,8 +692,7 @@ static int ibmveth_close(struct net_device *netdev)
napi_disable(&adapter->napi);
- if (!adapter->pool_config)
- netif_tx_stop_all_queues(netdev);
+ netif_tx_stop_all_queues(netdev);
h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
@@ -801,9 +800,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
if (netif_running(dev)) {
restart = 1;
- adapter->pool_config = 1;
ibmveth_close(dev);
- adapter->pool_config = 0;
}
set_attr = 0;
@@ -885,9 +882,7 @@ static int ibmveth_set_tso(struct net_device *dev, u32 data)
if (netif_running(dev)) {
restart = 1;
- adapter->pool_config = 1;
ibmveth_close(dev);
- adapter->pool_config = 0;
}
set_attr = 0;
@@ -1536,9 +1531,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
only the buffer pools necessary to hold the new MTU */
if (netif_running(adapter->netdev)) {
need_restart = 1;
- adapter->pool_config = 1;
ibmveth_close(adapter->netdev);
- adapter->pool_config = 0;
}
/* Look for an active buffer pool that can hold the new MTU */
@@ -1724,7 +1717,6 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
adapter->vdev = dev;
adapter->netdev = netdev;
adapter->mcastFilterSize = be32_to_cpu(*mcastFilterSize_p);
- adapter->pool_config = 0;
ibmveth_init_link_settings(netdev);
netif_napi_add_weight(netdev, &adapter->napi, ibmveth_poll, 16);
@@ -1865,9 +1857,7 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
return -ENOMEM;
}
pool->active = 1;
- adapter->pool_config = 1;
ibmveth_close(netdev);
- adapter->pool_config = 0;
if ((rc = ibmveth_open(netdev)))
return rc;
} else {
@@ -1893,10 +1883,8 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
}
if (netif_running(netdev)) {
- adapter->pool_config = 1;
ibmveth_close(netdev);
pool->active = 0;
- adapter->pool_config = 0;
if ((rc = ibmveth_open(netdev)))
return rc;
}
@@ -1907,9 +1895,7 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
return -EINVAL;
} else {
if (netif_running(netdev)) {
- adapter->pool_config = 1;
ibmveth_close(netdev);
- adapter->pool_config = 0;
pool->size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
@@ -1922,9 +1908,7 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
return -EINVAL;
} else {
if (netif_running(netdev)) {
- adapter->pool_config = 1;
ibmveth_close(netdev);
- adapter->pool_config = 0;
pool->buff_size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h
index 0e1dff1024442..bc1c1bb83c40c 100644
--- a/drivers/net/ethernet/ibm/ibmveth.h
+++ b/drivers/net/ethernet/ibm/ibmveth.h
@@ -148,7 +148,6 @@ struct ibmveth_adapter {
dma_addr_t filter_list_dma;
struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS];
struct ibmveth_rx_q rx_queue;
- int pool_config;
int rx_csum;
int large_send;
bool is_active_trunk;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0761/1887] net: ibmveth: make veth_pool_store stop hanging
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (759 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0760/1887] ibmveth: Always stop tx queues during close Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0762/1887] net: decrease cached dst counters in dst_release Greg Kroah-Hartman
` (237 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Marquardt, Nick Child,
Simon Horman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Marquardt <davemarq@linux.ibm.com>
[ Upstream commit 053f3ff67d7feefc75797863f3d84b47ad47086f ]
v2:
- Created a single error handling unlock and exit in veth_pool_store
- Greatly expanded commit message with previous explanatory-only text
Summary: Use rtnl_mutex to synchronize veth_pool_store with itself,
ibmveth_close and ibmveth_open, preventing multiple calls in a row to
napi_disable.
Background: Two (or more) threads could call veth_pool_store through
writing to /sys/devices/vio/30000002/pool*/*. You can do this easily
with a little shell script. This causes a hang.
I configured LOCKDEP, compiled ibmveth.c with DEBUG, and built a new
kernel. I ran this test again and saw:
Setting pool0/active to 0
Setting pool1/active to 1
[ 73.911067][ T4365] ibmveth 30000002 eth0: close starting
Setting pool1/active to 1
Setting pool1/active to 0
[ 73.911367][ T4366] ibmveth 30000002 eth0: close starting
[ 73.916056][ T4365] ibmveth 30000002 eth0: close complete
[ 73.916064][ T4365] ibmveth 30000002 eth0: open starting
[ 110.808564][ T712] systemd-journald[712]: Sent WATCHDOG=1 notification.
[ 230.808495][ T712] systemd-journald[712]: Sent WATCHDOG=1 notification.
[ 243.683786][ T123] INFO: task stress.sh:4365 blocked for more than 122 seconds.
[ 243.683827][ T123] Not tainted 6.14.0-01103-g2df0c02dab82-dirty #8
[ 243.683833][ T123] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 243.683838][ T123] task:stress.sh state:D stack:28096 pid:4365 tgid:4365 ppid:4364 task_flags:0x400040 flags:0x00042000
[ 243.683852][ T123] Call Trace:
[ 243.683857][ T123] [c00000000c38f690] [0000000000000001] 0x1 (unreliable)
[ 243.683868][ T123] [c00000000c38f840] [c00000000001f908] __switch_to+0x318/0x4e0
[ 243.683878][ T123] [c00000000c38f8a0] [c000000001549a70] __schedule+0x500/0x12a0
[ 243.683888][ T123] [c00000000c38f9a0] [c00000000154a878] schedule+0x68/0x210
[ 243.683896][ T123] [c00000000c38f9d0] [c00000000154ac80] schedule_preempt_disabled+0x30/0x50
[ 243.683904][ T123] [c00000000c38fa00] [c00000000154dbb0] __mutex_lock+0x730/0x10f0
[ 243.683913][ T123] [c00000000c38fb10] [c000000001154d40] napi_enable+0x30/0x60
[ 243.683921][ T123] [c00000000c38fb40] [c000000000f4ae94] ibmveth_open+0x68/0x5dc
[ 243.683928][ T123] [c00000000c38fbe0] [c000000000f4aa20] veth_pool_store+0x220/0x270
[ 243.683936][ T123] [c00000000c38fc70] [c000000000826278] sysfs_kf_write+0x68/0xb0
[ 243.683944][ T123] [c00000000c38fcb0] [c0000000008240b8] kernfs_fop_write_iter+0x198/0x2d0
[ 243.683951][ T123] [c00000000c38fd00] [c00000000071b9ac] vfs_write+0x34c/0x650
[ 243.683958][ T123] [c00000000c38fdc0] [c00000000071bea8] ksys_write+0x88/0x150
[ 243.683966][ T123] [c00000000c38fe10] [c0000000000317f4] system_call_exception+0x124/0x340
[ 243.683973][ T123] [c00000000c38fe50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec
...
[ 243.684087][ T123] Showing all locks held in the system:
[ 243.684095][ T123] 1 lock held by khungtaskd/123:
[ 243.684099][ T123] #0: c00000000278e370 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x50/0x248
[ 243.684114][ T123] 4 locks held by stress.sh/4365:
[ 243.684119][ T123] #0: c00000003a4cd3f8 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x88/0x150
[ 243.684132][ T123] #1: c000000041aea888 (&of->mutex#2){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x154/0x2d0
[ 243.684143][ T123] #2: c0000000366fb9a8 (kn->active#64){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x160/0x2d0
[ 243.684155][ T123] #3: c000000035ff4cb8 (&dev->lock){+.+.}-{3:3}, at: napi_enable+0x30/0x60
[ 243.684166][ T123] 5 locks held by stress.sh/4366:
[ 243.684170][ T123] #0: c00000003a4cd3f8 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x88/0x150
[ 243.684183][ T123] #1: c00000000aee2288 (&of->mutex#2){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x154/0x2d0
[ 243.684194][ T123] #2: c0000000366f4ba8 (kn->active#64){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x160/0x2d0
[ 243.684205][ T123] #3: c000000035ff4cb8 (&dev->lock){+.+.}-{3:3}, at: napi_disable+0x30/0x60
[ 243.684216][ T123] #4: c0000003ff9bbf18 (&rq->__lock){-.-.}-{2:2}, at: __schedule+0x138/0x12a0
>From the ibmveth debug, two threads are calling veth_pool_store, which
calls ibmveth_close and ibmveth_open. Here's the sequence:
T4365 T4366
----------------- ----------------- ---------
veth_pool_store veth_pool_store
ibmveth_close
ibmveth_close
napi_disable
napi_disable
ibmveth_open
napi_enable <- HANG
ibmveth_close calls napi_disable at the top and ibmveth_open calls
napi_enable at the top.
https://docs.kernel.org/networking/napi.html]] says
The control APIs are not idempotent. Control API calls are safe
against concurrent use of datapath APIs but an incorrect sequence of
control API calls may result in crashes, deadlocks, or race
conditions. For example, calling napi_disable() multiple times in a
row will deadlock.
In the normal open and close paths, rtnl_mutex is acquired to prevent
other callers. This is missing from veth_pool_store. Use rtnl_mutex in
veth_pool_store fixes these hangs.
Signed-off-by: Dave Marquardt <davemarq@linux.ibm.com>
Fixes: 860f242eb534 ("[PATCH] ibmveth change buffer pools dynamically")
Reviewed-by: Nick Child <nnac123@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250402154403.386744-1-davemarq@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 39 +++++++++++++++++++++---------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 468b3ac118af0..69e8233920a1e 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1848,18 +1848,22 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
long value = simple_strtol(buf, NULL, 10);
long rc;
+ rtnl_lock();
+
if (attr == &veth_active_attr) {
if (value && !pool->active) {
if (netif_running(netdev)) {
if (ibmveth_alloc_buffer_pool(pool)) {
netdev_err(netdev,
"unable to alloc pool\n");
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto unlock_err;
}
pool->active = 1;
ibmveth_close(netdev);
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->active = 1;
}
@@ -1879,48 +1883,59 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
if (i == IBMVETH_NUM_BUFF_POOLS) {
netdev_err(netdev, "no active pool >= MTU\n");
- return -EPERM;
+ rc = -EPERM;
+ goto unlock_err;
}
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->active = 0;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
}
pool->active = 0;
}
} else if (attr == &veth_num_attr) {
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
- return -EINVAL;
+ rc = -EINVAL;
+ goto unlock_err;
} else {
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->size = value;
}
}
} else if (attr == &veth_size_attr) {
if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
- return -EINVAL;
+ rc = -EINVAL;
+ goto unlock_err;
} else {
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->buff_size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->buff_size = value;
}
}
}
+ rtnl_unlock();
/* kick the interrupt handler to allocate/deallocate pools */
ibmveth_interrupt(netdev->irq, netdev);
return count;
+
+unlock_err:
+ rtnl_unlock();
+ return rc;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0762/1887] net: decrease cached dst counters in dst_release
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (760 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0761/1887] net: ibmveth: make veth_pool_store stop hanging Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0763/1887] fs/9p: fix NULL pointer dereference on mkdir Greg Kroah-Hartman
` (236 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Antoine Tenart, Paolo Abeni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoine Tenart <atenart@kernel.org>
[ Upstream commit 3a0a3ff6593d670af2451ec363ccb7b18aec0c0a ]
Upstream fix ac888d58869b ("net: do not delay dst_entries_add() in
dst_release()") moved decrementing the dst count from dst_destroy to
dst_release to avoid accessing already freed data in case of netns
dismantle. However in case CONFIG_DST_CACHE is enabled and OvS+tunnels
are used, this fix is incomplete as the same issue will be seen for
cached dsts:
Unable to handle kernel paging request at virtual address ffff5aabf6b5c000
Call trace:
percpu_counter_add_batch+0x3c/0x160 (P)
dst_release+0xec/0x108
dst_cache_destroy+0x68/0xd8
dst_destroy+0x13c/0x168
dst_destroy_rcu+0x1c/0xb0
rcu_do_batch+0x18c/0x7d0
rcu_core+0x174/0x378
rcu_core_si+0x18/0x30
Fix this by invalidating the cache, and thus decrementing cached dst
counters, in dst_release too.
Fixes: d71785ffc7e7 ("net: add dst_cache to ovs vxlan lwtunnel")
Signed-off-by: Antoine Tenart <atenart@kernel.org>
Link: https://patch.msgid.link/20250326173634.31096-1-atenart@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dst.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/core/dst.c b/net/core/dst.c
index cbb6888aa32ba..2ac7d3bbabf1c 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -173,6 +173,14 @@ void dst_release(struct dst_entry *dst)
net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
__func__, dst, newrefcnt);
if (!newrefcnt){
+#ifdef CONFIG_DST_CACHE
+ if (dst->flags & DST_METADATA) {
+ struct metadata_dst *md_dst = (struct metadata_dst *)dst;
+
+ if (md_dst->type == METADATA_IP_TUNNEL)
+ dst_cache_reset_now(&md_dst->u.tun_info.dst_cache);
+ }
+#endif
dst_count_dec(dst);
call_rcu(&dst->rcu_head, dst_destroy_rcu);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0763/1887] fs/9p: fix NULL pointer dereference on mkdir
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (761 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0762/1887] net: decrease cached dst counters in dst_release Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0764/1887] ax25: Remove broken autobind Greg Kroah-Hartman
` (235 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5b667f9a1fee4ba3775a,
Christian Schoenebeck, Dominique Martinet, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Schoenebeck <linux_oss@crudebyte.com>
[ Upstream commit 3f61ac7c65bdb26accb52f9db66313597e759821 ]
When a 9p tree was mounted with option 'posixacl', parent directory had a
default ACL set for its subdirectories, e.g.:
setfacl -m default:group:simpsons:rwx parentdir
then creating a subdirectory crashed 9p client, as v9fs_fid_add() call in
function v9fs_vfs_mkdir_dotl() sets the passed 'fid' pointer to NULL
(since dafbe689736) even though the subsequent v9fs_set_create_acl() call
expects a valid non-NULL 'fid' pointer:
[ 37.273191] BUG: kernel NULL pointer dereference, address: 0000000000000000
...
[ 37.322338] Call Trace:
[ 37.323043] <TASK>
[ 37.323621] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434)
[ 37.324448] ? page_fault_oops (arch/x86/mm/fault.c:714)
[ 37.325532] ? search_module_extables (kernel/module/main.c:3733)
[ 37.326742] ? p9_client_walk (net/9p/client.c:1165) 9pnet
[ 37.328006] ? search_bpf_extables (kernel/bpf/core.c:804)
[ 37.329142] ? exc_page_fault (./arch/x86/include/asm/paravirt.h:686 arch/x86/mm/fault.c:1488 arch/x86/mm/fault.c:1538)
[ 37.330196] ? asm_exc_page_fault (./arch/x86/include/asm/idtentry.h:574)
[ 37.331330] ? p9_client_walk (net/9p/client.c:1165) 9pnet
[ 37.332562] ? v9fs_fid_xattr_get (fs/9p/xattr.c:30) 9p
[ 37.333824] v9fs_fid_xattr_set (fs/9p/fid.h:23 fs/9p/xattr.c:121) 9p
[ 37.335077] v9fs_set_acl (fs/9p/acl.c:276) 9p
[ 37.336112] v9fs_set_create_acl (fs/9p/acl.c:307) 9p
[ 37.337326] v9fs_vfs_mkdir_dotl (fs/9p/vfs_inode_dotl.c:411) 9p
[ 37.338590] vfs_mkdir (fs/namei.c:4313)
[ 37.339535] do_mkdirat (fs/namei.c:4336)
[ 37.340465] __x64_sys_mkdir (fs/namei.c:4354)
[ 37.341455] do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
[ 37.342447] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
Fix this by simply swapping the sequence of these two calls in
v9fs_vfs_mkdir_dotl(), i.e. calling v9fs_set_create_acl() before
v9fs_fid_add().
Fixes: dafbe689736f ("9p fid refcount: cleanup p9_fid_put calls")
Reported-by: syzbot+5b667f9a1fee4ba3775a@syzkaller.appspotmail.com
Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com>
Message-ID: <E1tsiI6-002iMG-Kh@kylie.crudebyte.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/9p/vfs_inode_dotl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index e15ad46833e05..7c261b354379a 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -424,8 +424,8 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
err);
goto error;
}
- v9fs_fid_add(dentry, &fid);
v9fs_set_create_acl(inode, fid, dacl, pacl);
+ v9fs_fid_add(dentry, &fid);
d_instantiate(dentry, inode);
err = 0;
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0764/1887] ax25: Remove broken autobind
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (762 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0763/1887] fs/9p: fix NULL pointer dereference on mkdir Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0765/1887] btrfs: fix block group refcount race in btrfs_create_pending_block_groups() Greg Kroah-Hartman
` (234 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+33841dc6aa3e1d86b78a,
Murad Masimov, David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Murad Masimov <m.masimov@mt-integration.ru>
[ Upstream commit 2f6efbabceb6b2914ee9bafb86d9a51feae9cce8 ]
Binding AX25 socket by using the autobind feature leads to memory leaks
in ax25_connect() and also refcount leaks in ax25_release(). Memory
leak was detected with kmemleak:
================================================================
unreferenced object 0xffff8880253cd680 (size 96):
backtrace:
__kmalloc_node_track_caller_noprof (./include/linux/kmemleak.h:43)
kmemdup_noprof (mm/util.c:136)
ax25_rt_autobind (net/ax25/ax25_route.c:428)
ax25_connect (net/ax25/af_ax25.c:1282)
__sys_connect_file (net/socket.c:2045)
__sys_connect (net/socket.c:2064)
__x64_sys_connect (net/socket.c:2067)
do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
================================================================
When socket is bound, refcounts must be incremented the way it is done
in ax25_bind() and ax25_setsockopt() (SO_BINDTODEVICE). In case of
autobind, the refcounts are not incremented.
This bug leads to the following issue reported by Syzkaller:
================================================================
ax25_connect(): syz-executor318 uses autobind, please contact jreuter@yaina.de
------------[ cut here ]------------
refcount_t: decrement hit 0; leaking memory.
WARNING: CPU: 0 PID: 5317 at lib/refcount.c:31 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
Modules linked in:
CPU: 0 UID: 0 PID: 5317 Comm: syz-executor318 Not tainted 6.14.0-rc4-syzkaller-00278-gece144f151ac #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
RIP: 0010:refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
...
Call Trace:
<TASK>
__refcount_dec include/linux/refcount.h:336 [inline]
refcount_dec include/linux/refcount.h:351 [inline]
ref_tracker_free+0x6af/0x7e0 lib/ref_tracker.c:236
netdev_tracker_free include/linux/netdevice.h:4302 [inline]
netdev_put include/linux/netdevice.h:4319 [inline]
ax25_release+0x368/0x960 net/ax25/af_ax25.c:1080
__sock_release net/socket.c:647 [inline]
sock_close+0xbc/0x240 net/socket.c:1398
__fput+0x3e9/0x9f0 fs/file_table.c:464
__do_sys_close fs/open.c:1580 [inline]
__se_sys_close fs/open.c:1565 [inline]
__x64_sys_close+0x7f/0x110 fs/open.c:1565
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
...
</TASK>
================================================================
Considering the issues above and the comments left in the code that say:
"check if we can remove this feature. It is broken."; "autobinding in this
may or may not work"; - it is better to completely remove this feature than
to fix it because it is broken and leads to various kinds of memory bugs.
Now calling connect() without first binding socket will result in an
error (-EINVAL). Userspace software that relies on the autobind feature
might get broken. However, this feature does not seem widely used with
this specific driver as it was not reliable at any point of time, and it
is already broken anyway. E.g. ax25-tools and ax25-apps packages for
popular distributions do not use the autobind feature for AF_AX25.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+33841dc6aa3e1d86b78a@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=33841dc6aa3e1d86b78a
Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/ax25.h | 1 -
net/ax25/af_ax25.c | 30 ++++++------------
net/ax25/ax25_route.c | 74 -------------------------------------------
3 files changed, 10 insertions(+), 95 deletions(-)
diff --git a/include/net/ax25.h b/include/net/ax25.h
index e9465aa07a4e7..6b29f3a30cfa0 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -419,7 +419,6 @@ void ax25_rt_device_down(struct net_device *);
int ax25_rt_ioctl(unsigned int, void __user *);
extern const struct seq_operations ax25_rt_seqops;
ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
-int ax25_rt_autobind(ax25_cb *, ax25_address *);
struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
ax25_address *, ax25_digi *);
void ax25_rt_free(void);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 862e03493b7ed..64b81a693e25e 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1270,28 +1270,18 @@ static int __must_check ax25_connect(struct socket *sock,
}
}
- /*
- * Must bind first - autobinding in this may or may not work. If
- * the socket is already bound, check to see if the device has
- * been filled in, error if it hasn't.
- */
+ /* Must bind first - autobinding does not work. */
if (sock_flag(sk, SOCK_ZAPPED)) {
- /* check if we can remove this feature. It is broken. */
- printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
- current->comm);
- if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
- kfree(digi);
- goto out_release;
- }
+ kfree(digi);
+ err = -EINVAL;
+ goto out_release;
+ }
- ax25_fillin_cb(ax25, ax25->ax25_dev);
- ax25_cb_add(ax25);
- } else {
- if (ax25->ax25_dev == NULL) {
- kfree(digi);
- err = -EHOSTUNREACH;
- goto out_release;
- }
+ /* Check to see if the device has been filled in, error if it hasn't. */
+ if (ax25->ax25_dev == NULL) {
+ kfree(digi);
+ err = -EHOSTUNREACH;
+ goto out_release;
}
if (sk->sk_type == SOCK_SEQPACKET &&
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 69de75db0c9c2..10577434f40bf 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -373,80 +373,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
return ax25_rt;
}
-/*
- * Adjust path: If you specify a default route and want to connect
- * a target on the digipeater path but w/o having a special route
- * set before, the path has to be truncated from your target on.
- */
-static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
-{
- int k;
-
- for (k = 0; k < digipeat->ndigi; k++) {
- if (ax25cmp(addr, &digipeat->calls[k]) == 0)
- break;
- }
-
- digipeat->ndigi = k;
-}
-
-
-/*
- * Find which interface to use.
- */
-int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
-{
- ax25_uid_assoc *user;
- ax25_route *ax25_rt;
- int err = 0;
-
- ax25_route_lock_use();
- ax25_rt = ax25_get_route(addr, NULL);
- if (!ax25_rt) {
- ax25_route_lock_unuse();
- return -EHOSTUNREACH;
- }
- rcu_read_lock();
- if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
- err = -EHOSTUNREACH;
- goto put;
- }
-
- user = ax25_findbyuid(current_euid());
- if (user) {
- ax25->source_addr = user->call;
- ax25_uid_put(user);
- } else {
- if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
- err = -EPERM;
- goto put;
- }
- ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
- }
-
- if (ax25_rt->digipeat != NULL) {
- ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
- GFP_ATOMIC);
- if (ax25->digipeat == NULL) {
- err = -ENOMEM;
- goto put;
- }
- ax25_adjust_path(addr, ax25->digipeat);
- }
-
- if (ax25->sk != NULL) {
- local_bh_disable();
- bh_lock_sock(ax25->sk);
- sock_reset_flag(ax25->sk, SOCK_ZAPPED);
- bh_unlock_sock(ax25->sk);
- local_bh_enable();
- }
-
-put:
- rcu_read_unlock();
- ax25_route_lock_unuse();
- return err;
-}
struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
ax25_address *dest, ax25_digi *digi)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0765/1887] btrfs: fix block group refcount race in btrfs_create_pending_block_groups()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (763 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0764/1887] ax25: Remove broken autobind Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0766/1887] f2fs: convert f2fs_handle_page_eio() to use folio Greg Kroah-Hartman
` (233 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
Boris Burkov, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <boris@bur.io>
[ Upstream commit 2d8e5168d48a91e7a802d3003e72afb4304bebfa ]
Block group creation is done in two phases, which results in a slightly
unintuitive property: a block group can be allocated/deallocated from
after btrfs_make_block_group() adds it to the space_info with
btrfs_add_bg_to_space_info(), but before creation is completely completed
in btrfs_create_pending_block_groups(). As a result, it is possible for a
block group to go unused and have 'btrfs_mark_bg_unused' called on it
concurrently with 'btrfs_create_pending_block_groups'. This causes a
number of issues, which were fixed with the block group flag
'BLOCK_GROUP_FLAG_NEW'.
However, this fix is not quite complete. Since it does not use the
unused_bg_lock, it is possible for the following race to occur:
btrfs_create_pending_block_groups btrfs_mark_bg_unused
if list_empty // false
list_del_init
clear_bit
else if (test_bit) // true
list_move_tail
And we get into the exact same broken ref count and invalid new_bgs
state for transaction cleanup that BLOCK_GROUP_FLAG_NEW was designed to
prevent.
The broken refcount aspect will result in a warning like:
[1272.943527] refcount_t: underflow; use-after-free.
[1272.943967] WARNING: CPU: 1 PID: 61 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110
[1272.944731] Modules linked in: btrfs virtio_net xor zstd_compress raid6_pq null_blk [last unloaded: btrfs]
[1272.945550] CPU: 1 UID: 0 PID: 61 Comm: kworker/u32:1 Kdump: loaded Tainted: G W 6.14.0-rc5+ #108
[1272.946368] Tainted: [W]=WARN
[1272.946585] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
[1272.947273] Workqueue: btrfs_discard btrfs_discard_workfn [btrfs]
[1272.947788] RIP: 0010:refcount_warn_saturate+0xba/0x110
[1272.949532] RSP: 0018:ffffbf1200247df0 EFLAGS: 00010282
[1272.949901] RAX: 0000000000000000 RBX: ffffa14b00e3f800 RCX: 0000000000000000
[1272.950437] RDX: 0000000000000000 RSI: ffffbf1200247c78 RDI: 00000000ffffdfff
[1272.950986] RBP: ffffa14b00dc2860 R08: 00000000ffffdfff R09: ffffffff90526268
[1272.951512] R10: ffffffff904762c0 R11: 0000000063666572 R12: ffffa14b00dc28c0
[1272.952024] R13: 0000000000000000 R14: ffffa14b00dc2868 R15: 000001285dcd12c0
[1272.952850] FS: 0000000000000000(0000) GS:ffffa14d33c40000(0000) knlGS:0000000000000000
[1272.953458] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[1272.953931] CR2: 00007f838cbda000 CR3: 000000010104e000 CR4: 00000000000006f0
[1272.954474] Call Trace:
[1272.954655] <TASK>
[1272.954812] ? refcount_warn_saturate+0xba/0x110
[1272.955173] ? __warn.cold+0x93/0xd7
[1272.955487] ? refcount_warn_saturate+0xba/0x110
[1272.955816] ? report_bug+0xe7/0x120
[1272.956103] ? handle_bug+0x53/0x90
[1272.956424] ? exc_invalid_op+0x13/0x60
[1272.956700] ? asm_exc_invalid_op+0x16/0x20
[1272.957011] ? refcount_warn_saturate+0xba/0x110
[1272.957399] btrfs_discard_cancel_work.cold+0x26/0x2b [btrfs]
[1272.957853] btrfs_put_block_group.cold+0x5d/0x8e [btrfs]
[1272.958289] btrfs_discard_workfn+0x194/0x380 [btrfs]
[1272.958729] process_one_work+0x130/0x290
[1272.959026] worker_thread+0x2ea/0x420
[1272.959335] ? __pfx_worker_thread+0x10/0x10
[1272.959644] kthread+0xd7/0x1c0
[1272.959872] ? __pfx_kthread+0x10/0x10
[1272.960172] ret_from_fork+0x30/0x50
[1272.960474] ? __pfx_kthread+0x10/0x10
[1272.960745] ret_from_fork_asm+0x1a/0x30
[1272.961035] </TASK>
[1272.961238] ---[ end trace 0000000000000000 ]---
Though we have seen them in the async discard workfn as well. It is
most likely to happen after a relocation finishes which cancels discard,
tears down the block group, etc.
Fix this fully by taking the lock around the list_del_init + clear_bit
so that the two are done atomically.
Fixes: 0657b20c5a76 ("btrfs: fix use-after-free of new block group that became unused")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/block-group.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 1f9fbec887c03..a8f096b46b7b2 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -2586,8 +2586,11 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
/* Already aborted the transaction if it failed. */
next:
btrfs_delayed_refs_rsv_release(fs_info, 1);
+
+ spin_lock(&fs_info->unused_bgs_lock);
list_del_init(&block_group->bg_list);
clear_bit(BLOCK_GROUP_FLAG_NEW, &block_group->runtime_flags);
+ spin_unlock(&fs_info->unused_bgs_lock);
}
btrfs_trans_release_chunk_metadata(trans);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0766/1887] f2fs: convert f2fs_handle_page_eio() to use folio
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (764 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0765/1887] btrfs: fix block group refcount race in btrfs_create_pending_block_groups() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0767/1887] f2fs: fix potential deadloop in prepare_compress_overwrite() Greg Kroah-Hartman
` (232 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Wilcox, Chao Yu, Jaegeuk Kim,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 763a0dc792f9d7c79c1d85415c6cebc1f79bba16 ]
Convert to use folio, so that we can get rid of 'page->index' to
prepare for removal of 'index' field in structure page [1].
[1] https://lore.kernel.org/all/Zp8fgUSIBGQ1TN0D@casper.infradead.org/
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: 3147ee567dd9 ("f2fs: fix potential deadloop in prepare_compress_overwrite()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/checkpoint.c | 2 +-
fs/f2fs/f2fs.h | 6 ++++--
fs/f2fs/node.c | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 84fc60d843bc2..3d3b0e313af8f 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -102,7 +102,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
}
if (unlikely(!PageUptodate(page))) {
- f2fs_handle_page_eio(sbi, page->index, META);
+ f2fs_handle_page_eio(sbi, page_folio(page), META);
f2fs_put_page(page, 1);
return ERR_PTR(-EIO);
}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 6d22c18f948d3..5b63b92a10276 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4581,9 +4581,11 @@ static inline void f2fs_io_schedule_timeout(long timeout)
io_schedule_timeout(timeout);
}
-static inline void f2fs_handle_page_eio(struct f2fs_sb_info *sbi, pgoff_t ofs,
- enum page_type type)
+static inline void f2fs_handle_page_eio(struct f2fs_sb_info *sbi,
+ struct folio *folio, enum page_type type)
{
+ pgoff_t ofs = folio->index;
+
if (unlikely(f2fs_cp_error(sbi)))
return;
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 8b4e8e251649c..e69791dd74354 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1512,7 +1512,7 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
out_put_err:
/* ENOENT comes from read_node_page which is not an error. */
if (err != -ENOENT)
- f2fs_handle_page_eio(sbi, page->index, NODE);
+ f2fs_handle_page_eio(sbi, page_folio(page), NODE);
f2fs_put_page(page, 1);
return ERR_PTR(err);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0767/1887] f2fs: fix potential deadloop in prepare_compress_overwrite()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (765 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0766/1887] f2fs: convert f2fs_handle_page_eio() to use folio Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0768/1887] perf: Fix hang while freeing sigtrap event Greg Kroah-Hartman
` (231 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Prusakowski, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 3147ee567dd9004a49826ddeaf0a4b12865d4409 ]
Jan Prusakowski reported a kernel hang issue as below:
When running xfstests on linux-next kernel (6.14.0-rc3, 6.12) I
encountered a problem in generic/475 test where fsstress process
gets blocked in __f2fs_write_data_pages() and the test hangs.
The options I used are:
MKFS_OPTIONS -- -O compression -O extra_attr -O project_quota -O quota /dev/vdc
MOUNT_OPTIONS -- -o acl,user_xattr -o discard,compress_extension=* /dev/vdc /vdc
INFO: task kworker/u8:0:11 blocked for more than 122 seconds.
Not tainted 6.14.0-rc3-xfstests-lockdep #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/u8:0 state:D stack:0 pid:11 tgid:11 ppid:2 task_flags:0x4208160 flags:0x00004000
Workqueue: writeback wb_workfn (flush-253:0)
Call Trace:
<TASK>
__schedule+0x309/0x8e0
schedule+0x3a/0x100
schedule_preempt_disabled+0x15/0x30
__mutex_lock+0x59a/0xdb0
__f2fs_write_data_pages+0x3ac/0x400
do_writepages+0xe8/0x290
__writeback_single_inode+0x5c/0x360
writeback_sb_inodes+0x22f/0x570
wb_writeback+0xb0/0x410
wb_do_writeback+0x47/0x2f0
wb_workfn+0x5a/0x1c0
process_one_work+0x223/0x5b0
worker_thread+0x1d5/0x3c0
kthread+0xfd/0x230
ret_from_fork+0x31/0x50
ret_from_fork_asm+0x1a/0x30
</TASK>
The root cause is: once generic/475 starts toload error table to dm
device, f2fs_prepare_compress_overwrite() will loop reading compressed
cluster pages due to IO error, meanwhile it has held .writepages lock,
it can block all other writeback tasks.
Let's fix this issue w/ below changes:
- add f2fs_handle_page_eio() in prepare_compress_overwrite() to
detect IO error.
- detect cp_error earler in f2fs_read_multi_pages().
Fixes: 4c8ff7095bef ("f2fs: support data compression")
Reported-by: Jan Prusakowski <jprusakowski@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/compress.c | 1 +
fs/f2fs/data.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 5d0c41abb4050..de64a621c729b 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1123,6 +1123,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
f2fs_compress_ctx_add_page(cc, page);
if (!PageUptodate(page)) {
+ f2fs_handle_page_eio(sbi, page_folio(page), DATA);
release_and_retry:
f2fs_put_rpages(cc);
f2fs_unlock_rpages(cc, i + 1);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 082e09be4e8a9..6384ac931bb7d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2241,6 +2241,12 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
int i;
int ret = 0;
+ if (unlikely(f2fs_cp_error(sbi))) {
+ ret = -EIO;
+ from_dnode = false;
+ goto out_put_dnode;
+ }
+
f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
last_block_in_file = bytes_to_blks(inode,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0768/1887] perf: Fix hang while freeing sigtrap event
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (766 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0767/1887] f2fs: fix potential deadloop in prepare_compress_overwrite() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0769/1887] smb: client: fix UAF in decryption with multichannel Greg Kroah-Hartman
` (230 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yi Lai, syzbot+3c4321e10eea460eb606,
Frederic Weisbecker, Peter Zijlstra (Intel), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <frederic@kernel.org>
[ Upstream commit 56799bc035658738f362acec3e7647bb84e68933 ]
Perf can hang while freeing a sigtrap event if a related deferred
signal hadn't managed to be sent before the file got closed:
perf_event_overflow()
task_work_add(perf_pending_task)
fput()
task_work_add(____fput())
task_work_run()
____fput()
perf_release()
perf_event_release_kernel()
_free_event()
perf_pending_task_sync()
task_work_cancel() -> FAILED
rcuwait_wait_event()
Once task_work_run() is running, the list of pending callbacks is
removed from the task_struct and from this point on task_work_cancel()
can't remove any pending and not yet started work items, hence the
task_work_cancel() failure and the hang on rcuwait_wait_event().
Task work could be changed to remove one work at a time, so a work
running on the current task can always cancel a pending one, however
the wait / wake design is still subject to inverted dependencies when
remote targets are involved, as pictured by Oleg:
T1 T2
fd = perf_event_open(pid => T2->pid); fd = perf_event_open(pid => T1->pid);
close(fd) close(fd)
<IRQ> <IRQ>
perf_event_overflow() perf_event_overflow()
task_work_add(perf_pending_task) task_work_add(perf_pending_task)
</IRQ> </IRQ>
fput() fput()
task_work_add(____fput()) task_work_add(____fput())
task_work_run() task_work_run()
____fput() ____fput()
perf_release() perf_release()
perf_event_release_kernel() perf_event_release_kernel()
_free_event() _free_event()
perf_pending_task_sync() perf_pending_task_sync()
rcuwait_wait_event() rcuwait_wait_event()
Therefore the only option left is to acquire the event reference count
upon queueing the perf task work and release it from the task work, just
like it was done before 3a5465418f5f ("perf: Fix event leak upon exec and file release")
but without the leaks it fixed.
Some adjustments are necessary to make it work:
* A child event might dereference its parent upon freeing. Care must be
taken to release the parent last.
* Some places assuming the event doesn't have any reference held and
therefore can be freed right away must instead put the reference and
let the reference counting to its job.
Reported-by: "Yi Lai" <yi1.lai@linux.intel.com>
Closes: https://lore.kernel.org/all/Zx9Losv4YcJowaP%2F@ly-workstation/
Reported-by: syzbot+3c4321e10eea460eb606@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/673adf75.050a0220.87769.0024.GAE@google.com/
Fixes: 3a5465418f5f ("perf: Fix event leak upon exec and file release")
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20250304135446.18905-1-frederic@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/perf_event.h | 1 -
kernel/events/core.c | 64 +++++++++++---------------------------
2 files changed, 19 insertions(+), 46 deletions(-)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 41ff70f315a92..1c32eec27b045 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -765,7 +765,6 @@ struct perf_event {
struct irq_work pending_irq;
struct callback_head pending_task;
unsigned int pending_work;
- struct rcuwait pending_work_wait;
atomic_t event_limit;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index a64e0254e803c..49b79617723ab 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2317,6 +2317,7 @@ event_sched_out(struct perf_event *event,
!event->pending_work &&
!task_work_add(current, &event->pending_task, TWA_RESUME)) {
event->pending_work = 1;
+ WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount));
} else {
local_dec(&event->ctx->nr_pending);
}
@@ -5016,35 +5017,9 @@ static bool exclusive_event_installable(struct perf_event *event,
static void perf_addr_filters_splice(struct perf_event *event,
struct list_head *head);
-static void perf_pending_task_sync(struct perf_event *event)
-{
- struct callback_head *head = &event->pending_task;
-
- if (!event->pending_work)
- return;
- /*
- * If the task is queued to the current task's queue, we
- * obviously can't wait for it to complete. Simply cancel it.
- */
- if (task_work_cancel(current, head)) {
- event->pending_work = 0;
- local_dec(&event->ctx->nr_pending);
- return;
- }
-
- /*
- * All accesses related to the event are within the same
- * non-preemptible section in perf_pending_task(). The RCU
- * grace period before the event is freed will make sure all
- * those accesses are complete by then.
- */
- rcuwait_wait_event(&event->pending_work_wait, !event->pending_work, TASK_UNINTERRUPTIBLE);
-}
-
static void _free_event(struct perf_event *event)
{
irq_work_sync(&event->pending_irq);
- perf_pending_task_sync(event);
unaccount_event(event);
@@ -5166,10 +5141,17 @@ static void perf_remove_from_owner(struct perf_event *event)
static void put_event(struct perf_event *event)
{
+ struct perf_event *parent;
+
if (!atomic_long_dec_and_test(&event->refcount))
return;
+ parent = event->parent;
_free_event(event);
+
+ /* Matches the refcount bump in inherit_event() */
+ if (parent)
+ put_event(parent);
}
/*
@@ -5253,11 +5235,6 @@ int perf_event_release_kernel(struct perf_event *event)
if (tmp == child) {
perf_remove_from_context(child, DETACH_GROUP);
list_move(&child->child_list, &free_list);
- /*
- * This matches the refcount bump in inherit_event();
- * this can't be the last reference.
- */
- put_event(event);
} else {
var = &ctx->refcount;
}
@@ -5283,7 +5260,8 @@ int perf_event_release_kernel(struct perf_event *event)
void *var = &child->ctx->refcount;
list_del(&child->child_list);
- free_event(child);
+ /* Last reference unless ->pending_task work is pending */
+ put_event(child);
/*
* Wake any perf_event_free_task() waiting for this event to be
@@ -5294,7 +5272,11 @@ int perf_event_release_kernel(struct perf_event *event)
}
no_ctx:
- put_event(event); /* Must be the 'last' reference */
+ /*
+ * Last reference unless ->pending_task work is pending on this event
+ * or any of its children.
+ */
+ put_event(event);
return 0;
}
EXPORT_SYMBOL_GPL(perf_event_release_kernel);
@@ -6699,11 +6681,6 @@ static void perf_pending_task(struct callback_head *head)
struct perf_event *event = container_of(head, struct perf_event, pending_task);
int rctx;
- /*
- * All accesses to the event must belong to the same implicit RCU read-side
- * critical section as the ->pending_work reset. See comment in
- * perf_pending_task_sync().
- */
preempt_disable_notrace();
/*
* If we 'fail' here, that's OK, it means recursion is already disabled
@@ -6715,12 +6692,13 @@ static void perf_pending_task(struct callback_head *head)
event->pending_work = 0;
perf_sigtrap(event);
local_dec(&event->ctx->nr_pending);
- rcuwait_wake_up(&event->pending_work_wait);
}
if (rctx >= 0)
perf_swevent_put_recursion_context(rctx);
preempt_enable_notrace();
+
+ put_event(event);
}
#ifdef CONFIG_GUEST_PERF_EVENTS
@@ -11915,7 +11893,6 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
init_waitqueue_head(&event->waitq);
init_irq_work(&event->pending_irq, perf_pending_irq);
init_task_work(&event->pending_task, perf_pending_task);
- rcuwait_init(&event->pending_work_wait);
mutex_init(&event->mmap_mutex);
raw_spin_lock_init(&event->addr_filters.lock);
@@ -13100,8 +13077,7 @@ perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
* Kick perf_poll() for is_event_hup();
*/
perf_event_wakeup(parent_event);
- free_event(event);
- put_event(parent_event);
+ put_event(event);
return;
}
@@ -13221,13 +13197,11 @@ static void perf_free_event(struct perf_event *event,
list_del_init(&event->child_list);
mutex_unlock(&parent->child_mutex);
- put_event(parent);
-
raw_spin_lock_irq(&ctx->lock);
perf_group_detach(event);
list_del_event(event, ctx);
raw_spin_unlock_irq(&ctx->lock);
- free_event(event);
+ put_event(event);
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0769/1887] smb: client: fix UAF in decryption with multichannel
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (767 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0768/1887] perf: Fix hang while freeing sigtrap event Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0770/1887] fs/ntfs3: Keep write operations atomic Greg Kroah-Hartman
` (229 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Steve French,
Paulo Alcantara (Red Hat), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.com>
[ Upstream commit 9502dd5c7029902f4a425bf959917a5a9e7c0e50 ]
After commit f7025d861694 ("smb: client: allocate crypto only for
primary server") and commit b0abcd65ec54 ("smb: client: fix UAF in
async decryption"), the channels started reusing AEAD TFM from primary
channel to perform synchronous decryption, but that can't done as
there could be multiple cifsd threads (one per channel) simultaneously
accessing it to perform decryption.
This fixes the following KASAN splat when running fstest generic/249
with 'vers=3.1.1,multichannel,max_channels=4,seal' against Windows
Server 2022:
BUG: KASAN: slab-use-after-free in gf128mul_4k_lle+0xba/0x110
Read of size 8 at addr ffff8881046c18a0 by task cifsd/986
CPU: 3 UID: 0 PID: 986 Comm: cifsd Not tainted 6.15.0-rc1 #1
PREEMPT(voluntary)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-3.fc41
04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x5d/0x80
print_report+0x156/0x528
? gf128mul_4k_lle+0xba/0x110
? __virt_addr_valid+0x145/0x300
? __phys_addr+0x46/0x90
? gf128mul_4k_lle+0xba/0x110
kasan_report+0xdf/0x1a0
? gf128mul_4k_lle+0xba/0x110
gf128mul_4k_lle+0xba/0x110
ghash_update+0x189/0x210
shash_ahash_update+0x295/0x370
? __pfx_shash_ahash_update+0x10/0x10
? __pfx_shash_ahash_update+0x10/0x10
? __pfx_extract_iter_to_sg+0x10/0x10
? ___kmalloc_large_node+0x10e/0x180
? __asan_memset+0x23/0x50
crypto_ahash_update+0x3c/0xc0
gcm_hash_assoc_remain_continue+0x93/0xc0
crypt_message+0xe09/0xec0 [cifs]
? __pfx_crypt_message+0x10/0x10 [cifs]
? _raw_spin_unlock+0x23/0x40
? __pfx_cifs_readv_from_socket+0x10/0x10 [cifs]
decrypt_raw_data+0x229/0x380 [cifs]
? __pfx_decrypt_raw_data+0x10/0x10 [cifs]
? __pfx_cifs_read_iter_from_socket+0x10/0x10 [cifs]
smb3_receive_transform+0x837/0xc80 [cifs]
? __pfx_smb3_receive_transform+0x10/0x10 [cifs]
? __pfx___might_resched+0x10/0x10
? __pfx_smb3_is_transform_hdr+0x10/0x10 [cifs]
cifs_demultiplex_thread+0x692/0x1570 [cifs]
? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs]
? rcu_is_watching+0x20/0x50
? rcu_lockdep_current_cpu_online+0x62/0xb0
? find_held_lock+0x32/0x90
? kvm_sched_clock_read+0x11/0x20
? local_clock_noinstr+0xd/0xd0
? trace_irq_enable.constprop.0+0xa8/0xe0
? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs]
kthread+0x1fe/0x380
? kthread+0x10f/0x380
? __pfx_kthread+0x10/0x10
? local_clock_noinstr+0xd/0xd0
? ret_from_fork+0x1b/0x60
? local_clock+0x15/0x30
? lock_release+0x29b/0x390
? rcu_is_watching+0x20/0x50
? __pfx_kthread+0x10/0x10
ret_from_fork+0x31/0x60
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Tested-by: David Howells <dhowells@redhat.com>
Reported-by: Steve French <stfrench@microsoft.com>
Closes: https://lore.kernel.org/r/CAH2r5mu6Yc0-RJXM3kFyBYUB09XmXBrNodOiCVR4EDrmxq5Szg@mail.gmail.com
Fixes: f7025d861694 ("smb: client: allocate crypto only for primary server")
Fixes: b0abcd65ec54 ("smb: client: fix UAF in async decryption")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 3278591b3647b..ef61a60a082ef 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4781,9 +4781,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
return rc;
}
} else {
- if (unlikely(!server->secmech.dec))
- return -EIO;
-
+ rc = smb3_crypto_aead_allocate(server);
+ if (unlikely(rc))
+ return rc;
tfm = server->secmech.dec;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0770/1887] fs/ntfs3: Keep write operations atomic
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (768 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0769/1887] smb: client: fix UAF in decryption with multichannel Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0771/1887] bpf: Fix kmemleak warning for percpu hashmap Greg Kroah-Hartman
` (228 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5d0bdc98770e6c55a0fd,
Lizhi Xu, Konstantin Komarov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <lizhi.xu@windriver.com>
[ Upstream commit 285cec318bf5a7a6c8ba999b2b6ec96f9a20590f ]
syzbot reported a NULL pointer dereference in __generic_file_write_iter. [1]
Before the write operation is completed, the user executes ioctl[2] to clear
the compress flag of the file, which causes the is_compressed() judgment to
return 0, further causing the program to enter the wrong process and call the
wrong ops ntfs_aops_cmpr, which triggers the null pointer dereference of
write_begin.
Use inode lock to synchronize ioctl and write to avoid this case.
[1]
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Mem abort info:
ESR = 0x0000000086000006
EC = 0x21: IABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x06: level 2 translation fault
user pgtable: 4k pages, 48-bit VAs, pgdp=000000011896d000
[0000000000000000] pgd=0800000118b44403, p4d=0800000118b44403, pud=0800000117517403, pmd=0000000000000000
Internal error: Oops: 0000000086000006 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 UID: 0 PID: 6427 Comm: syz-executor347 Not tainted 6.13.0-rc3-syzkaller-g573067a5a685 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : 0x0
lr : generic_perform_write+0x29c/0x868 mm/filemap.c:4055
sp : ffff80009d4978a0
x29: ffff80009d4979c0 x28: dfff800000000000 x27: ffff80009d497bc8
x26: 0000000000000000 x25: ffff80009d497960 x24: ffff80008ba71c68
x23: 0000000000000000 x22: ffff0000c655dac0 x21: 0000000000001000
x20: 000000000000000c x19: 1ffff00013a92f2c x18: ffff0000e183aa1c
x17: 0004060000000014 x16: ffff800083275834 x15: 0000000000000001
x14: 0000000000000000 x13: 0000000000000001 x12: ffff0000c655dac0
x11: 0000000000ff0100 x10: 0000000000ff0100 x9 : 0000000000000000
x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000
x5 : ffff80009d497980 x4 : ffff80009d497960 x3 : 0000000000001000
x2 : 0000000000000000 x1 : ffff0000e183a928 x0 : ffff0000d60b0fc0
Call trace:
0x0 (P)
__generic_file_write_iter+0xfc/0x204 mm/filemap.c:4156
ntfs_file_write_iter+0x54c/0x630 fs/ntfs3/file.c:1267
new_sync_write fs/read_write.c:586 [inline]
vfs_write+0x920/0xcf4 fs/read_write.c:679
ksys_write+0x15c/0x26c fs/read_write.c:731
__do_sys_write fs/read_write.c:742 [inline]
__se_sys_write fs/read_write.c:739 [inline]
__arm64_sys_write+0x7c/0x90 fs/read_write.c:739
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744
el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762
[2]
ioctl$FS_IOC_SETFLAGS(r0, 0x40086602, &(0x7f00000000c0)=0x20)
Reported-by: syzbot+5d0bdc98770e6c55a0fd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5d0bdc98770e6c55a0fd
Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/file.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index f2d1df2c988a9..b825862d74f95 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -1049,25 +1049,28 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
ssize_t ret;
struct ntfs_inode *ni = ntfs_i(inode);
+ if (!inode_trylock(inode)) {
+ if (iocb->ki_flags & IOCB_NOWAIT)
+ return -EAGAIN;
+ inode_lock(inode);
+ }
+
if (is_encrypted(ni)) {
ntfs_inode_warn(inode, "encrypted i/o not supported");
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out;
}
if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
ntfs_inode_warn(inode, "direct i/o + compressed not supported");
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out;
}
if (is_dedup(ni)) {
ntfs_inode_warn(inode, "write into deduplicated not supported");
- return -EOPNOTSUPP;
- }
-
- if (!inode_trylock(inode)) {
- if (iocb->ki_flags & IOCB_NOWAIT)
- return -EAGAIN;
- inode_lock(inode);
+ ret = -EOPNOTSUPP;
+ goto out;
}
ret = generic_write_checks(iocb, from);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0771/1887] bpf: Fix kmemleak warning for percpu hashmap
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (769 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0770/1887] fs/ntfs3: Keep write operations atomic Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0772/1887] spi: fsl-qspi: use devm function instead of driver remove Greg Kroah-Hartman
` (227 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vlad Poenaru, Yonghong Song,
Martin KaFai Lau, Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yonghong Song <yonghong.song@linux.dev>
[ Upstream commit 11ba7ce076e5903e7bdc1fd1498979c331b3c286 ]
Vlad Poenaru reported the following kmemleak issue:
unreferenced object 0x606fd7c44ac8 (size 32):
backtrace (crc 0):
pcpu_alloc_noprof+0x730/0xeb0
bpf_map_alloc_percpu+0x69/0xc0
prealloc_init+0x9d/0x1b0
htab_map_alloc+0x363/0x510
map_create+0x215/0x3a0
__sys_bpf+0x16b/0x3e0
__x64_sys_bpf+0x18/0x20
do_syscall_64+0x7b/0x150
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Further investigation shows the reason is due to not 8-byte aligned
store of percpu pointer in htab_elem_set_ptr():
*(void __percpu **)(l->key + key_size) = pptr;
Note that the whole htab_elem alignment is 8 (for x86_64). If the key_size
is 4, that means pptr is stored in a location which is 4 byte aligned but
not 8 byte aligned. In mm/kmemleak.c, scan_block() scans the memory based
on 8 byte stride, so it won't detect above pptr, hence reporting the memory
leak.
In htab_map_alloc(), we already have
htab->elem_size = sizeof(struct htab_elem) +
round_up(htab->map.key_size, 8);
if (percpu)
htab->elem_size += sizeof(void *);
else
htab->elem_size += round_up(htab->map.value_size, 8);
So storing pptr with 8-byte alignment won't cause any problem and can fix
kmemleak too.
The issue can be reproduced with bpf selftest as well:
1. Enable CONFIG_DEBUG_KMEMLEAK config
2. Add a getchar() before skel destroy in test_hash_map() in prog_tests/for_each.c.
The purpose is to keep map available so kmemleak can be detected.
3. run './test_progs -t for_each/hash_map &' and a kmemleak should be reported.
Reported-by: Vlad Poenaru <thevlad@meta.com>
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20250224175514.2207227-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 56d2879c64699..36c44451b0911 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -197,12 +197,12 @@ static bool htab_is_percpu(const struct bpf_htab *htab)
static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size,
void __percpu *pptr)
{
- *(void __percpu **)(l->key + key_size) = pptr;
+ *(void __percpu **)(l->key + roundup(key_size, 8)) = pptr;
}
static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size)
{
- return *(void __percpu **)(l->key + key_size);
+ return *(void __percpu **)(l->key + roundup(key_size, 8));
}
static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0772/1887] spi: fsl-qspi: use devm function instead of driver remove
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (770 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0771/1887] bpf: Fix kmemleak warning for percpu hashmap Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0773/1887] drm/amdkfd: debugfs hang_hws skip GPU with MES Greg Kroah-Hartman
` (226 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kevin Hao, Han Xu, Frank Li,
Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Xu <han.xu@nxp.com>
[ Upstream commit 40369bfe717e96e26650eeecfa5a6363563df6e4 ]
Driver use devm APIs to manage clk/irq/resources and register the spi
controller, but the legacy remove function will be called first during
device detach and trigger kernel panic. Drop the remove function and use
devm_add_action_or_reset() for driver cleanup to ensure the release
sequence.
Trigger kernel panic on i.MX8MQ by
echo 30bb0000.spi >/sys/bus/platform/drivers/fsl-quadspi/unbind
Cc: stable@vger.kernel.org
Fixes: 8fcb830a00f0 ("spi: spi-fsl-qspi: use devm_spi_register_controller")
Reported-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Han Xu <han.xu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20250326224152.2147099-1-han.xu@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-fsl-qspi.c | 42 +++++++++++++++++---------------------
1 file changed, 19 insertions(+), 23 deletions(-)
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index aee9993fe09db..665ce836c72f6 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -840,6 +840,19 @@ static const struct spi_controller_mem_ops fsl_qspi_mem_ops = {
.get_name = fsl_qspi_get_name,
};
+static void fsl_qspi_cleanup(void *data)
+{
+ struct fsl_qspi *q = data;
+
+ /* disable the hardware */
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
+
+ fsl_qspi_clk_disable_unprep(q);
+
+ mutex_destroy(&q->lock);
+}
+
static int fsl_qspi_probe(struct platform_device *pdev)
{
struct spi_controller *ctlr;
@@ -849,7 +862,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct fsl_qspi *q;
int ret;
- ctlr = spi_alloc_master(&pdev->dev, sizeof(*q));
+ ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*q));
if (!ctlr)
return -ENOMEM;
@@ -930,40 +943,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ctlr->dev.of_node = np;
+ ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q);
+ if (ret)
+ goto err_put_ctrl;
+
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
- goto err_destroy_mutex;
+ goto err_put_ctrl;
return 0;
-err_destroy_mutex:
- mutex_destroy(&q->lock);
-
err_disable_clk:
fsl_qspi_clk_disable_unprep(q);
err_put_ctrl:
- spi_controller_put(ctlr);
-
dev_err(dev, "Freescale QuadSPI probe failed\n");
return ret;
}
-static int fsl_qspi_remove(struct platform_device *pdev)
-{
- struct fsl_qspi *q = platform_get_drvdata(pdev);
-
- /* disable the hardware */
- qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
- qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
-
- fsl_qspi_clk_disable_unprep(q);
-
- mutex_destroy(&q->lock);
-
- return 0;
-}
-
static int fsl_qspi_suspend(struct device *dev)
{
return 0;
@@ -1001,7 +998,6 @@ static struct platform_driver fsl_qspi_driver = {
.pm = &fsl_qspi_pm_ops,
},
.probe = fsl_qspi_probe,
- .remove = fsl_qspi_remove,
};
module_platform_driver(fsl_qspi_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0773/1887] drm/amdkfd: debugfs hang_hws skip GPU with MES
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (771 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0772/1887] spi: fsl-qspi: use devm function instead of driver remove Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0774/1887] btrfs: harden block_group::bg_list against list_del() races Greg Kroah-Hartman
` (225 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Philip Yang, Kent Russell,
Felix Kuehling, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <Philip.Yang@amd.com>
[ Upstream commit fe9d0061c413f8fb8c529b18b592b04170850ded ]
debugfs hang_hws is used by GPU reset test with HWS, for MES this crash
the kernel with NULL pointer access because dqm->packet_mgr is not setup
for MES path.
Skip GPU with MES for now, MES hang_hws debugfs interface will be
supported later.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Kent Russell <kent.russell@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index e2c055abfea97..a4eadd6416f86 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -1177,6 +1177,11 @@ int kfd_debugfs_hang_hws(struct kfd_dev *dev)
return -EINVAL;
}
+ if (dev->shared_resources.enable_mes) {
+ dev_err(dev->adev->dev, "Inducing MES hang is not supported\n");
+ return -EINVAL;
+ }
+
return dqm_debugfs_hang_hws(dev->dqm);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0774/1887] btrfs: harden block_group::bg_list against list_del() races
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (772 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0773/1887] drm/amdkfd: debugfs hang_hws skip GPU with MES Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0775/1887] sfc: fix NULL dereferences in ef100_process_design_param() Greg Kroah-Hartman
` (224 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
Boris Burkov, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <boris@bur.io>
[ Upstream commit 7511e29cf1355b2c47d0effb39e463119913e2f6 ]
As far as I can tell, these calls of list_del_init() on bg_list cannot
run concurrently with btrfs_mark_bg_unused() or btrfs_mark_bg_to_reclaim(),
as they are in transaction error paths and situations where the block
group is readonly.
However, if there is any chance at all of racing with mark_bg_unused(),
or a different future user of bg_list, better to be safe than sorry.
Otherwise we risk the following interleaving (bg_list refcount in parens)
T1 (some random op) T2 (btrfs_mark_bg_unused)
!list_empty(&bg->bg_list); (1)
list_del_init(&bg->bg_list); (1)
list_move_tail (1)
btrfs_put_block_group (0)
btrfs_delete_unused_bgs
bg = list_first_entry
list_del_init(&bg->bg_list);
btrfs_put_block_group(bg); (-1)
Ultimately, this results in a broken ref count that hits zero one deref
early and the real final deref underflows the refcount, resulting in a WARNING.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/extent-tree.c | 8 ++++++++
fs/btrfs/transaction.c | 12 ++++++++++++
2 files changed, 20 insertions(+)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a09ac37f7cf48..3ecb3d0018a18 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2834,7 +2834,15 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
block_group->length,
&trimmed);
+ /*
+ * Not strictly necessary to lock, as the block_group should be
+ * read-only from btrfs_delete_unused_bgs().
+ */
+ ASSERT(block_group->ro);
+ spin_lock(&fs_info->unused_bgs_lock);
list_del_init(&block_group->bg_list);
+ spin_unlock(&fs_info->unused_bgs_lock);
+
btrfs_unfreeze_block_group(block_group);
btrfs_put_block_group(block_group);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index af7b5aae842a8..6b9a41c939d28 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -148,7 +148,13 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
cache = list_first_entry(&transaction->deleted_bgs,
struct btrfs_block_group,
bg_list);
+ /*
+ * Not strictly necessary to lock, as no other task will be using a
+ * block_group on the deleted_bgs list during a transaction abort.
+ */
+ spin_lock(&transaction->fs_info->unused_bgs_lock);
list_del_init(&cache->bg_list);
+ spin_unlock(&transaction->fs_info->unused_bgs_lock);
btrfs_unfreeze_block_group(cache);
btrfs_put_block_group(cache);
}
@@ -2104,7 +2110,13 @@ static void btrfs_cleanup_pending_block_groups(struct btrfs_trans_handle *trans)
list_for_each_entry_safe(block_group, tmp, &trans->new_bgs, bg_list) {
btrfs_delayed_refs_rsv_release(fs_info, 1);
+ /*
+ * Not strictly necessary to lock, as no other task will be using a
+ * block_group on the new_bgs list during a transaction abort.
+ */
+ spin_lock(&fs_info->unused_bgs_lock);
list_del_init(&block_group->bg_list);
+ spin_unlock(&fs_info->unused_bgs_lock);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0775/1887] sfc: fix NULL dereferences in ef100_process_design_param()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (773 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0774/1887] btrfs: harden block_group::bg_list against list_del() races Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0776/1887] scsi: mpi3mr: Synchronous access b/w reset and tm thread for reply queue Greg Kroah-Hartman
` (223 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyungwook Boo, Edward Cree,
Michal Swiatkowski, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Cree <ecree.xilinx@gmail.com>
[ Upstream commit 8241ecec1cdc6699ae197d52d58e76bddd995fa5 ]
Since cited commit, ef100_probe_main() and hence also
ef100_check_design_params() run before efx->net_dev is created;
consequently, we cannot netif_set_tso_max_size() or _segs() at this
point.
Move those netif calls to ef100_probe_netdev(), and also replace
netif_err within the design params code with pci_err.
Reported-by: Kyungwook Boo <bookyungwook@gmail.com>
Fixes: 98ff4c7c8ac7 ("sfc: Separate netdev probe/remove from PCI probe/remove")
Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Link: https://patch.msgid.link/20250401225439.2401047-1-edward.cree@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/sfc/ef100_netdev.c | 6 ++--
drivers/net/ethernet/sfc/ef100_nic.c | 47 +++++++++++--------------
2 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
index c6b9ba6803c8d..258e31ef7f2ce 100644
--- a/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -354,6 +354,7 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
{
struct efx_nic *efx = &probe_data->efx;
struct efx_probe_data **probe_ptr;
+ struct ef100_nic_data *nic_data;
struct net_device *net_dev;
int rc;
@@ -379,8 +380,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
net_dev->hw_enc_features |= efx->type->offload_features;
net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
- netif_set_tso_max_segs(net_dev,
- ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT);
+ nic_data = efx->nic_data;
+ netif_set_tso_max_size(efx->net_dev, nic_data->tso_max_payload_len);
+ netif_set_tso_max_segs(efx->net_dev, nic_data->tso_max_payload_num_segs);
efx->mdio.dev = net_dev;
rc = efx_ef100_init_datapath_caps(efx);
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index fa1f7039a8e28..5bf264414b9e0 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -866,8 +866,7 @@ static int ef100_process_design_param(struct efx_nic *efx,
case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS:
/* We always put HDR_NUM_SEGS=1 in our TSO descriptors */
if (!reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "TSO_MAX_HDR_NUM_SEGS < 1\n");
+ pci_err(efx->pci_dev, "TSO_MAX_HDR_NUM_SEGS < 1\n");
return -EOPNOTSUPP;
}
return 0;
@@ -880,32 +879,28 @@ static int ef100_process_design_param(struct efx_nic *efx,
*/
if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE ||
EFX_MIN_DMAQ_SIZE % (u32)reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "%s size granularity is %llu, can't guarantee safety\n",
- reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
- reader->value);
+ pci_err(efx->pci_dev,
+ "%s size granularity is %llu, can't guarantee safety\n",
+ reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
+ reader->value);
return -EOPNOTSUPP;
}
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN:
nic_data->tso_max_payload_len = min_t(u64, reader->value,
GSO_LEGACY_MAX_SIZE);
- netif_set_tso_max_size(efx->net_dev,
- nic_data->tso_max_payload_len);
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS:
nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff);
- netif_set_tso_max_segs(efx->net_dev,
- nic_data->tso_max_payload_num_segs);
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES:
nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff);
return 0;
case ESE_EF100_DP_GZ_COMPAT:
if (reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
- reader->value);
+ pci_err(efx->pci_dev,
+ "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
+ reader->value);
return -EOPNOTSUPP;
}
return 0;
@@ -925,10 +920,10 @@ static int ef100_process_design_param(struct efx_nic *efx,
* So the value of this shouldn't matter.
*/
if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT)
- netif_dbg(efx, probe, efx->net_dev,
- "NIC has other than default VI_STRIDES (mask "
- "%#llx), early probing might use wrong one\n",
- reader->value);
+ pci_dbg(efx->pci_dev,
+ "NIC has other than default VI_STRIDES (mask "
+ "%#llx), early probing might use wrong one\n",
+ reader->value);
return 0;
case ESE_EF100_DP_GZ_RX_MAX_RUNT:
/* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't
@@ -940,9 +935,9 @@ static int ef100_process_design_param(struct efx_nic *efx,
/* Host interface says "Drivers should ignore design parameters
* that they do not recognise."
*/
- netif_dbg(efx, probe, efx->net_dev,
- "Ignoring unrecognised design parameter %u\n",
- reader->type);
+ pci_dbg(efx->pci_dev,
+ "Ignoring unrecognised design parameter %u\n",
+ reader->type);
return 0;
}
}
@@ -978,13 +973,13 @@ static int ef100_check_design_params(struct efx_nic *efx)
*/
if (reader.state != EF100_TLV_TYPE) {
if (reader.state == EF100_TLV_TYPE_CONT)
- netif_err(efx, probe, efx->net_dev,
- "truncated design parameter (incomplete type %u)\n",
- reader.type);
+ pci_err(efx->pci_dev,
+ "truncated design parameter (incomplete type %u)\n",
+ reader.type);
else
- netif_err(efx, probe, efx->net_dev,
- "truncated design parameter %u\n",
- reader.type);
+ pci_err(efx->pci_dev,
+ "truncated design parameter %u\n",
+ reader.type);
rc = -EIO;
}
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0776/1887] scsi: mpi3mr: Synchronous access b/w reset and tm thread for reply queue
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (774 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0775/1887] sfc: fix NULL dereferences in ef100_process_design_param() Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0777/1887] um: fix time-travel syscall scheduling hack Greg Kroah-Hartman
` (222 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sumit Saxena, Ranjan Kumar,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <ranjan.kumar@broadcom.com>
[ Upstream commit f195fc060c738d303a21fae146dbf85e1595fb4c ]
When the task management thread processes reply queues while the reset
thread resets them, the task management thread accesses an invalid queue ID
(0xFFFF), set by the reset thread, which points to unallocated memory,
causing a crash.
Add flag 'io_admin_reset_sync' to synchronize access between the reset,
I/O, and admin threads. Before a reset, the reset handler sets this flag to
block I/O and admin processing threads. If any thread bypasses the initial
check, the reset thread waits up to 10 seconds for processing to finish. If
the wait exceeds 10 seconds, the controller is marked as unrecoverable.
Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
Link: https://lore.kernel.org/r/20250129100850.25430-4-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpi3mr/mpi3mr.h | 2 +
drivers/scsi/mpi3mr/mpi3mr_fw.c | 67 +++++++++++++++++++++++++++++++--
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 982629a0ec803..422cb50b3577e 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -969,6 +969,7 @@ struct scmd_priv {
* @ts_update_counter: Timestamp update counter
* @reset_in_progress: Reset in progress flag
* @unrecoverable: Controller unrecoverable flag
+ * @io_admin_reset_sync: Manage state of I/O ops during an admin reset process
* @prev_reset_result: Result of previous reset
* @reset_mutex: Controller reset mutex
* @reset_waitq: Controller reset wait queue
@@ -1141,6 +1142,7 @@ struct mpi3mr_ioc {
u32 ts_update_counter;
u8 reset_in_progress;
u8 unrecoverable;
+ u8 io_admin_reset_sync;
int prev_reset_result;
struct mutex reset_mutex;
wait_queue_head_t reset_waitq;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index c14bee07f8c10..8cdbb593c8e59 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -17,7 +17,7 @@ static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc,
struct mpi3_ioc_facts_data *facts_data);
static void mpi3mr_pel_wait_complete(struct mpi3mr_ioc *mrioc,
struct mpi3mr_drv_cmd *drv_cmd);
-
+static int mpi3mr_check_op_admin_proc(struct mpi3mr_ioc *mrioc);
static int poll_queues;
module_param(poll_queues, int, 0444);
MODULE_PARM_DESC(poll_queues, "Number of queues for io_uring poll mode. (Range 1 - 126)");
@@ -449,7 +449,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
}
do {
- if (mrioc->unrecoverable)
+ if (mrioc->unrecoverable || mrioc->io_admin_reset_sync)
break;
mrioc->admin_req_ci = le16_to_cpu(reply_desc->request_queue_ci);
@@ -538,7 +538,7 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
}
do {
- if (mrioc->unrecoverable)
+ if (mrioc->unrecoverable || mrioc->io_admin_reset_sync)
break;
req_q_idx = le16_to_cpu(reply_desc->request_queue_id) - 1;
@@ -3990,6 +3990,7 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume)
goto out_failed_noretry;
}
+ mrioc->io_admin_reset_sync = 0;
if (is_resume) {
dprint_reset(mrioc, "setting up single ISR\n");
retval = mpi3mr_setup_isr(mrioc, 1);
@@ -4824,6 +4825,55 @@ void mpi3mr_pel_get_seqnum_complete(struct mpi3mr_ioc *mrioc,
drv_cmd->retry_count = 0;
}
+/**
+ * mpi3mr_check_op_admin_proc -
+ * @mrioc: Adapter instance reference
+ *
+ * Check if any of the operation reply queues
+ * or the admin reply queue are currently in use.
+ * If any queue is in use, this function waits for
+ * a maximum of 10 seconds for them to become available.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+static int mpi3mr_check_op_admin_proc(struct mpi3mr_ioc *mrioc)
+{
+
+ u16 timeout = 10 * 10;
+ u16 elapsed_time = 0;
+ bool op_admin_in_use = false;
+
+ do {
+ op_admin_in_use = false;
+
+ /* Check admin_reply queue first to exit early */
+ if (atomic_read(&mrioc->admin_reply_q_in_use) == 1)
+ op_admin_in_use = true;
+ else {
+ /* Check op_reply queues */
+ int i;
+
+ for (i = 0; i < mrioc->num_queues; i++) {
+ if (atomic_read(&mrioc->op_reply_qinfo[i].in_use) == 1) {
+ op_admin_in_use = true;
+ break;
+ }
+ }
+ }
+
+ if (!op_admin_in_use)
+ break;
+
+ msleep(100);
+
+ } while (++elapsed_time < timeout);
+
+ if (op_admin_in_use)
+ return 1;
+
+ return 0;
+}
+
/**
* mpi3mr_soft_reset_handler - Reset the controller
* @mrioc: Adapter instance reference
@@ -4897,6 +4947,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
mpi3mr_wait_for_host_io(mrioc, MPI3MR_RESET_HOST_IOWAIT_TIMEOUT);
mpi3mr_ioc_disable_intr(mrioc);
+ mrioc->io_admin_reset_sync = 1;
if (snapdump) {
mpi3mr_set_diagsave(mrioc);
@@ -4920,6 +4971,16 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
ioc_err(mrioc, "Failed to issue soft reset to the ioc\n");
goto out;
}
+
+ retval = mpi3mr_check_op_admin_proc(mrioc);
+ if (retval) {
+ ioc_err(mrioc, "Soft reset failed due to an Admin or I/O queue polling\n"
+ "thread still processing replies even after a 10 second\n"
+ "timeout. Marking the controller as unrecoverable!\n");
+
+ goto out;
+ }
+
if (mrioc->num_io_throttle_group !=
mrioc->facts.max_io_throttle_group) {
ioc_err(mrioc,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0777/1887] um: fix time-travel syscall scheduling hack
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (775 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0776/1887] scsi: mpi3mr: Synchronous access b/w reset and tm thread for reply queue Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0778/1887] ksmbd: Fix UAF in __close_file_table_ids Greg Kroah-Hartman
` (221 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Berg, Richard Weinberger,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 381d2f95c8aa575d5d42bf1fe0ea9a70c4bec0cf ]
The schedule() call there really never did anything at
least since the introduction of the EEVDF scheduler,
but now I found a case where we permanently hang in a
loop of -ERESTARTNOINTR (due to locking.) Work around
it by making any syscalls with error return take time
(and then schedule after) so we cannot hang in such a
loop forever.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Stable-dep-of: 887c5c12e80c ("um: work around sched_yield not yielding in time-travel mode")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/um/kernel/skas/syscall.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 9ee19e566da3b..b09e85279d2b8 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -12,23 +12,13 @@
#include <sysdep/syscalls.h>
#include <linux/time-internal.h>
#include <asm/unistd.h>
+#include <asm/delay.h>
void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
int syscall;
- /*
- * If we have infinite CPU resources, then make every syscall also a
- * preemption point, since we don't have any other preemption in this
- * case, and kernel threads would basically never run until userspace
- * went to sleep, even if said userspace interacts with the kernel in
- * various ways.
- */
- if (time_travel_mode == TT_MODE_INFCPU ||
- time_travel_mode == TT_MODE_EXTERNAL)
- schedule();
-
/* Initialize the syscall number and default return value. */
UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
@@ -41,9 +31,25 @@ void handle_syscall(struct uml_pt_regs *r)
goto out;
syscall = UPT_SYSCALL_NR(r);
- if (syscall >= 0 && syscall < __NR_syscalls)
- PT_REGS_SET_SYSCALL_RETURN(regs,
- EXECUTE_SYSCALL(syscall, regs));
+ if (syscall >= 0 && syscall < __NR_syscalls) {
+ unsigned long ret = EXECUTE_SYSCALL(syscall, regs);
+
+ PT_REGS_SET_SYSCALL_RETURN(regs, ret);
+
+ /*
+ * An error value here can be some form of -ERESTARTSYS
+ * and then we'd just loop. Make any error syscalls take
+ * some time, so that it won't just loop if something is
+ * not ready, and hopefully other things will make some
+ * progress.
+ */
+ if (IS_ERR_VALUE(ret) &&
+ (time_travel_mode == TT_MODE_INFCPU ||
+ time_travel_mode == TT_MODE_EXTERNAL)) {
+ um_udelay(1);
+ schedule();
+ }
+ }
out:
syscall_trace_leave(regs);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0778/1887] ksmbd: Fix UAF in __close_file_table_ids
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (776 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0777/1887] um: fix time-travel syscall scheduling hack Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0779/1887] ksmbd: prevent rename with empty string Greg Kroah-Hartman
` (220 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Heelan, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Heelan <seanheelan@gmail.com>
[ Upstream commit 36991c1ccde2d5a521577c448ffe07fcccfe104d ]
A use-after-free is possible if one thread destroys the file
via __ksmbd_close_fd while another thread holds a reference to
it. The existing checks on fp->refcount are not sufficient to
prevent this.
The fix takes ft->lock around the section which removes the
file from the file table. This prevents two threads acquiring the
same file pointer via __close_file_table_ids, as well as the other
functions which retrieve a file from the IDR and which already use
this same lock.
Cc: stable@vger.kernel.org
Signed-off-by: Sean Heelan <seanheelan@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/vfs_cache.c | 37 +++++++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 9eb9f892ac2b5..4b35e4f960694 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -648,21 +648,46 @@ __close_file_table_ids(struct ksmbd_file_table *ft,
bool (*skip)(struct ksmbd_tree_connect *tcon,
struct ksmbd_file *fp))
{
- unsigned int id;
- struct ksmbd_file *fp;
- int num = 0;
+ struct ksmbd_file *fp;
+ unsigned int id = 0;
+ int num = 0;
+
+ while (1) {
+ write_lock(&ft->lock);
+ fp = idr_get_next(ft->idr, &id);
+ if (!fp) {
+ write_unlock(&ft->lock);
+ break;
+ }
- idr_for_each_entry(ft->idr, fp, id) {
- if (skip(tcon, fp))
+ if (skip(tcon, fp)) {
+ id++;
+ write_unlock(&ft->lock);
continue;
+ }
set_close_state_blocked_works(fp);
- if (!atomic_dec_and_test(&fp->refcount))
+ if (!atomic_dec_and_test(&fp->refcount)) {
+ id++;
+ write_unlock(&ft->lock);
continue;
+ }
+
+ idr_remove(ft->idr, fp->volatile_id);
+ fp->volatile_id = KSMBD_NO_FID;
+ write_unlock(&ft->lock);
+
+ write_lock(&fp->f_ci->m_lock);
+ list_del_init(&fp->node);
+ write_unlock(&fp->f_ci->m_lock);
+
__ksmbd_close_fd(ft, fp);
+
num++;
+ id++;
}
+
return num;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0779/1887] ksmbd: prevent rename with empty string
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (777 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0778/1887] ksmbd: Fix UAF in __close_file_table_ids Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0780/1887] KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception Greg Kroah-Hartman
` (219 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 53e3e5babc0963a92d856a5ec0ce92c59f54bc12 ]
Client can send empty newname string to ksmbd server.
It will cause a kernel oops from d_alloc.
This patch return the error when attempting to rename
a file or directory with an empty new name string.
Cc: stable@vger.kernel.org
Reported-by: Norbert Szetei <norbert@doyensec.com>
Tested-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 561581c0f26db..16477ad9dde8d 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -665,6 +665,11 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
return name;
}
+ if (*name == '\0') {
+ kfree(name);
+ return ERR_PTR(-EINVAL);
+ }
+
ksmbd_conv_path_to_unix(name);
ksmbd_strip_last_slash(name);
return name;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0780/1887] KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (778 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0779/1887] ksmbd: prevent rename with empty string Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0781/1887] scsi: ufs: exynos: Disable iocc if dma-coherent property isnt set Greg Kroah-Hartman
` (218 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson, Mikhail Lobanov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <m.lobanov@rosa.ru>
[ Upstream commit a2620f8932fa9fdabc3d78ed6efb004ca409019f ]
Previously, commit ed129ec9057f ("KVM: x86: forcibly leave nested mode
on vCPU reset") addressed an issue where a triple fault occurring in
nested mode could lead to use-after-free scenarios. However, the commit
did not handle the analogous situation for System Management Mode (SMM).
This omission results in triggering a WARN when KVM forces a vCPU INIT
after SHUTDOWN interception while the vCPU is in SMM. This situation was
reprodused using Syzkaller by:
1) Creating a KVM VM and vCPU
2) Sending a KVM_SMI ioctl to explicitly enter SMM
3) Executing invalid instructions causing consecutive exceptions and
eventually a triple fault
The issue manifests as follows:
WARNING: CPU: 0 PID: 25506 at arch/x86/kvm/x86.c:12112
kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112
Modules linked in:
CPU: 0 PID: 25506 Comm: syz-executor.0 Not tainted
6.1.130-syzkaller-00157-g164fe5dde9b6 #0
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS 1.12.0-1 04/01/2014
RIP: 0010:kvm_vcpu_reset+0x1d2/0x1530 arch/x86/kvm/x86.c:12112
Call Trace:
<TASK>
shutdown_interception+0x66/0xb0 arch/x86/kvm/svm/svm.c:2136
svm_invoke_exit_handler+0x110/0x530 arch/x86/kvm/svm/svm.c:3395
svm_handle_exit+0x424/0x920 arch/x86/kvm/svm/svm.c:3457
vcpu_enter_guest arch/x86/kvm/x86.c:10959 [inline]
vcpu_run+0x2c43/0x5a90 arch/x86/kvm/x86.c:11062
kvm_arch_vcpu_ioctl_run+0x50f/0x1cf0 arch/x86/kvm/x86.c:11283
kvm_vcpu_ioctl+0x570/0xf00 arch/x86/kvm/../../../virt/kvm/kvm_main.c:4122
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:870 [inline]
__se_sys_ioctl fs/ioctl.c:856 [inline]
__x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:856
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Architecturally, INIT is blocked when the CPU is in SMM, hence KVM's WARN()
in kvm_vcpu_reset() to guard against KVM bugs, e.g. to detect improper
emulation of INIT. SHUTDOWN on SVM is a weird edge case where KVM needs to
do _something_ sane with the VMCB, since it's technically undefined, and
INIT is the least awful choice given KVM's ABI.
So, double down on stuffing INIT on SHUTDOWN, and force the vCPU out of
SMM to avoid any weirdness (and the WARN).
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: ed129ec9057f ("KVM: x86: forcibly leave nested mode on vCPU reset")
Cc: stable@vger.kernel.org
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Mikhail Lobanov <m.lobanov@rosa.ru>
Link: https://lore.kernel.org/r/20250414171207.155121-1-m.lobanov@rosa.ru
[sean: massage changelog, make it clear this isn't architectural behavior]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/svm.c | 2 ++
arch/x86/kvm/x86.c | 5 ++---
arch/x86/kvm/x86.h | 1 +
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 488e954a4483a..d2a84597711ed 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -2130,6 +2130,8 @@ static int shutdown_interception(struct kvm_vcpu *vcpu)
* in response to shutdown.
*/
clear_page(svm->vmcb);
+ if (is_smm(vcpu))
+ kvm_smm_changed(vcpu, false);
kvm_vcpu_reset(vcpu, true);
kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ffbf532baf7cd..daa52c04630ac 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5165,8 +5165,6 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
memset(&events->reserved, 0, sizeof(events->reserved));
}
-static void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm);
-
static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events)
{
@@ -8676,7 +8674,7 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
static int complete_emulated_mmio(struct kvm_vcpu *vcpu);
static int complete_emulated_pio(struct kvm_vcpu *vcpu);
-static void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm)
+void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm)
{
trace_kvm_smm_transition(vcpu->vcpu_id, vcpu->arch.smbase, entering_smm);
@@ -8698,6 +8696,7 @@ static void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm)
kvm_mmu_reset_context(vcpu);
}
+EXPORT_SYMBOL_GPL(kvm_smm_changed);
static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7,
unsigned long *db)
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 9bb2f237b0fc0..2f21f99d9ce26 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -82,6 +82,7 @@ static inline unsigned int __shrink_ple_window(unsigned int val,
void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu);
int kvm_check_nested_events(struct kvm_vcpu *vcpu);
+void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm);
static inline bool kvm_is_exception_pending(struct kvm_vcpu *vcpu)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0781/1887] scsi: ufs: exynos: Disable iocc if dma-coherent property isnt set
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (779 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0780/1887] KVM: SVM: Forcibly leave SMM mode on SHUTDOWN interception Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0782/1887] net: mctp: Dont access ifa_index when missing Greg Kroah-Hartman
` (217 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bart Van Assche, Peter Griffin,
Chanho Park, Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin <peter.griffin@linaro.org>
[ Upstream commit f92bb7436802f8eb7ee72dc911a33c8897fde366 ]
If dma-coherent property isn't set then descriptors are non-cacheable
and the iocc shareability bits should be disabled. Without this UFS can
end up in an incompatible configuration and suffer from random cache
related stability issues.
Suggested-by: Bart Van Assche <bvanassche@acm.org>
Fixes: cc52e15397cc ("scsi: ufs: ufs-exynos: Support ExynosAuto v9 UFS")
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Link: https://lore.kernel.org/r/20250319-exynos-ufs-stability-fixes-v2-3-96722cc2ba1b@linaro.org
Cc: Chanho Park <chanho61.park@samsung.com>
Cc: stable@vger.kernel.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/host/ufs-exynos.c | 17 +++++++++++++----
drivers/ufs/host/ufs-exynos.h | 3 ++-
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
index 17db3f8c8c516..6bb8da1436867 100644
--- a/drivers/ufs/host/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -200,8 +200,8 @@ static int exynosauto_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
/* IO Coherency setting */
if (ufs->sysreg) {
return regmap_update_bits(ufs->sysreg,
- ufs->shareability_reg_offset,
- UFS_SHARABLE, UFS_SHARABLE);
+ ufs->iocc_offset,
+ UFS_SHARABLE, ufs->iocc_val);
}
attr->tx_dif_p_nsec = 3200000;
@@ -1102,12 +1102,21 @@ static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs)
ufs->sysreg = NULL;
else {
if (of_property_read_u32_index(np, "samsung,sysreg", 1,
- &ufs->shareability_reg_offset)) {
+ &ufs->iocc_offset)) {
dev_warn(dev, "can't get an offset from sysreg. Set to default value\n");
- ufs->shareability_reg_offset = UFS_SHAREABILITY_OFFSET;
+ ufs->iocc_offset = UFS_SHAREABILITY_OFFSET;
}
}
+ /*
+ * no 'dma-coherent' property means the descriptors are
+ * non-cacheable so iocc shareability should be disabled.
+ */
+ if (of_dma_is_coherent(dev->of_node))
+ ufs->iocc_val = UFS_SHARABLE;
+ else
+ ufs->iocc_val = 0;
+
ufs->pclk_avail_min = PCLK_AVAIL_MIN;
ufs->pclk_avail_max = PCLK_AVAIL_MAX;
diff --git a/drivers/ufs/host/ufs-exynos.h b/drivers/ufs/host/ufs-exynos.h
index a4bd6646d7f13..65aa04d41c3eb 100644
--- a/drivers/ufs/host/ufs-exynos.h
+++ b/drivers/ufs/host/ufs-exynos.h
@@ -212,7 +212,8 @@ struct exynos_ufs {
ktime_t entry_hibern8_t;
const struct exynos_ufs_drv_data *drv_data;
struct regmap *sysreg;
- u32 shareability_reg_offset;
+ u32 iocc_offset;
+ u32 iocc_val;
u32 opts;
#define EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL BIT(0)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0782/1887] net: mctp: Dont access ifa_index when missing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (780 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0781/1887] scsi: ufs: exynos: Disable iocc if dma-coherent property isnt set Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:47 ` [PATCH 6.1 0783/1887] kasan: use unchecked __memset internally Greg Kroah-Hartman
` (216 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e76d52dadc089b9d197f,
syzbot+1065a199625a388fce60, Matt Johnston, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Johnston <matt@codeconstruct.com.au>
[ Upstream commit f11cf946c0a92c560a890d68e4775723353599e1 ]
In mctp_dump_addrinfo, ifa_index can be used to filter interfaces, but
only when the struct ifaddrmsg is provided. Otherwise it will be
comparing to uninitialised memory - reproducible in the syzkaller case from
dhcpd, or busybox "ip addr show".
The kernel MCTP implementation has always filtered by ifa_index, so
existing userspace programs expecting to dump MCTP addresses must
already be passing a valid ifa_index value (either 0 or a real index).
BUG: KMSAN: uninit-value in mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128
mctp_dump_addrinfo+0x208/0xac0 net/mctp/device.c:128
rtnl_dump_all+0x3ec/0x5b0 net/core/rtnetlink.c:4380
rtnl_dumpit+0xd5/0x2f0 net/core/rtnetlink.c:6824
netlink_dump+0x97b/0x1690 net/netlink/af_netlink.c:2309
Fixes: 583be982d934 ("mctp: Add device handling and netlink interface")
Reported-by: syzbot+e76d52dadc089b9d197f@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/68135815.050a0220.3a872c.000e.GAE@google.com/
Reported-by: syzbot+1065a199625a388fce60@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/681357d6.050a0220.14dd7d.000d.GAE@google.com/
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
Link: https://patch.msgid.link/20250508-mctp-addr-dump-v2-1-c8a53fd2dd66@codeconstruct.com.au
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mctp/device.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/net/mctp/device.c b/net/mctp/device.c
index 47407c07afc27..365726010340d 100644
--- a/net/mctp/device.c
+++ b/net/mctp/device.c
@@ -120,12 +120,19 @@ static int mctp_dump_addrinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
struct ifaddrmsg *hdr;
struct mctp_dev *mdev;
- int ifindex;
+ int ifindex = 0;
int idx = 0, rc;
- hdr = nlmsg_data(cb->nlh);
- // filter by ifindex if requested
- ifindex = hdr->ifa_index;
+ /* Filter by ifindex if a header is provided */
+ if (cb->nlh->nlmsg_len >= nlmsg_msg_size(sizeof(*hdr))) {
+ hdr = nlmsg_data(cb->nlh);
+ ifindex = hdr->ifa_index;
+ } else {
+ if (cb->strict_check) {
+ NL_SET_ERR_MSG(cb->extack, "mctp: Invalid header for addr dump request");
+ return -EINVAL;
+ }
+ }
rcu_read_lock();
for (; mcb->h < NETDEV_HASHENTRIES; mcb->h++, mcb->idx = 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0783/1887] kasan: use unchecked __memset internally
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (781 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0782/1887] net: mctp: Dont access ifa_index when missing Greg Kroah-Hartman
@ 2026-10-28 16:47 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0784/1887] kasan: avoid sleepable page allocation from atomic context Greg Kroah-Hartman
` (215 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrey Konovalov, Marco Elver,
Alexander Potapenko, Andrey Ryabinin, Dmitry Vyukov,
kernel test robot, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Konovalov <andreyknvl@google.com>
[ Upstream commit 01a5ad81637672940844052404678678a0ec8854 ]
KASAN code is supposed to use the unchecked __memset implementation when
accessing its metadata.
Change uses of memset to __memset in mm/kasan/.
Link: https://lkml.kernel.org/r/6f621966c6f52241b5aaa7220c348be90c075371.1696605143.git.andreyknvl@google.com
Fixes: 59e6e098d1c1 ("kasan: introduce kasan_complete_mode_report_info")
Fixes: 3c5c3cfb9ef4 ("kasan: support backing vmalloc space with real shadow memory")
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Reviewed-by: Marco Elver <elver@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: kernel test robot <lkp@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: b6ea95a34cbd ("kasan: avoid sleepable page allocation from atomic context")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kasan/report.c | 4 ++--
mm/kasan/shadow.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 240560ec8d99a..a69d0812a9220 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -477,7 +477,7 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty
start_report(&flags, true);
- memset(&info, 0, sizeof(info));
+ __memset(&info, 0, sizeof(info));
info.type = type;
info.access_addr = ptr;
info.access_size = 0;
@@ -512,7 +512,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
start_report(&irq_flags, true);
- memset(&info, 0, sizeof(info));
+ __memset(&info, 0, sizeof(info));
info.type = KASAN_REPORT_ACCESS;
info.access_addr = ptr;
info.access_size = size;
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index ecb7acb3897cd..578877ed49564 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -272,7 +272,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
if (!page)
return -ENOMEM;
- memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
+ __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
spin_lock(&init_mm.page_table_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0784/1887] kasan: avoid sleepable page allocation from atomic context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (782 preceding siblings ...)
2026-10-28 16:47 ` [PATCH 6.1 0783/1887] kasan: use unchecked __memset internally Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0785/1887] clk: sunxi-ng: h616: Reparent CPU clock during frequency changes Greg Kroah-Hartman
` (214 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Gordeev, Andrey Ryabinin,
Harry Yoo, Daniel Axtens, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Gordeev <agordeev@linux.ibm.com>
[ Upstream commit b6ea95a34cbd014ab6ade4248107b86b0aaf2d6c ]
apply_to_pte_range() enters the lazy MMU mode and then invokes
kasan_populate_vmalloc_pte() callback on each page table walk iteration.
However, the callback can go into sleep when trying to allocate a single
page, e.g. if an architecutre disables preemption on lazy MMU mode enter.
On s390 if make arch_enter_lazy_mmu_mode() -> preempt_enable() and
arch_leave_lazy_mmu_mode() -> preempt_disable(), such crash occurs:
[ 0.663336] BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:321
[ 0.663348] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2, name: kthreadd
[ 0.663358] preempt_count: 1, expected: 0
[ 0.663366] RCU nest depth: 0, expected: 0
[ 0.663375] no locks held by kthreadd/2.
[ 0.663383] Preemption disabled at:
[ 0.663386] [<0002f3284cbb4eda>] apply_to_pte_range+0xfa/0x4a0
[ 0.663405] CPU: 0 UID: 0 PID: 2 Comm: kthreadd Not tainted 6.15.0-rc5-gcc-kasan-00043-gd76bb1ebb558-dirty #162 PREEMPT
[ 0.663408] Hardware name: IBM 3931 A01 701 (KVM/Linux)
[ 0.663409] Call Trace:
[ 0.663410] [<0002f3284c385f58>] dump_stack_lvl+0xe8/0x140
[ 0.663413] [<0002f3284c507b9e>] __might_resched+0x66e/0x700
[ 0.663415] [<0002f3284cc4f6c0>] __alloc_frozen_pages_noprof+0x370/0x4b0
[ 0.663419] [<0002f3284ccc73c0>] alloc_pages_mpol+0x1a0/0x4a0
[ 0.663421] [<0002f3284ccc8518>] alloc_frozen_pages_noprof+0x88/0xc0
[ 0.663424] [<0002f3284ccc8572>] alloc_pages_noprof+0x22/0x120
[ 0.663427] [<0002f3284cc341ac>] get_free_pages_noprof+0x2c/0xc0
[ 0.663429] [<0002f3284cceba70>] kasan_populate_vmalloc_pte+0x50/0x120
[ 0.663433] [<0002f3284cbb4ef8>] apply_to_pte_range+0x118/0x4a0
[ 0.663435] [<0002f3284cbc7c14>] apply_to_pmd_range+0x194/0x3e0
[ 0.663437] [<0002f3284cbc99be>] __apply_to_page_range+0x2fe/0x7a0
[ 0.663440] [<0002f3284cbc9e88>] apply_to_page_range+0x28/0x40
[ 0.663442] [<0002f3284ccebf12>] kasan_populate_vmalloc+0x82/0xa0
[ 0.663445] [<0002f3284cc1578c>] alloc_vmap_area+0x34c/0xc10
[ 0.663448] [<0002f3284cc1c2a6>] __get_vm_area_node+0x186/0x2a0
[ 0.663451] [<0002f3284cc1e696>] __vmalloc_node_range_noprof+0x116/0x310
[ 0.663454] [<0002f3284cc1d950>] __vmalloc_node_noprof+0xd0/0x110
[ 0.663457] [<0002f3284c454b88>] alloc_thread_stack_node+0xf8/0x330
[ 0.663460] [<0002f3284c458d56>] dup_task_struct+0x66/0x4d0
[ 0.663463] [<0002f3284c45be90>] copy_process+0x280/0x4b90
[ 0.663465] [<0002f3284c460940>] kernel_clone+0xd0/0x4b0
[ 0.663467] [<0002f3284c46115e>] kernel_thread+0xbe/0xe0
[ 0.663469] [<0002f3284c4e440e>] kthreadd+0x50e/0x7f0
[ 0.663472] [<0002f3284c38c04a>] __ret_from_fork+0x8a/0xf0
[ 0.663475] [<0002f3284ed57ff2>] ret_from_fork+0xa/0x38
Instead of allocating single pages per-PTE, bulk-allocate the shadow
memory prior to applying kasan_populate_vmalloc_pte() callback on a page
range.
Link: https://lkml.kernel.org/r/c61d3560297c93ed044f0b1af085610353a06a58.1747316918.git.agordeev@linux.ibm.com
Fixes: 3c5c3cfb9ef4 ("kasan: support backing vmalloc space with real shadow memory")
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Suggested-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Reviewed-by: Harry Yoo <harry.yoo@oracle.com>
Cc: Daniel Axtens <dja@axtens.net>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/kasan/shadow.c | 92 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 78 insertions(+), 14 deletions(-)
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 578877ed49564..9dc041fd4f0f7 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -259,33 +259,99 @@ void __init __weak kasan_populate_early_vm_area_shadow(void *start,
{
}
+struct vmalloc_populate_data {
+ unsigned long start;
+ struct page **pages;
+};
+
static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
- void *unused)
+ void *_data)
{
- unsigned long page;
+ struct vmalloc_populate_data *data = _data;
+ struct page *page;
pte_t pte;
+ int index;
if (likely(!pte_none(*ptep)))
return 0;
- page = __get_free_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
-
- __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
- pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
+ index = PFN_DOWN(addr - data->start);
+ page = data->pages[index];
+ __memset(page_to_virt(page), KASAN_VMALLOC_INVALID, PAGE_SIZE);
+ pte = pfn_pte(page_to_pfn(page), PAGE_KERNEL);
spin_lock(&init_mm.page_table_lock);
if (likely(pte_none(*ptep))) {
set_pte_at(&init_mm, addr, ptep, pte);
- page = 0;
+ data->pages[index] = NULL;
}
spin_unlock(&init_mm.page_table_lock);
- if (page)
- free_page(page);
+
+ return 0;
+}
+
+static void ___free_pages_bulk(struct page **pages, int nr_pages)
+{
+ int i;
+
+ for (i = 0; i < nr_pages; i++) {
+ if (pages[i]) {
+ __free_pages(pages[i], 0);
+ pages[i] = NULL;
+ }
+ }
+}
+
+static int ___alloc_pages_bulk(struct page **pages, int nr_pages)
+{
+ unsigned long nr_populated, nr_total = nr_pages;
+ struct page **page_array = pages;
+
+ while (nr_pages) {
+ nr_populated = alloc_pages_bulk_array(GFP_KERNEL, nr_pages, pages);
+ if (!nr_populated) {
+ ___free_pages_bulk(page_array, nr_total - nr_pages);
+ return -ENOMEM;
+ }
+ pages += nr_populated;
+ nr_pages -= nr_populated;
+ }
+
return 0;
}
+static int __kasan_populate_vmalloc(unsigned long start, unsigned long end)
+{
+ unsigned long nr_pages, nr_total = PFN_UP(end - start);
+ struct vmalloc_populate_data data;
+ int ret = 0;
+
+ data.pages = (struct page **)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+ if (!data.pages)
+ return -ENOMEM;
+
+ while (nr_total) {
+ nr_pages = min(nr_total, PAGE_SIZE / sizeof(data.pages[0]));
+ ret = ___alloc_pages_bulk(data.pages, nr_pages);
+ if (ret)
+ break;
+
+ data.start = start;
+ ret = apply_to_page_range(&init_mm, start, nr_pages * PAGE_SIZE,
+ kasan_populate_vmalloc_pte, &data);
+ ___free_pages_bulk(data.pages, nr_pages);
+ if (ret)
+ break;
+
+ start += nr_pages * PAGE_SIZE;
+ nr_total -= nr_pages;
+ }
+
+ free_page((unsigned long)data.pages);
+
+ return ret;
+}
+
int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
{
unsigned long shadow_start, shadow_end;
@@ -315,9 +381,7 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
shadow_start = PAGE_ALIGN_DOWN(shadow_start);
shadow_end = PAGE_ALIGN(shadow_end);
- ret = apply_to_page_range(&init_mm, shadow_start,
- shadow_end - shadow_start,
- kasan_populate_vmalloc_pte, NULL);
+ ret = __kasan_populate_vmalloc(shadow_start, shadow_end);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0785/1887] clk: sunxi-ng: h616: Reparent CPU clock during frequency changes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (783 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0784/1887] kasan: avoid sleepable page allocation from atomic context Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0786/1887] clk: sunxi-ng: h616: Reparent GPU " Greg Kroah-Hartman
` (213 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andre Przywara, Evgeny Boger,
Chen-Yu Tsai, Stephen Boyd, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara <andre.przywara@arm.com>
[ Upstream commit 087b4083d3f9d202266debc6b684b0662c96f51b ]
The H616 user manual recommends to re-parent the CPU clock during
frequency changes of the PLL, and recommends PLL_PERI0(1X), which runs
at 600 MHz. Also it asks to disable and then re-enable the PLL lock bit,
after the factor changes have been applied.
Add clock notifiers for the PLL and the CPU mux clock, using the existing
notifier callbacks, and tell them to use mux 4 (the PLL_PERI0(1X) source),
and bit 29 (the LOCK_ENABLE) bit. The existing code already follows the
correct algorithms.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Link: https://lore.kernel.org/r/20241025105620.1891596-1-andre.przywara@arm.com
Tested-by: Evgeny Boger <boger@wirenboard.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Stable-dep-of: eb963d7948ce ("clk: sunxi-ng: h616: Reparent GPU clock during frequency changes")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 28 ++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
index 21e918582aa56..e52f94822aff8 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
@@ -1090,11 +1090,24 @@ static const u32 usb2_clk_regs[] = {
SUN50I_H616_USB3_CLK_REG,
};
+static struct ccu_mux_nb sun50i_h616_cpu_nb = {
+ .common = &cpux_clk.common,
+ .cm = &cpux_clk.mux,
+ .delay_us = 1, /* manual doesn't really say */
+ .bypass_index = 4, /* PLL_PERI0@600MHz, as recommended by manual */
+};
+
+static struct ccu_pll_nb sun50i_h616_pll_cpu_nb = {
+ .common = &pll_cpux_clk.common,
+ .enable = BIT(29), /* LOCK_ENABLE */
+ .lock = BIT(28),
+};
+
static int sun50i_h616_ccu_probe(struct platform_device *pdev)
{
void __iomem *reg;
u32 val;
- int i;
+ int ret, i;
reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg))
@@ -1147,7 +1160,18 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
val |= BIT(24);
writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
- return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
+ ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
+ if (ret)
+ return ret;
+
+ /* Reparent CPU during CPU PLL rate changes */
+ ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+ &sun50i_h616_cpu_nb);
+
+ /* Re-lock the CPU PLL after any rate changes */
+ ccu_pll_notifier_register(&sun50i_h616_pll_cpu_nb);
+
+ return 0;
}
static const struct of_device_id sun50i_h616_ccu_ids[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0786/1887] clk: sunxi-ng: h616: Reparent GPU clock during frequency changes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (784 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0785/1887] clk: sunxi-ng: h616: Reparent CPU clock during frequency changes Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0787/1887] dmaengine: ti: k3-udma-glue: Drop skip_fdq argument from k3_udma_glue_reset_rx_chn Greg Kroah-Hartman
` (212 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Philippe Simons, Andre Przywara,
Jernej Skrabec, Chen-Yu Tsai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philippe Simons <simons.philippe@gmail.com>
[ Upstream commit eb963d7948ce6571939c6875424b557b25f16610 ]
The H616 manual does not state that the GPU PLL supports
dynamic frequency configuration, so we must take extra care when changing
the frequency. Currently any attempt to do device DVFS on the GPU lead
to panfrost various ooops, and GPU hangs.
The manual describes the algorithm for changing the PLL
frequency, which the CPU PLL notifier code already support, so we reuse
that to reparent the GPU clock to GPU1 clock during frequency
changes.
Signed-off-by: Philippe Simons <simons.philippe@gmail.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Link: https://patch.msgid.link/20250220113808.1122414-2-simons.philippe@gmail.com
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 36 +++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
index e52f94822aff8..5831bcfbe5002 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
@@ -318,10 +318,16 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu0_clk, "gpu0", gpu0_parents, 0x670,
24, 1, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
+
+/*
+ * This clk is needed as a temporary fall back during GPU PLL freq changes.
+ * Set CLK_IS_CRITICAL flag to prevent from being disabled.
+ */
+#define SUN50I_H616_GPU_CLK1_REG 0x674
static SUNXI_CCU_M_WITH_GATE(gpu1_clk, "gpu1", "pll-periph0-2x", 0x674,
0, 2, /* M */
BIT(31),/* gate */
- 0);
+ CLK_IS_CRITICAL);
static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
0x67c, BIT(0), 0);
@@ -1103,6 +1109,19 @@ static struct ccu_pll_nb sun50i_h616_pll_cpu_nb = {
.lock = BIT(28),
};
+static struct ccu_mux_nb sun50i_h616_gpu_nb = {
+ .common = &gpu0_clk.common,
+ .cm = &gpu0_clk.mux,
+ .delay_us = 1, /* manual doesn't really say */
+ .bypass_index = 1, /* GPU_CLK1@400MHz */
+};
+
+static struct ccu_pll_nb sun50i_h616_pll_gpu_nb = {
+ .common = &pll_gpu_clk.common,
+ .enable = BIT(29), /* LOCK_ENABLE */
+ .lock = BIT(28),
+};
+
static int sun50i_h616_ccu_probe(struct platform_device *pdev)
{
void __iomem *reg;
@@ -1151,6 +1170,14 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
val &= ~(GENMASK(21, 16) | BIT(0));
writel(val | (11 << 16) | BIT(0), reg + SUN50I_H616_PLL_AUDIO_REG);
+ /*
+ * Set the input-divider for the gpu1 clock to 3, to reach a safe 400 MHz.
+ */
+ val = readl(reg + SUN50I_H616_GPU_CLK1_REG);
+ val &= ~GENMASK(1, 0);
+ val |= 2;
+ writel(val, reg + SUN50I_H616_GPU_CLK1_REG);
+
/*
* First clock parent (osc32K) is unusable for CEC. But since there
* is no good way to force parent switch (both run with same frequency),
@@ -1171,6 +1198,13 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
/* Re-lock the CPU PLL after any rate changes */
ccu_pll_notifier_register(&sun50i_h616_pll_cpu_nb);
+ /* Reparent GPU during GPU PLL rate changes */
+ ccu_mux_notifier_register(pll_gpu_clk.common.hw.clk,
+ &sun50i_h616_gpu_nb);
+
+ /* Re-lock the GPU PLL after any rate changes */
+ ccu_pll_notifier_register(&sun50i_h616_pll_gpu_nb);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0787/1887] dmaengine: ti: k3-udma-glue: Drop skip_fdq argument from k3_udma_glue_reset_rx_chn
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (785 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0786/1887] clk: sunxi-ng: h616: Reparent GPU " Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0788/1887] wifi: iwlwifi: dbg-tlv: fix DRAM data init Greg Kroah-Hartman
` (211 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Roger Quadros, Jakub Kicinski,
Peter Ujfalusi, Vinod Koul, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros <rogerq@kernel.org>
[ Upstream commit 0da30874729baeb01889b0eca16cfda122687503 ]
The user of k3_udma_glue_reset_rx_chn() e.g. ti_am65_cpsw_nuss can
run on multiple platforms having different DMA architectures.
On some platforms there can be one FDQ for all flows in the RX channel
while for others there is a separate FDQ for each flow in the RX channel.
So far we have been relying on the skip_fdq argument of
k3_udma_glue_reset_rx_chn().
Instead of relying on the user to provide this information, infer it
based on DMA architecture during k3_udma_glue_request_rx_chn() and save it
in an internal flag 'single_fdq'. Use that flag at
k3_udma_glue_reset_rx_chn() to deicide if the FDQ needs
to be cleared for every flow or just for flow 0.
Fixes the below issue on ti_am65_cpsw_nuss driver on AM62-SK.
> ip link set eth1 down
> ip link set eth0 down
> ethtool -L eth0 rx 8
> ip link set eth0 up
> modprobe -r ti_am65_cpsw_nuss
[ 103.045726] ------------[ cut here ]------------
[ 103.050505] k3_knav_desc_pool size 512000 != avail 64000
[ 103.050703] WARNING: CPU: 1 PID: 450 at drivers/net/ethernet/ti/k3-cppi-desc-pool.c:33 k3_cppi_desc_pool_destroy+0xa0/0xa8 [k3_cppi_desc_pool]
[ 103.068810] Modules linked in: ti_am65_cpsw_nuss(-) k3_cppi_desc_pool snd_soc_hdmi_codec crct10dif_ce snd_soc_simple_card snd_soc_simple_card_utils display_connector rtc_ti_k3 k3_j72xx_bandgap tidss drm_client_lib snd_soc_davinci_mcas
p drm_dma_helper tps6598x phylink snd_soc_ti_udma rti_wdt drm_display_helper snd_soc_tlv320aic3x_i2c typec at24 phy_gmii_sel snd_soc_ti_edma snd_soc_tlv320aic3x sii902x snd_soc_ti_sdma sa2ul omap_mailbox drm_kms_helper authenc cfg80211 r
fkill fuse drm drm_panel_orientation_quirks backlight ip_tables x_tables ipv6 [last unloaded: k3_cppi_desc_pool]
[ 103.119950] CPU: 1 UID: 0 PID: 450 Comm: modprobe Not tainted 6.13.0-rc7-00001-g9c5e3435fa66 #1011
[ 103.119968] Hardware name: Texas Instruments AM625 SK (DT)
[ 103.119974] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 103.119983] pc : k3_cppi_desc_pool_destroy+0xa0/0xa8 [k3_cppi_desc_pool]
[ 103.148007] lr : k3_cppi_desc_pool_destroy+0xa0/0xa8 [k3_cppi_desc_pool]
[ 103.154709] sp : ffff8000826ebbc0
[ 103.158015] x29: ffff8000826ebbc0 x28: ffff0000090b6300 x27: 0000000000000000
[ 103.165145] x26: 0000000000000000 x25: 0000000000000000 x24: ffff0000019df6b0
[ 103.172271] x23: ffff0000019df6b8 x22: ffff0000019df410 x21: ffff8000826ebc88
[ 103.179397] x20: 000000000007d000 x19: ffff00000a3b3000 x18: 0000000000000000
[ 103.186522] x17: 0000000000000000 x16: 0000000000000000 x15: 000001e8c35e1cde
[ 103.193647] x14: 0000000000000396 x13: 000000000000035c x12: 0000000000000000
[ 103.200772] x11: 000000000000003a x10: 00000000000009c0 x9 : ffff8000826eba20
[ 103.207897] x8 : ffff0000090b6d20 x7 : ffff00007728c180 x6 : ffff00007728c100
[ 103.215022] x5 : 0000000000000001 x4 : ffff000000508a50 x3 : ffff7ffff6146000
[ 103.222147] x2 : 0000000000000000 x1 : e300b4173ee6b200 x0 : 0000000000000000
[ 103.229274] Call trace:
[ 103.231714] k3_cppi_desc_pool_destroy+0xa0/0xa8 [k3_cppi_desc_pool] (P)
[ 103.238408] am65_cpsw_nuss_free_rx_chns+0x28/0x4c [ti_am65_cpsw_nuss]
[ 103.244942] devm_action_release+0x14/0x20
[ 103.249040] release_nodes+0x3c/0x68
[ 103.252610] devres_release_all+0x8c/0xdc
[ 103.256614] device_unbind_cleanup+0x18/0x60
[ 103.260876] device_release_driver_internal+0xf8/0x178
[ 103.266004] driver_detach+0x50/0x9c
[ 103.269571] bus_remove_driver+0x6c/0xbc
[ 103.273485] driver_unregister+0x30/0x60
[ 103.277401] platform_driver_unregister+0x14/0x20
[ 103.282096] am65_cpsw_nuss_driver_exit+0x18/0xff4 [ti_am65_cpsw_nuss]
[ 103.288620] __arm64_sys_delete_module+0x17c/0x25c
[ 103.293404] invoke_syscall+0x44/0x100
[ 103.297149] el0_svc_common.constprop.0+0xc0/0xe0
[ 103.301845] do_el0_svc+0x1c/0x28
[ 103.305155] el0_svc+0x28/0x98
[ 103.308207] el0t_64_sync_handler+0xc8/0xcc
[ 103.312384] el0t_64_sync+0x198/0x19c
[ 103.316040] ---[ end trace 0000000000000000 ]---
Signed-off-by: Roger Quadros <rogerq@kernel.org>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
Link: https://lore.kernel.org/r/20250224-k3-udma-glue-single-fdq-v2-1-cbe7621f2507@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/ti/k3-udma-glue.c | 15 +++++++++++----
drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 ++--
include/linux/dma/k3-udma-glue.h | 3 +--
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index a739e60b07648..2d18463a6a582 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -83,6 +83,7 @@ struct k3_udma_glue_rx_channel {
struct k3_udma_glue_rx_flow *flows;
u32 flow_num;
u32 flows_ready;
+ bool single_fdq; /* one FDQ for all flows */
};
static void k3_udma_chan_dev_release(struct device *dev)
@@ -896,10 +897,13 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
ep_cfg = rx_chn->common.ep_config;
- if (xudma_is_pktdma(rx_chn->common.udmax))
+ if (xudma_is_pktdma(rx_chn->common.udmax)) {
rx_chn->udma_rchan_id = ep_cfg->mapped_channel_id;
- else
+ rx_chn->single_fdq = false;
+ } else {
rx_chn->udma_rchan_id = -1;
+ rx_chn->single_fdq = true;
+ }
/* request and cfg UDMAP RX channel */
rx_chn->udma_rchanx = xudma_rchan_get(rx_chn->common.udmax,
@@ -1060,6 +1064,9 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
rx_chn->common.chan_dev.dma_coherent = true;
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
DMA_BIT_MASK(48));
+ rx_chn->single_fdq = false;
+ } else {
+ rx_chn->single_fdq = true;
}
ret = k3_udma_glue_allocate_rx_flows(rx_chn, cfg);
@@ -1321,7 +1328,7 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_tdown_rx_chn);
void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_num, void *data,
- void (*cleanup)(void *data, dma_addr_t desc_dma), bool skip_fdq)
+ void (*cleanup)(void *data, dma_addr_t desc_dma))
{
struct k3_udma_glue_rx_flow *flow = &rx_chn->flows[flow_num];
struct device *dev = rx_chn->common.dev;
@@ -1333,7 +1340,7 @@ void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn,
dev_dbg(dev, "RX reset flow %u occ_rx %u\n", flow_num, occ_rx);
/* Skip RX FDQ in case one FDQ is used for the set of flows */
- if (skip_fdq)
+ if (rx_chn->single_fdq && flow_num)
goto do_reset;
/*
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 450fd4fb58d1a..a4184e9dddf15 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -514,7 +514,7 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)
for (i = 0; i < AM65_CPSW_MAX_RX_FLOWS; i++)
k3_udma_glue_reset_rx_chn(common->rx_chns.rx_chn, i,
&common->rx_chns,
- am65_cpsw_nuss_rx_cleanup, !!i);
+ am65_cpsw_nuss_rx_cleanup);
k3_udma_glue_disable_rx_chn(common->rx_chns.rx_chn);
@@ -2583,7 +2583,7 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common)
for (i = 0; i < AM65_CPSW_MAX_RX_FLOWS; i++)
k3_udma_glue_reset_rx_chn(rx_chan->rx_chn, i, rx_chan,
- am65_cpsw_nuss_rx_cleanup, !!i);
+ am65_cpsw_nuss_rx_cleanup);
k3_udma_glue_disable_rx_chn(rx_chan->rx_chn);
diff --git a/include/linux/dma/k3-udma-glue.h b/include/linux/dma/k3-udma-glue.h
index e443be4d3b4b7..a76f1c09a884a 100644
--- a/include/linux/dma/k3-udma-glue.h
+++ b/include/linux/dma/k3-udma-glue.h
@@ -130,8 +130,7 @@ void k3_udma_glue_rx_put_irq(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_num);
void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_num, void *data,
- void (*cleanup)(void *data, dma_addr_t desc_dma),
- bool skip_fdq);
+ void (*cleanup)(void *data, dma_addr_t desc_dma));
int k3_udma_glue_rx_flow_enable(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_idx);
int k3_udma_glue_rx_flow_disable(struct k3_udma_glue_rx_channel *rx_chn,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0788/1887] wifi: iwlwifi: dbg-tlv: fix DRAM data init
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (786 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0787/1887] dmaengine: ti: k3-udma-glue: Drop skip_fdq argument from k3_udma_glue_reset_rx_chn Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0789/1887] wifi: iwlwifi: fix debug actions order Greg Kroah-Hartman
` (210 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Berg, Gregory Greenman,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit c2a2f505e0bcb45052131d173504887041e1faae ]
Given the existing code in iwl_dbg_tlv_update_drams(), the
following can happen and cause firmware asserts, and even
the device to become unusable:
* We set the magic so the firmware will use the data;
* we try to fill multiple allocation IDs, with at least
one successful, but - crucially - one failing and thus
not touching the data;
* we don't clear the data since there was one success.
This doesn't seem like much of a problem just yet, however,
what happens now is that the allocation ID(s) that failed
are not initialized.
There are two additional things to know:
* we never free these allocations across FW restart or
interface down/up etc., in fact we never free them until
the driver is unbound from the device (e.g. unloaded)
* the firmware uses the DRAM info structure for real debug
data when it has used it completely
Given that, and the fact that we never initialize the data
on restart, we can be unlucky and end up with an allocation
that looks for the most part valid (valid ID, valid number
of buffers, etc.) but has bad sizes - causing the firmware
to throw an assert we can never recover from.
Fixing the code to have the entire buffers cleared (which
we should do so old debug data isn't sticking around) is a
bit more complex, so as a first step make the actual code
that fills the information more robust by clearing the
structure first, and filling the magic values only if it
actually succeeded for one, rather than doing it the other
way around.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230613155501.87cf5528f4bc.I26ac907a4162297808b33467fc7f5d8177474a34@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: eb29b4ffafb2 ("wifi: iwlwifi: fix debug actions order")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 677c9e0b46f10..b7165082bdd80 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/
#include <linux/firmware.h>
#include "iwl-drv.h"
@@ -797,8 +797,7 @@ static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt)
IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT))
return;
- dram_info->first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD);
- dram_info->second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD);
+ memset(dram_info, 0, sizeof(*dram_info));
for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1;
i <= IWL_FW_INI_ALLOCATION_ID_DBGC3; i++) {
@@ -811,11 +810,10 @@ static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt)
i, ret);
}
- if (dram_alloc)
- IWL_DEBUG_FW(fwrt, "block data after %08x\n",
- dram_info->first_word);
- else
- memset(frags->block, 0, sizeof(*dram_info));
+ if (dram_alloc) {
+ dram_info->first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD);
+ dram_info->second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD);
+ }
}
static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0789/1887] wifi: iwlwifi: fix debug actions order
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (787 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0788/1887] wifi: iwlwifi: dbg-tlv: fix DRAM data init Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0790/1887] virtio: break and reset virtio devices on device_shutdown() Greg Kroah-Hartman
` (209 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Berg, Miri Korenblit,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit eb29b4ffafb20281624dcd2cbb768d6f30edf600 ]
The order of actions taken for debug was implemented incorrectly.
Now we implemented the dump split and do the FW reset only in the
middle of the dump (rather than the FW killing itself on error.)
As a result, some of the actions taken when applying the config
will now crash the device, so we need to fix the order.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250308231427.6de7fa8e63ed.I40632c48e2a67a8aca05def572a934b88ce7934b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index b7165082bdd80..a14a4437a0940 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2018-2023 Intel Corporation
+ * Copyright (C) 2018-2025 Intel Corporation
*/
#include <linux/firmware.h>
#include "iwl-drv.h"
@@ -1361,15 +1361,15 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
switch (tp_id) {
case IWL_FW_INI_TIME_POINT_EARLY:
iwl_dbg_tlv_init_cfg(fwrt);
- iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_update_drams(fwrt);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ iwl_dbg_tlv_apply_config(fwrt, conf_list);
break;
case IWL_FW_INI_TIME_POINT_AFTER_ALIVE:
iwl_dbg_tlv_apply_buffers(fwrt);
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
- iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ iwl_dbg_tlv_apply_config(fwrt, conf_list);
break;
case IWL_FW_INI_TIME_POINT_PERIODIC:
iwl_dbg_tlv_set_periodic_trigs(fwrt);
@@ -1379,14 +1379,14 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
case IWL_FW_INI_TIME_POINT_MISSED_BEACONS:
case IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFICATION:
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
- iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data,
iwl_dbg_tlv_check_fw_pkt);
+ iwl_dbg_tlv_apply_config(fwrt, conf_list);
break;
default:
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
- iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ iwl_dbg_tlv_apply_config(fwrt, conf_list);
break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0790/1887] virtio: break and reset virtio devices on device_shutdown()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (788 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0789/1887] wifi: iwlwifi: fix debug actions order Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0791/1887] PCI: endpoint: pci-epf-test: Fix double free that causes kernel to oops Greg Kroah-Hartman
` (208 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Auger, Hongyu Ning, Eric Auger,
Jason Wang, Michael S. Tsirkin, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <mst@redhat.com>
[ Upstream commit 8bd2fa086a04886798b505f28db4002525895203 ]
Hongyu reported a hang on kexec in a VM. QEMU reported invalid memory
accesses during the hang.
Invalid read at addr 0x102877002, size 2, region '(null)', reason: rejected
Invalid write at addr 0x102877A44, size 2, region '(null)', reason: rejected
...
It was traced down to virtio-console. Kexec works fine if virtio-console
is not in use.
The issue is that virtio-console continues to write to the MMIO even after
underlying virtio-pci device is reset.
Additionally, Eric noticed that IOMMUs are reset before devices, if
devices are not reset on shutdown they continue to poke at guest memory
and get errors from the IOMMU. Some devices get wedged then.
The problem can be solved by breaking all virtio devices on virtio
bus shutdown, then resetting them.
Reported-by: Eric Auger <eauger@redhat.com>
Reported-by: Hongyu Ning <hongyu.ning@linux.intel.com>
Message-ID: <c1dbc7dbad9b445245d3348f19e6742b0be07347.1740094946.git.mst@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 1ef094427f299..0d3481250fb98 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -340,6 +340,34 @@ static void virtio_dev_remove(struct device *_d)
of_node_put(dev->dev.of_node);
}
+static void virtio_dev_shutdown(struct device *_d)
+{
+ struct virtio_device *dev = dev_to_virtio(_d);
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ /*
+ * Stop accesses to or from the device.
+ * We only need to do it if there's a driver - no accesses otherwise.
+ */
+ if (!drv)
+ return;
+
+ /*
+ * Some devices get wedged if you kick them after they are
+ * reset. Mark all vqs as broken to make sure we don't.
+ */
+ virtio_break_device(dev);
+ /*
+ * Guarantee that any callback will see vq->broken as true.
+ */
+ virtio_synchronize_cbs(dev);
+ /*
+ * As IOMMUs are reset on shutdown, this will block device access to memory.
+ * Some devices get wedged if this happens, so reset to make sure it does not.
+ */
+ dev->config->reset(dev);
+}
+
static struct bus_type virtio_bus = {
.name = "virtio",
.match = virtio_dev_match,
@@ -347,6 +375,7 @@ static struct bus_type virtio_bus = {
.uevent = virtio_uevent,
.probe = virtio_dev_probe,
.remove = virtio_dev_remove,
+ .shutdown = virtio_dev_shutdown,
};
int register_virtio_driver(struct virtio_driver *driver)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0791/1887] PCI: endpoint: pci-epf-test: Fix double free that causes kernel to oops
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (789 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0790/1887] virtio: break and reset virtio devices on device_shutdown() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0792/1887] spi-rockchip: Fix register out of bounds access Greg Kroah-Hartman
` (207 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Niklas Cassel, Manivannan Sadhasivam,
Christian Bruel, Krzysztof Wilczyński, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Bruel <christian.bruel@foss.st.com>
[ Upstream commit 934e9d137d937706004c325fa1474f9e3f1ba10a ]
Fix a kernel oops found while testing the stm32_pcie Endpoint driver
with handling of PERST# deassertion:
During EP initialization, pci_epf_test_alloc_space() allocates all BARs,
which are further freed if epc_set_bar() fails (for instance, due to no
free inbound window).
However, when pci_epc_set_bar() fails, the error path:
pci_epc_set_bar() ->
pci_epf_free_space()
does not clear the previous assignment to epf_test->reg[bar].
Then, if the host reboots, the PERST# deassertion restarts the BAR
allocation sequence with the same allocation failure (no free inbound
window), creating a double free situation since epf_test->reg[bar] was
deallocated and is still non-NULL.
Thus, make sure that pci_epf_alloc_space() and pci_epf_free_space()
invocations are symmetric, and as such, set epf_test->reg[bar] to NULL
when memory is freed.
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Christian Bruel <christian.bruel@foss.st.com>
Link: https://lore.kernel.org/r/20250124123043.96112-1-christian.bruel@foss.st.com
[kwilczynski: commit log]
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index fb47ce721e095..53f1236cd91d7 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -735,6 +735,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
epf_bar);
pci_epf_free_space(epf, epf_test->reg[bar], bar,
PRIMARY_INTERFACE);
+ epf_test->reg[bar] = NULL;
}
}
}
@@ -769,6 +770,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar,
PRIMARY_INTERFACE);
+ epf_test->reg[bar] = NULL;
dev_err(dev, "Failed to set BAR%d\n", bar);
if (bar == test_reg_bar)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0792/1887] spi-rockchip: Fix register out of bounds access
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (790 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0791/1887] PCI: endpoint: pci-epf-test: Fix double free that causes kernel to oops Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0793/1887] wifi: iwlwifi: dont warn when if there is a FW error Greg Kroah-Hartman
` (206 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luis de Arquer, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis de Arquer <luis.dearquer@inertim.com>
[ Upstream commit 7a874e8b54ea21094f7fd2d428b164394c6cb316 ]
Do not write native chip select stuff for GPIO chip selects.
GPIOs can be numbered much higher than native CS.
Also, it makes no sense.
Signed-off-by: Luis de Arquer <luis.dearquer@inertim.com>
Link: https://patch.msgid.link/365ccddfba110549202b3520f4401a6a936e82a8.camel@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-rockchip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index c38d515e4399e..ccf6025229735 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -541,7 +541,7 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
if (spi->mode & SPI_LSB_FIRST)
cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET;
- if (spi->mode & SPI_CS_HIGH)
+ if ((spi->mode & SPI_CS_HIGH) && !spi->cs_gpiod)
cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET;
if (xfer->rx_buf && xfer->tx_buf)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0793/1887] wifi: iwlwifi: dont warn when if there is a FW error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (791 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0792/1887] spi-rockchip: Fix register out of bounds access Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0794/1887] ice: fix Tx scheduler error handling in XDP callback Greg Kroah-Hartman
` (205 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miri Korenblit, Johannes Berg,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
[ Upstream commit c7f50d0433a016d43681592836a3d484817bfb34 ]
iwl_trans_reclaim is warning if it is called when the FW is not alive.
But if it is called when there is a pending restart, i.e. after a FW
error, there is no need to warn, instead - return silently.
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250308231427.ba3d90b22c25.I9332506af1997faefcf0bdb51d98d5e874051722@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index ad29663a356be..9380fdd707afe 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -1194,6 +1194,9 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
int ssn, struct sk_buff_head *skbs,
bool is_flush)
{
+ if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
+ return;
+
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0794/1887] ice: fix Tx scheduler error handling in XDP callback
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (792 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0793/1887] wifi: iwlwifi: dont warn when if there is a FW error Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0795/1887] coresight: holding cscfg_csdev_lock while removing cscfg from csdev Greg Kroah-Hartman
` (204 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dawid Osuchowski, Przemek Kitszel,
Jacob Keller, Michal Kubiak, Aleksandr Loktionov, Simon Horman,
Jesse Brandeburg, Tony Nguyen, Sasha Levin, Saritha Sanigani
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Kubiak <michal.kubiak@intel.com>
[ Upstream commit 0153f36041b8e52019ebfa8629c13bf8f9b0a951 ]
When the XDP program is loaded, the XDP callback adds new Tx queues.
This means that the callback must update the Tx scheduler with the new
queue number. In the event of a Tx scheduler failure, the XDP callback
should also fail and roll back any changes previously made for XDP
preparation.
The previous implementation had a bug that not all changes made by the
XDP callback were rolled back. This caused the crash with the following
call trace:
[ +9.549584] ice 0000:ca:00.0: Failed VSI LAN queue config for XDP, error: -5
[ +0.382335] Oops: general protection fault, probably for non-canonical address 0x50a2250a90495525: 0000 [#1] SMP NOPTI
[ +0.010710] CPU: 103 UID: 0 PID: 0 Comm: swapper/103 Not tainted 6.14.0-net-next-mar-31+ #14 PREEMPT(voluntary)
[ +0.010175] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0005.2202160810 02/16/2022
[ +0.010946] RIP: 0010:__ice_update_sample+0x39/0xe0 [ice]
[...]
[ +0.002715] Call Trace:
[ +0.002452] <IRQ>
[ +0.002021] ? __die_body.cold+0x19/0x29
[ +0.003922] ? die_addr+0x3c/0x60
[ +0.003319] ? exc_general_protection+0x17c/0x400
[ +0.004707] ? asm_exc_general_protection+0x26/0x30
[ +0.004879] ? __ice_update_sample+0x39/0xe0 [ice]
[ +0.004835] ice_napi_poll+0x665/0x680 [ice]
[ +0.004320] __napi_poll+0x28/0x190
[ +0.003500] net_rx_action+0x198/0x360
[ +0.003752] ? update_rq_clock+0x39/0x220
[ +0.004013] handle_softirqs+0xf1/0x340
[ +0.003840] ? sched_clock_cpu+0xf/0x1f0
[ +0.003925] __irq_exit_rcu+0xc2/0xe0
[ +0.003665] common_interrupt+0x85/0xa0
[ +0.003839] </IRQ>
[ +0.002098] <TASK>
[ +0.002106] asm_common_interrupt+0x26/0x40
[ +0.004184] RIP: 0010:cpuidle_enter_state+0xd3/0x690
Fix this by performing the missing unmapping of XDP queues from
q_vectors and setting the XDP rings pointer back to NULL after all those
queues are released.
Also, add an immediate exit from the XDP callback in case of ring
preparation failure.
Fixes: efc2214b6047 ("ice: Add support for XDP")
Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Jesse Brandeburg <jbrandeburg@cloudflare.com>
Tested-by: Saritha Sanigani <sarithax.sanigani@intel.com> (A Contingent Worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_main.c | 46 ++++++++++++++++-------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 75fede7d31749..8db6e47decdb9 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2642,6 +2642,27 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog)
bpf_prog_put(old_prog);
}
+/**
+ * ice_unmap_xdp_rings - Unmap XDP rings from interrupt vectors
+ * @vsi: the VSI with XDP rings being unmapped
+ */
+static void ice_unmap_xdp_rings(struct ice_vsi *vsi)
+{
+ int v_idx;
+
+ ice_for_each_q_vector(vsi, v_idx) {
+ struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
+ struct ice_tx_ring *ring;
+
+ ice_for_each_tx_ring(ring, q_vector->tx)
+ if (!ring->tx_buf || !ice_ring_is_xdp(ring))
+ break;
+
+ /* restore the value of last node prior to XDP setup */
+ q_vector->tx.tx_ring = ring;
+ }
+}
+
/**
* ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
* @vsi: VSI to bring up Tx rings used by XDP
@@ -2739,7 +2760,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
if (status) {
dev_err(dev, "Failed VSI LAN queue config for XDP, error: %d\n",
status);
- goto clear_xdp_rings;
+ goto unmap_xdp_rings;
}
/* assign the prog only when it's not already present on VSI;
@@ -2755,6 +2776,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
ice_vsi_assign_bpf_prog(vsi, prog);
return 0;
+unmap_xdp_rings:
+ ice_unmap_xdp_rings(vsi);
clear_xdp_rings:
ice_for_each_xdp_txq(vsi, i)
if (vsi->xdp_rings[i]) {
@@ -2772,6 +2795,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
devm_kfree(dev, vsi->xdp_rings);
vsi->xdp_rings = NULL;
+
return -ENOMEM;
}
@@ -2786,7 +2810,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi)
{
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
struct ice_pf *pf = vsi->back;
- int i, v_idx;
+ int i;
/* q_vectors are freed in reset path so there's no point in detaching
* rings; in case of rebuild being triggered not from reset bits
@@ -2796,17 +2820,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi)
if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
goto free_qmap;
- ice_for_each_q_vector(vsi, v_idx) {
- struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
- struct ice_tx_ring *ring;
-
- ice_for_each_tx_ring(ring, q_vector->tx)
- if (!ring->tx_buf || !ice_ring_is_xdp(ring))
- break;
-
- /* restore the value of last node prior to XDP setup */
- q_vector->tx.tx_ring = ring;
- }
+ ice_unmap_xdp_rings(vsi);
free_qmap:
mutex_lock(&pf->avail_q_mutex);
@@ -2943,10 +2957,13 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
xdp_ring_err = ice_vsi_determine_xdp_res(vsi);
if (xdp_ring_err) {
NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
+ goto resume_if;
} else {
xdp_ring_err = ice_prepare_xdp_rings(vsi, prog);
- if (xdp_ring_err)
+ if (xdp_ring_err) {
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
+ goto resume_if;
+ }
}
/* reallocate Rx queues that are used for zero-copy */
xdp_ring_err = ice_realloc_zc_buf(vsi, true);
@@ -2962,6 +2979,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed");
}
+resume_if:
if (if_running)
ret = ice_up(vsi);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0795/1887] coresight: holding cscfg_csdev_lock while removing cscfg from csdev
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (793 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0794/1887] ice: fix Tx scheduler error handling in XDP callback Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0796/1887] ublk: santizize the arguments from userspace when adding a device Greg Kroah-Hartman
` (203 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yeoreum Yun, Leo Yan,
Suzuki K Poulose, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeoreum Yun <yeoreum.yun@arm.com>
[ Upstream commit 53b9e2659719b04f5ba7593f2af0f2335f75e94a ]
There'll be possible race scenario for coresight config:
CPU0 CPU1
(perf enable) load module
cscfg_load_config_sets()
activate config. // sysfs
(sys_active_cnt == 1)
...
cscfg_csdev_enable_active_config()
lock(csdev->cscfg_csdev_lock)
deactivate config // sysfs
(sys_activec_cnt == 0)
cscfg_unload_config_sets()
<iterating config_csdev_list> cscfg_remove_owned_csdev_configs()
// here load config activate by CPU1
unlock(csdev->cscfg_csdev_lock)
iterating config_csdev_list could be raced with config_csdev_list's
entry delete.
To resolve this race , hold csdev->cscfg_csdev_lock() while
cscfg_remove_owned_csdev_configs()
Fixes: 02bd588e12df ("coresight: configuration: Update API to permit dynamic load/unload")
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250514161951.3427590-3-yeoreum.yun@arm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwtracing/coresight/coresight-syscfg.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 30a561d874819..55f36ed1af13c 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -395,6 +395,8 @@ static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, voi
if (list_empty(&csdev->config_csdev_list))
return;
+ guard(spinlock_irqsave)(&csdev->cscfg_csdev_lock);
+
list_for_each_entry_safe(config_csdev, tmp, &csdev->config_csdev_list, node) {
if (config_csdev->config_desc->load_owner == load_owner)
list_del(&config_csdev->node);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0796/1887] ublk: santizize the arguments from userspace when adding a device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (794 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0795/1887] coresight: holding cscfg_csdev_lock while removing cscfg from csdev Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0797/1887] LoongArch: Fix panic caused by NULL-PMD in huge_pte_offset() Greg Kroah-Hartman
` (202 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ronnie Sahlberg, Ming Lei,
Jens Axboe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ronnie Sahlberg <rsahlberg@whamcloud.com>
[ Upstream commit 8c8472855884355caf3d8e0c50adf825f83454b2 ]
Sanity check the values for queue depth and number of queues
we get from userspace when adding a device.
Signed-off-by: Ronnie Sahlberg <rsahlberg@whamcloud.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver")
Fixes: 62fe99cef94a ("ublk: add read()/write() support for ublk char device")
Link: https://lore.kernel.org/r/20250619021031.181340-1-ronniesahlberg@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/ublk_drv.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index c41bb08efb12c..538827b68d881 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1697,6 +1697,10 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
if (copy_from_user(&info, argp, sizeof(info)))
return -EFAULT;
ublk_dump_dev_info(&info);
+
+ if (info.queue_depth > UBLK_MAX_QUEUE_DEPTH)
+ return -EINVAL;
+
if (header->dev_id != info.dev_id) {
pr_warn("%s: dev id not match %u %u\n",
__func__, header->dev_id, info.dev_id);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0797/1887] LoongArch: Fix panic caused by NULL-PMD in huge_pte_offset()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (795 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0796/1887] ublk: santizize the arguments from userspace when adding a device Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0798/1887] sched/rt: Fix race in push_rt_task Greg Kroah-Hartman
` (201 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tianyang Zhang, Huacai Chen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianyang Zhang <zhangtianyang@loongson.cn>
[ Upstream commit ee084fa96123ede8b0563a1b5a9b23adc43cd50d ]
ERROR INFO:
CPU 25 Unable to handle kernel paging request at virtual address 0x0
...
Call Trace:
[<900000000023c30c>] huge_pte_offset+0x3c/0x58
[<900000000057fd4c>] hugetlb_follow_page_mask+0x74/0x438
[<900000000051fee8>] __get_user_pages+0xe0/0x4c8
[<9000000000522414>] faultin_page_range+0x84/0x380
[<9000000000564e8c>] madvise_vma_behavior+0x534/0xa48
[<900000000056689c>] do_madvise+0x1bc/0x3e8
[<9000000000566df4>] sys_madvise+0x24/0x38
[<90000000015b9e88>] do_syscall+0x78/0x98
[<9000000000221f18>] handle_syscall+0xb8/0x158
In some cases, pmd may be NULL and rely on NULL as the return value for
processing, so it is necessary to determine this situation here.
Cc: stable@vger.kernel.org
Fixes: bd51834d1cf6 ("LoongArch: Return NULL from huge_pte_offset() for invalid PMD")
Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/mm/hugetlbpage.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c
index 70b4a51885c24..9bc1ac6ad762a 100644
--- a/arch/loongarch/mm/hugetlbpage.c
+++ b/arch/loongarch/mm/hugetlbpage.c
@@ -47,7 +47,8 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
pmd = pmd_offset(pud, addr);
}
}
- return pmd_none(*pmd) ? NULL : (pte_t *) pmd;
+
+ return (!pmd || pmd_none(*pmd)) ? NULL : (pte_t *) pmd;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0798/1887] sched/rt: Fix race in push_rt_task
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (796 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0797/1887] LoongArch: Fix panic caused by NULL-PMD in huge_pte_offset() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0799/1887] smb: client: fix potential deadlock when reconnecting channels Greg Kroah-Hartman
` (200 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jon Kohler, Gauri Patwardhan,
Rahul Chunduru, Harshit Agarwal, Peter Zijlstra (Intel),
Steven Rostedt (Google), Phil Auld, Will Ton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Agarwal <harshit@nutanix.com>
[ Upstream commit 690e47d1403e90b7f2366f03b52ed3304194c793 ]
Overview
========
When a CPU chooses to call push_rt_task and picks a task to push to
another CPU's runqueue then it will call find_lock_lowest_rq method
which would take a double lock on both CPUs' runqueues. If one of the
locks aren't readily available, it may lead to dropping the current
runqueue lock and reacquiring both the locks at once. During this window
it is possible that the task is already migrated and is running on some
other CPU. These cases are already handled. However, if the task is
migrated and has already been executed and another CPU is now trying to
wake it up (ttwu) such that it is queued again on the runqeue
(on_rq is 1) and also if the task was run by the same CPU, then the
current checks will pass even though the task was migrated out and is no
longer in the pushable tasks list.
Crashes
=======
This bug resulted in quite a few flavors of crashes triggering kernel
panics with various crash signatures such as assert failures, page
faults, null pointer dereferences, and queue corruption errors all
coming from scheduler itself.
Some of the crashes:
-> kernel BUG at kernel/sched/rt.c:1616! BUG_ON(idx >= MAX_RT_PRIO)
Call Trace:
? __die_body+0x1a/0x60
? die+0x2a/0x50
? do_trap+0x85/0x100
? pick_next_task_rt+0x6e/0x1d0
? do_error_trap+0x64/0xa0
? pick_next_task_rt+0x6e/0x1d0
? exc_invalid_op+0x4c/0x60
? pick_next_task_rt+0x6e/0x1d0
? asm_exc_invalid_op+0x12/0x20
? pick_next_task_rt+0x6e/0x1d0
__schedule+0x5cb/0x790
? update_ts_time_stats+0x55/0x70
schedule_idle+0x1e/0x40
do_idle+0x15e/0x200
cpu_startup_entry+0x19/0x20
start_secondary+0x117/0x160
secondary_startup_64_no_verify+0xb0/0xbb
-> BUG: kernel NULL pointer dereference, address: 00000000000000c0
Call Trace:
? __die_body+0x1a/0x60
? no_context+0x183/0x350
? __warn+0x8a/0xe0
? exc_page_fault+0x3d6/0x520
? asm_exc_page_fault+0x1e/0x30
? pick_next_task_rt+0xb5/0x1d0
? pick_next_task_rt+0x8c/0x1d0
__schedule+0x583/0x7e0
? update_ts_time_stats+0x55/0x70
schedule_idle+0x1e/0x40
do_idle+0x15e/0x200
cpu_startup_entry+0x19/0x20
start_secondary+0x117/0x160
secondary_startup_64_no_verify+0xb0/0xbb
-> BUG: unable to handle page fault for address: ffff9464daea5900
kernel BUG at kernel/sched/rt.c:1861! BUG_ON(rq->cpu != task_cpu(p))
-> kernel BUG at kernel/sched/rt.c:1055! BUG_ON(!rq->nr_running)
Call Trace:
? __die_body+0x1a/0x60
? die+0x2a/0x50
? do_trap+0x85/0x100
? dequeue_top_rt_rq+0xa2/0xb0
? do_error_trap+0x64/0xa0
? dequeue_top_rt_rq+0xa2/0xb0
? exc_invalid_op+0x4c/0x60
? dequeue_top_rt_rq+0xa2/0xb0
? asm_exc_invalid_op+0x12/0x20
? dequeue_top_rt_rq+0xa2/0xb0
dequeue_rt_entity+0x1f/0x70
dequeue_task_rt+0x2d/0x70
__schedule+0x1a8/0x7e0
? blk_finish_plug+0x25/0x40
schedule+0x3c/0xb0
futex_wait_queue_me+0xb6/0x120
futex_wait+0xd9/0x240
do_futex+0x344/0xa90
? get_mm_exe_file+0x30/0x60
? audit_exe_compare+0x58/0x70
? audit_filter_rules.constprop.26+0x65e/0x1220
__x64_sys_futex+0x148/0x1f0
do_syscall_64+0x30/0x80
entry_SYSCALL_64_after_hwframe+0x62/0xc7
-> BUG: unable to handle page fault for address: ffff8cf3608bc2c0
Call Trace:
? __die_body+0x1a/0x60
? no_context+0x183/0x350
? spurious_kernel_fault+0x171/0x1c0
? exc_page_fault+0x3b6/0x520
? plist_check_list+0x15/0x40
? plist_check_list+0x2e/0x40
? asm_exc_page_fault+0x1e/0x30
? _cond_resched+0x15/0x30
? futex_wait_queue_me+0xc8/0x120
? futex_wait+0xd9/0x240
? try_to_wake_up+0x1b8/0x490
? futex_wake+0x78/0x160
? do_futex+0xcd/0xa90
? plist_check_list+0x15/0x40
? plist_check_list+0x2e/0x40
? plist_del+0x6a/0xd0
? plist_check_list+0x15/0x40
? plist_check_list+0x2e/0x40
? dequeue_pushable_task+0x20/0x70
? __schedule+0x382/0x7e0
? asm_sysvec_reschedule_ipi+0xa/0x20
? schedule+0x3c/0xb0
? exit_to_user_mode_prepare+0x9e/0x150
? irqentry_exit_to_user_mode+0x5/0x30
? asm_sysvec_reschedule_ipi+0x12/0x20
Above are some of the common examples of the crashes that were observed
due to this issue.
Details
=======
Let's look at the following scenario to understand this race.
1) CPU A enters push_rt_task
a) CPU A has chosen next_task = task p.
b) CPU A calls find_lock_lowest_rq(Task p, CPU Z’s rq).
c) CPU A identifies CPU X as a destination CPU (X < Z).
d) CPU A enters double_lock_balance(CPU Z’s rq, CPU X’s rq).
e) Since X is lower than Z, CPU A unlocks CPU Z’s rq. Someone else has
locked CPU X’s rq, and thus, CPU A must wait.
2) At CPU Z
a) Previous task has completed execution and thus, CPU Z enters
schedule, locks its own rq after CPU A releases it.
b) CPU Z dequeues previous task and begins executing task p.
c) CPU Z unlocks its rq.
d) Task p yields the CPU (ex. by doing IO or waiting to acquire a
lock) which triggers the schedule function on CPU Z.
e) CPU Z enters schedule again, locks its own rq, and dequeues task p.
f) As part of dequeue, it sets p.on_rq = 0 and unlocks its rq.
3) At CPU B
a) CPU B enters try_to_wake_up with input task p.
b) Since CPU Z dequeued task p, p.on_rq = 0, and CPU B updates
B.state = WAKING.
c) CPU B via select_task_rq determines CPU Y as the target CPU.
4) The race
a) CPU A acquires CPU X’s lock and relocks CPU Z.
b) CPU A reads task p.cpu = Z and incorrectly concludes task p is
still on CPU Z.
c) CPU A failed to notice task p had been dequeued from CPU Z while
CPU A was waiting for locks in double_lock_balance. If CPU A knew
that task p had been dequeued, it would return NULL forcing
push_rt_task to give up the task p's migration.
d) CPU B updates task p.cpu = Y and calls ttwu_queue.
e) CPU B locks Ys rq. CPU B enqueues task p onto Y and sets task
p.on_rq = 1.
f) CPU B unlocks CPU Y, triggering memory synchronization.
g) CPU A reads task p.on_rq = 1, cementing its assumption that task p
has not migrated.
h) CPU A decides to migrate p to CPU X.
This leads to A dequeuing p from Y's queue and various crashes down the
line.
Solution
========
The solution here is fairly simple. After obtaining the lock (at 4a),
the check is enhanced to make sure that the task is still at the head of
the pushable tasks list. If not, then it is anyway not suitable for
being pushed out.
Testing
=======
The fix is tested on a cluster of 3 nodes, where the panics due to this
are hit every couple of days. A fix similar to this was deployed on such
cluster and was stable for more than 30 days.
Co-developed-by: Jon Kohler <jon@nutanix.com>
Signed-off-by: Jon Kohler <jon@nutanix.com>
Co-developed-by: Gauri Patwardhan <gauri.patwardhan@nutanix.com>
Signed-off-by: Gauri Patwardhan <gauri.patwardhan@nutanix.com>
Co-developed-by: Rahul Chunduru <rahul.chunduru@nutanix.com>
Signed-off-by: Rahul Chunduru <rahul.chunduru@nutanix.com>
Signed-off-by: Harshit Agarwal <harshit@nutanix.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: "Steven Rostedt (Google)" <rostedt@goodmis.org>
Reviewed-by: Phil Auld <pauld@redhat.com>
Tested-by: Will Ton <william.ton@nutanix.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20250225180553.167995-1-harshit@nutanix.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/rt.c | 52 +++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 49e19ed896f8c..2eddf5653f6a0 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1972,6 +1972,26 @@ static int find_lowest_rq(struct task_struct *task)
return -1;
}
+static struct task_struct *pick_next_pushable_task(struct rq *rq)
+{
+ struct task_struct *p;
+
+ if (!has_pushable_tasks(rq))
+ return NULL;
+
+ p = plist_first_entry(&rq->rt.pushable_tasks,
+ struct task_struct, pushable_tasks);
+
+ BUG_ON(rq->cpu != task_cpu(p));
+ BUG_ON(task_current(rq, p));
+ BUG_ON(p->nr_cpus_allowed <= 1);
+
+ BUG_ON(!task_on_rq_queued(p));
+ BUG_ON(!rt_task(p));
+
+ return p;
+}
+
/* Will lock the rq it finds */
static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
{
@@ -2002,18 +2022,16 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
/*
* We had to unlock the run queue. In
* the mean time, task could have
- * migrated already or had its affinity changed.
- * Also make sure that it wasn't scheduled on its rq.
+ * migrated already or had its affinity changed,
+ * therefore check if the task is still at the
+ * head of the pushable tasks list.
* It is possible the task was scheduled, set
* "migrate_disabled" and then got preempted, so we must
* check the task migration disable flag here too.
*/
- if (unlikely(task_rq(task) != rq ||
+ if (unlikely(is_migration_disabled(task) ||
!cpumask_test_cpu(lowest_rq->cpu, &task->cpus_mask) ||
- task_on_cpu(rq, task) ||
- !rt_task(task) ||
- is_migration_disabled(task) ||
- !task_on_rq_queued(task))) {
+ task != pick_next_pushable_task(rq))) {
double_unlock_balance(rq, lowest_rq);
lowest_rq = NULL;
@@ -2033,26 +2051,6 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
return lowest_rq;
}
-static struct task_struct *pick_next_pushable_task(struct rq *rq)
-{
- struct task_struct *p;
-
- if (!has_pushable_tasks(rq))
- return NULL;
-
- p = plist_first_entry(&rq->rt.pushable_tasks,
- struct task_struct, pushable_tasks);
-
- BUG_ON(rq->cpu != task_cpu(p));
- BUG_ON(task_current(rq, p));
- BUG_ON(p->nr_cpus_allowed <= 1);
-
- BUG_ON(!task_on_rq_queued(p));
- BUG_ON(!rt_task(p));
-
- return p;
-}
-
/*
* If the current CPU has more than one RT task, see if the non
* running task can migrate over to a CPU that is running a task
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0799/1887] smb: client: fix potential deadlock when reconnecting channels
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (797 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0798/1887] sched/rt: Fix race in push_rt_task Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0800/1887] bnxt: properly flush XDP redirect lists Greg Kroah-Hartman
` (199 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-cifs, David Howells,
Paulo Alcantara (Red Hat), Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
[ Upstream commit 711741f94ac3cf9f4e3aa73aa171e76d188c0819 ]
Fix cifs_signal_cifsd_for_reconnect() to take the correct lock order
and prevent the following deadlock from happening
======================================================
WARNING: possible circular locking dependency detected
6.16.0-rc3-build2+ #1301 Tainted: G S W
------------------------------------------------------
cifsd/6055 is trying to acquire lock:
ffff88810ad56038 (&tcp_ses->srv_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x134/0x200
but task is already holding lock:
ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&ret_buf->chan_lock){+.+.}-{3:3}:
validate_chain+0x1cf/0x270
__lock_acquire+0x60e/0x780
lock_acquire.part.0+0xb4/0x1f0
_raw_spin_lock+0x2f/0x40
cifs_setup_session+0x81/0x4b0
cifs_get_smb_ses+0x771/0x900
cifs_mount_get_session+0x7e/0x170
cifs_mount+0x92/0x2d0
cifs_smb3_do_mount+0x161/0x460
smb3_get_tree+0x55/0x90
vfs_get_tree+0x46/0x180
do_new_mount+0x1b0/0x2e0
path_mount+0x6ee/0x740
do_mount+0x98/0xe0
__do_sys_mount+0x148/0x180
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x76/0x7e
-> #1 (&ret_buf->ses_lock){+.+.}-{3:3}:
validate_chain+0x1cf/0x270
__lock_acquire+0x60e/0x780
lock_acquire.part.0+0xb4/0x1f0
_raw_spin_lock+0x2f/0x40
cifs_match_super+0x101/0x320
sget+0xab/0x270
cifs_smb3_do_mount+0x1e0/0x460
smb3_get_tree+0x55/0x90
vfs_get_tree+0x46/0x180
do_new_mount+0x1b0/0x2e0
path_mount+0x6ee/0x740
do_mount+0x98/0xe0
__do_sys_mount+0x148/0x180
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x76/0x7e
-> #0 (&tcp_ses->srv_lock){+.+.}-{3:3}:
check_noncircular+0x95/0xc0
check_prev_add+0x115/0x2f0
validate_chain+0x1cf/0x270
__lock_acquire+0x60e/0x780
lock_acquire.part.0+0xb4/0x1f0
_raw_spin_lock+0x2f/0x40
cifs_signal_cifsd_for_reconnect+0x134/0x200
__cifs_reconnect+0x8f/0x500
cifs_handle_standard+0x112/0x280
cifs_demultiplex_thread+0x64d/0xbc0
kthread+0x2f7/0x310
ret_from_fork+0x2a/0x230
ret_from_fork_asm+0x1a/0x30
other info that might help us debug this:
Chain exists of:
&tcp_ses->srv_lock --> &ret_buf->ses_lock --> &ret_buf->chan_lock
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&ret_buf->chan_lock);
lock(&ret_buf->ses_lock);
lock(&ret_buf->chan_lock);
lock(&tcp_ses->srv_lock);
*** DEADLOCK ***
3 locks held by cifsd/6055:
#0: ffffffff857de398 (&cifs_tcp_ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x7b/0x200
#1: ffff888119c64060 (&ret_buf->ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x9c/0x200
#2: ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200
Cc: linux-cifs@vger.kernel.org
Reported-by: David Howells <dhowells@redhat.com>
Fixes: d7d7a66aacd6 ("cifs: avoid use of global locks for high contention data")
Reviewed-by: David Howells <dhowells@redhat.com>
Tested-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 1 +
fs/smb/client/connect.c | 56 ++++++++++++++++++++++++++--------------
2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index c37f10eedddf2..4e463ee8e40bb 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -589,6 +589,7 @@ get_rfc1002_length(void *buf)
struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
+ struct list_head rlist; /* reconnect list */
spinlock_t srv_lock; /* protect anything here that is not protected */
__u64 conn_id; /* connection identifier (useful for debugging) */
int srv_count; /* reference counter */
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 9172b4136a925..abc03adb692b5 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -185,6 +185,14 @@ static void cifs_resolve_server(struct work_struct *work)
cifs_server_unlock(server);
}
+#define set_need_reco(server) \
+do { \
+ spin_lock(&server->srv_lock); \
+ if (server->tcpStatus != CifsExiting) \
+ server->tcpStatus = CifsNeedReconnect; \
+ spin_unlock(&server->srv_lock); \
+} while (0)
+
/*
* Update the tcpStatus for the server.
* This is used to signal the cifsd thread to call cifs_reconnect
@@ -198,35 +206,45 @@ void
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
bool all_channels)
{
- struct TCP_Server_Info *pserver;
+ struct TCP_Server_Info *nserver;
struct cifs_ses *ses;
+ LIST_HEAD(reco);
int i;
- /* If server is a channel, select the primary channel */
- pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
-
/* if we need to signal just this channel */
if (!all_channels) {
- spin_lock(&server->srv_lock);
- if (server->tcpStatus != CifsExiting)
- server->tcpStatus = CifsNeedReconnect;
- spin_unlock(&server->srv_lock);
+ set_need_reco(server);
return;
}
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
- if (cifs_ses_exiting(ses))
- continue;
- spin_lock(&ses->chan_lock);
- for (i = 0; i < ses->chan_count; i++) {
- spin_lock(&ses->chans[i].server->srv_lock);
- ses->chans[i].server->tcpStatus = CifsNeedReconnect;
- spin_unlock(&ses->chans[i].server->srv_lock);
+ if (CIFS_SERVER_IS_CHAN(server))
+ server = server->primary_server;
+ scoped_guard(spinlock, &cifs_tcp_ses_lock) {
+ set_need_reco(server);
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ spin_lock(&ses->ses_lock);
+ if (ses->ses_status == SES_EXITING) {
+ spin_unlock(&ses->ses_lock);
+ continue;
+ }
+ spin_lock(&ses->chan_lock);
+ for (i = 1; i < ses->chan_count; i++) {
+ nserver = ses->chans[i].server;
+ if (!nserver)
+ continue;
+ nserver->srv_count++;
+ list_add(&nserver->rlist, &reco);
+ }
+ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
}
- spin_unlock(&ses->chan_lock);
}
- spin_unlock(&cifs_tcp_ses_lock);
+
+ list_for_each_entry_safe(server, nserver, &reco, rlist) {
+ list_del_init(&server->rlist);
+ set_need_reco(server);
+ cifs_put_tcp_session(server, 0);
+ }
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0800/1887] bnxt: properly flush XDP redirect lists
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (798 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0799/1887] smb: client: fix potential deadlock when reconnecting channels Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0801/1887] bridge: mcast: Fix use-after-free during router port configuration Greg Kroah-Hartman
` (198 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Rzeznik, Yan Zhai,
Jesper Dangaard Brouer, Michael Chan, Andy Gospodarek,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhai <yan@cloudflare.com>
[ Upstream commit 9caca6ac0e26cd20efd490d8b3b2ffb1c7c00f6f ]
We encountered following crash when testing a XDP_REDIRECT feature
in production:
[56251.579676] list_add corruption. next->prev should be prev (ffff93120dd40f30), but was ffffb301ef3a6740. (next=ffff93120dd
40f30).
[56251.601413] ------------[ cut here ]------------
[56251.611357] kernel BUG at lib/list_debug.c:29!
[56251.621082] Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
[56251.632073] CPU: 111 UID: 0 PID: 0 Comm: swapper/111 Kdump: loaded Tainted: P O 6.12.33-cloudflare-2025.6.
3 #1
[56251.653155] Tainted: [P]=PROPRIETARY_MODULE, [O]=OOT_MODULE
[56251.663877] Hardware name: MiTAC GC68B-B8032-G11P6-GPU/S8032GM-HE-CFR, BIOS V7.020.B10-sig 01/22/2025
[56251.682626] RIP: 0010:__list_add_valid_or_report+0x4b/0xa0
[56251.693203] Code: 0e 48 c7 c7 68 e7 d9 97 e8 42 16 fe ff 0f 0b 48 8b 52 08 48 39 c2 74 14 48 89 f1 48 c7 c7 90 e7 d9 97 48
89 c6 e8 25 16 fe ff <0f> 0b 4c 8b 02 49 39 f0 74 14 48 89 d1 48 c7 c7 e8 e7 d9 97 4c 89
[56251.725811] RSP: 0018:ffff93120dd40b80 EFLAGS: 00010246
[56251.736094] RAX: 0000000000000075 RBX: ffffb301e6bba9d8 RCX: 0000000000000000
[56251.748260] RDX: 0000000000000000 RSI: ffff9149afda0b80 RDI: ffff9149afda0b80
[56251.760349] RBP: ffff9131e49c8000 R08: 0000000000000000 R09: ffff93120dd40a18
[56251.772382] R10: ffff9159cf2ce1a8 R11: 0000000000000003 R12: ffff911a80850000
[56251.784364] R13: ffff93120fbc7000 R14: 0000000000000010 R15: ffff9139e7510e40
[56251.796278] FS: 0000000000000000(0000) GS:ffff9149afd80000(0000) knlGS:0000000000000000
[56251.809133] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[56251.819561] CR2: 00007f5e85e6f300 CR3: 00000038b85e2006 CR4: 0000000000770ef0
[56251.831365] PKRU: 55555554
[56251.838653] Call Trace:
[56251.845560] <IRQ>
[56251.851943] cpu_map_enqueue.cold+0x5/0xa
[56251.860243] xdp_do_redirect+0x2d9/0x480
[56251.868388] bnxt_rx_xdp+0x1d8/0x4c0 [bnxt_en]
[56251.877028] bnxt_rx_pkt+0x5f7/0x19b0 [bnxt_en]
[56251.885665] ? cpu_max_write+0x1e/0x100
[56251.893510] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.902276] __bnxt_poll_work+0x190/0x340 [bnxt_en]
[56251.911058] bnxt_poll+0xab/0x1b0 [bnxt_en]
[56251.919041] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.927568] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.935958] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.944250] __napi_poll+0x2b/0x160
[56251.951155] bpf_trampoline_6442548651+0x79/0x123
[56251.959262] __napi_poll+0x5/0x160
[56251.966037] net_rx_action+0x3d2/0x880
[56251.973133] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.981265] ? srso_alias_return_thunk+0x5/0xfbef5
[56251.989262] ? __hrtimer_run_queues+0x162/0x2a0
[56251.996967] ? srso_alias_return_thunk+0x5/0xfbef5
[56252.004875] ? srso_alias_return_thunk+0x5/0xfbef5
[56252.012673] ? bnxt_msix+0x62/0x70 [bnxt_en]
[56252.019903] handle_softirqs+0xcf/0x270
[56252.026650] irq_exit_rcu+0x67/0x90
[56252.032933] common_interrupt+0x85/0xa0
[56252.039498] </IRQ>
[56252.044246] <TASK>
[56252.048935] asm_common_interrupt+0x26/0x40
[56252.055727] RIP: 0010:cpuidle_enter_state+0xb8/0x420
[56252.063305] Code: dc 01 00 00 e8 f9 79 3b ff e8 64 f7 ff ff 49 89 c5 0f 1f 44 00 00 31 ff e8 a5 32 3a ff 45 84 ff 0f 85 ae
01 00 00 fb 45 85 f6 <0f> 88 88 01 00 00 48 8b 04 24 49 63 ce 4c 89 ea 48 6b f1 68 48 29
[56252.088911] RSP: 0018:ffff93120c97fe98 EFLAGS: 00000202
[56252.096912] RAX: ffff9149afd80000 RBX: ffff9141d3a72800 RCX: 0000000000000000
[56252.106844] RDX: 00003329176c6b98 RSI: ffffffe36db3fdc7 RDI: 0000000000000000
[56252.116733] RBP: 0000000000000002 R08: 0000000000000002 R09: 000000000000004e
[56252.126652] R10: ffff9149afdb30c4 R11: 071c71c71c71c71c R12: ffffffff985ff860
[56252.136637] R13: 00003329176c6b98 R14: 0000000000000002 R15: 0000000000000000
[56252.146667] ? cpuidle_enter_state+0xab/0x420
[56252.153909] cpuidle_enter+0x2d/0x40
[56252.160360] do_idle+0x176/0x1c0
[56252.166456] cpu_startup_entry+0x29/0x30
[56252.173248] start_secondary+0xf7/0x100
[56252.179941] common_startup_64+0x13e/0x141
[56252.186886] </TASK>
>From the crash dump, we found that the cpu_map_flush_list inside
redirect info is partially corrupted: its list_head->next points to
itself, but list_head->prev points to a valid list of unflushed bq
entries.
This turned out to be a result of missed XDP flush on redirect lists. By
digging in the actual source code, we found that
commit 7f0a168b0441 ("bnxt_en: Add completion ring pointer in TX and RX
ring structures") incorrectly overwrites the event mask for XDP_REDIRECT
in bnxt_rx_xdp. We can stably reproduce this crash by returning XDP_TX
and XDP_REDIRECT randomly for incoming packets in a naive XDP program.
Properly propagate the XDP_REDIRECT events back fixes the crash.
Fixes: a7559bc8c17c ("bnxt: support transmit and free of aggregation buffers")
Tested-by: Andrew Rzeznik <arzeznik@cloudflare.com>
Signed-off-by: Yan Zhai <yan@cloudflare.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Link: https://patch.msgid.link/aFl7jpCNzscumuN2@debian.debian
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 321504790948f..de7bef33641a8 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -2543,6 +2543,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
{
struct bnxt_napi *bnapi = cpr->bnapi;
u32 raw_cons = cpr->cp_raw_cons;
+ bool flush_xdp = false;
u32 cons;
int tx_pkts = 0;
int rx_pkts = 0;
@@ -2580,6 +2581,8 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
else
rc = bnxt_force_rx_discard(bp, cpr, &raw_cons,
&event);
+ if (event & BNXT_REDIRECT_EVENT)
+ flush_xdp = true;
if (likely(rc >= 0))
rx_pkts += rc;
/* Increment rx_pkts when rc is -ENOMEM to count towards
@@ -2607,7 +2610,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
}
}
- if (event & BNXT_REDIRECT_EVENT)
+ if (flush_xdp)
xdp_do_flush();
if (event & BNXT_TX_EVENT) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0801/1887] bridge: mcast: Fix use-after-free during router port configuration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (799 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0800/1887] bnxt: properly flush XDP redirect lists Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0802/1887] riscv: save the SR_SUM status over switches Greg Kroah-Hartman
` (197 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+7bfa4b72c6a5da128d32,
Ido Schimmel, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 7544f3f5b0b58c396f374d060898b5939da31709 ]
The bridge maintains a global list of ports behind which a multicast
router resides. The list is consulted during forwarding to ensure
multicast packets are forwarded to these ports even if the ports are not
member in the matching MDB entry.
When per-VLAN multicast snooping is enabled, the per-port multicast
context is disabled on each port and the port is removed from the global
router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1
# ip link add name dummy1 up master br1 type dummy
# ip link set dev dummy1 type bridge_slave mcast_router 2
$ bridge -d mdb show | grep router
router ports on br1: dummy1
# ip link set dev br1 type bridge mcast_vlan_snooping 1
$ bridge -d mdb show | grep router
However, the port can be re-added to the global list even when per-VLAN
multicast snooping is enabled:
# ip link set dev dummy1 type bridge_slave mcast_router 0
# ip link set dev dummy1 type bridge_slave mcast_router 2
$ bridge -d mdb show | grep router
router ports on br1: dummy1
Since commit 4b30ae9adb04 ("net: bridge: mcast: re-implement
br_multicast_{enable, disable}_port functions"), when per-VLAN multicast
snooping is enabled, multicast disablement on a port will disable the
per-{port, VLAN} multicast contexts and not the per-port one. As a
result, a port will remain in the global router port list even after it
is deleted. This will lead to a use-after-free [1] when the list is
traversed (when adding a new port to the list, for example):
# ip link del dev dummy1
# ip link add name dummy2 up master br1 type dummy
# ip link set dev dummy2 type bridge_slave mcast_router 2
Similarly, stale entries can also be found in the per-VLAN router port
list. When per-VLAN multicast snooping is disabled, the per-{port, VLAN}
contexts are disabled on each port and the port is removed from the
per-VLAN router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1
# ip link add name dummy1 up master br1 type dummy
# bridge vlan add vid 2 dev dummy1
# bridge vlan global set vid 2 dev br1 mcast_snooping 1
# bridge vlan set vid 2 dev dummy1 mcast_router 2
$ bridge vlan global show dev br1 vid 2 | grep router
router ports: dummy1
# ip link set dev br1 type bridge mcast_vlan_snooping 0
$ bridge vlan global show dev br1 vid 2 | grep router
However, the port can be re-added to the per-VLAN list even when
per-VLAN multicast snooping is disabled:
# bridge vlan set vid 2 dev dummy1 mcast_router 0
# bridge vlan set vid 2 dev dummy1 mcast_router 2
$ bridge vlan global show dev br1 vid 2 | grep router
router ports: dummy1
When the VLAN is deleted from the port, the per-{port, VLAN} multicast
context will not be disabled since multicast snooping is not enabled
on the VLAN. As a result, the port will remain in the per-VLAN router
port list even after it is no longer member in the VLAN. This will lead
to a use-after-free [2] when the list is traversed (when adding a new
port to the list, for example):
# ip link add name dummy2 up master br1 type dummy
# bridge vlan add vid 2 dev dummy2
# bridge vlan del vid 2 dev dummy1
# bridge vlan set vid 2 dev dummy2 mcast_router 2
Fix these issues by removing the port from the relevant (global or
per-VLAN) router port list in br_multicast_port_ctx_deinit(). The
function is invoked during port deletion with the per-port multicast
context and during VLAN deletion with the per-{port, VLAN} multicast
context.
Note that deleting the multicast router timer is not enough as it only
takes care of the temporary multicast router states (1 or 3) and not the
permanent one (2).
[1]
BUG: KASAN: slab-out-of-bounds in br_multicast_add_router.part.0+0x3f1/0x560
Write of size 8 at addr ffff888004a67328 by task ip/384
[...]
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xa0
print_address_description.constprop.0+0x6f/0x350
print_report+0x108/0x205
kasan_report+0xdf/0x110
br_multicast_add_router.part.0+0x3f1/0x560
br_multicast_set_port_router+0x74e/0xac0
br_setport+0xa55/0x1870
br_port_slave_changelink+0x95/0x120
__rtnl_newlink+0x5e8/0xa40
rtnl_newlink+0x627/0xb00
rtnetlink_rcv_msg+0x6fb/0xb70
netlink_rcv_skb+0x11f/0x350
netlink_unicast+0x426/0x710
netlink_sendmsg+0x75a/0xc20
__sock_sendmsg+0xc1/0x150
____sys_sendmsg+0x5aa/0x7b0
___sys_sendmsg+0xfc/0x180
__sys_sendmsg+0x124/0x1c0
do_syscall_64+0xbb/0x360
entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2]
BUG: KASAN: slab-use-after-free in br_multicast_add_router.part.0+0x378/0x560
Read of size 8 at addr ffff888009f00840 by task bridge/391
[...]
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xa0
print_address_description.constprop.0+0x6f/0x350
print_report+0x108/0x205
kasan_report+0xdf/0x110
br_multicast_add_router.part.0+0x378/0x560
br_multicast_set_port_router+0x6f9/0xac0
br_vlan_process_options+0x8b6/0x1430
br_vlan_rtm_process_one+0x605/0xa30
br_vlan_rtm_process+0x396/0x4c0
rtnetlink_rcv_msg+0x2f7/0xb70
netlink_rcv_skb+0x11f/0x350
netlink_unicast+0x426/0x710
netlink_sendmsg+0x75a/0xc20
__sock_sendmsg+0xc1/0x150
____sys_sendmsg+0x5aa/0x7b0
___sys_sendmsg+0xfc/0x180
__sys_sendmsg+0x124/0x1c0
do_syscall_64+0xbb/0x360
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Fixes: 2796d846d74a ("net: bridge: vlan: convert mcast router global option to per-vlan entry")
Fixes: 4b30ae9adb04 ("net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions")
Reported-by: syzbot+7bfa4b72c6a5da128d32@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/684c18bd.a00a0220.279073.000b.GAE@google.com/T/
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20250619182228.1656906-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/br_multicast.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index c96a9c2a27780..c2fec582372c9 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1872,10 +1872,19 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
{
+ struct net_bridge *br = pmctx->port->br;
+ bool del = false;
+
#if IS_ENABLED(CONFIG_IPV6)
del_timer_sync(&pmctx->ip6_mc_router_timer);
#endif
del_timer_sync(&pmctx->ip4_mc_router_timer);
+
+ spin_lock_bh(&br->multicast_lock);
+ del |= br_ip6_multicast_rport_del(pmctx);
+ del |= br_ip4_multicast_rport_del(pmctx);
+ br_multicast_rport_del_notify(pmctx, del);
+ spin_unlock_bh(&br->multicast_lock);
}
int br_multicast_add_port(struct net_bridge_port *port)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0802/1887] riscv: save the SR_SUM status over switches
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (800 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0801/1887] bridge: mcast: Fix use-after-free during router port configuration Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0803/1887] net: dsa: b53: do not enable EEE on bcm63xx Greg Kroah-Hartman
` (196 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e74b94fe601ab9552d69,
Ben Dooks, Cyril Bur, Alexandre Ghiti, Deepak Gupta,
Palmer Dabbelt, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <ben.dooks@codethink.co.uk>
[ Upstream commit 788aa64c01f1262310b4c1fb827a36df170d86ea ]
When threads/tasks are switched we need to ensure the old execution's
SR_SUM state is saved and the new thread has the old SR_SUM state
restored.
The issue was seen under heavy load especially with the syz-stress tool
running, with crashes as follows in schedule_tail:
Unable to handle kernel access to user memory without uaccess routines
at virtual address 000000002749f0d0
Oops [#1]
Modules linked in:
CPU: 1 PID: 4875 Comm: syz-executor.0 Not tainted
5.12.0-rc2-syzkaller-00467-g0d7588ab9ef9 #0
Hardware name: riscv-virtio,qemu (DT)
epc : schedule_tail+0x72/0xb2 kernel/sched/core.c:4264
ra : task_pid_vnr include/linux/sched.h:1421 [inline]
ra : schedule_tail+0x70/0xb2 kernel/sched/core.c:4264
epc : ffffffe00008c8b0 ra : ffffffe00008c8ae sp : ffffffe025d17ec0
gp : ffffffe005d25378 tp : ffffffe00f0d0000 t0 : 0000000000000000
t1 : 0000000000000001 t2 : 00000000000f4240 s0 : ffffffe025d17ee0
s1 : 000000002749f0d0 a0 : 000000000000002a a1 : 0000000000000003
a2 : 1ffffffc0cfac500 a3 : ffffffe0000c80cc a4 : 5ae9db91c19bbe00
a5 : 0000000000000000 a6 : 0000000000f00000 a7 : ffffffe000082eba
s2 : 0000000000040000 s3 : ffffffe00eef96c0 s4 : ffffffe022c77fe0
s5 : 0000000000004000 s6 : ffffffe067d74e00 s7 : ffffffe067d74850
s8 : ffffffe067d73e18 s9 : ffffffe067d74e00 s10: ffffffe00eef96e8
s11: 000000ae6cdf8368 t3 : 5ae9db91c19bbe00 t4 : ffffffc4043cafb2
t5 : ffffffc4043cafba t6 : 0000000000040000
status: 0000000000000120 badaddr: 000000002749f0d0 cause:
000000000000000f
Call Trace:
[<ffffffe00008c8b0>] schedule_tail+0x72/0xb2 kernel/sched/core.c:4264
[<ffffffe000005570>] ret_from_exception+0x0/0x14
Dumping ftrace buffer:
(ftrace buffer empty)
---[ end trace b5f8f9231dc87dda ]---
The issue comes from the put_user() in schedule_tail
(kernel/sched/core.c) doing the following:
asmlinkage __visible void schedule_tail(struct task_struct *prev)
{
...
if (current->set_child_tid)
put_user(task_pid_vnr(current), current->set_child_tid);
...
}
the put_user() macro causes the code sequence to come out as follows:
1: __enable_user_access()
2: reg = task_pid_vnr(current);
3: *current->set_child_tid = reg;
4: __disable_user_access()
The problem is that we may have a sleeping function as argument which
could clear SR_SUM causing the panic above. This was fixed by
evaluating the argument of the put_user() macro outside the user-enabled
section in commit 285a76bb2cf5 ("riscv: evaluate put_user() arg before
enabling user access")"
In order for riscv to take advantage of unsafe_get/put_XXX() macros and
to avoid the same issue we had with put_user() and sleeping functions we
must ensure code flow can go through switch_to() from within a region of
code with SR_SUM enabled and come back with SR_SUM still enabled. This
patch addresses the problem allowing future work to enable full use of
unsafe_get/put_XXX() macros without needing to take a CSR bit flip cost
on every access. Make switch_to() save and restore SR_SUM.
Reported-by: syzbot+e74b94fe601ab9552d69@syzkaller.appspotmail.com
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Signed-off-by: Cyril Bur <cyrilbur@tenstorrent.com>
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Link: https://lore.kernel.org/r/20250410070526.3160847-2-cyrilbur@tenstorrent.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/include/asm/processor.h | 1 +
arch/riscv/kernel/asm-offsets.c | 5 +++++
arch/riscv/kernel/entry.S | 9 +++++++++
3 files changed, 15 insertions(+)
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 94a0590c69710..2a22ee93c54c9 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -39,6 +39,7 @@ struct thread_struct {
unsigned long s[12]; /* s[0]: frame pointer */
struct __riscv_d_ext_state fstate;
unsigned long bad_cause;
+ unsigned long status;
};
/* Whitelist the fstate from the task_struct for hardened usercopy */
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 9e6e35da69ce4..1c228973971f4 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -33,6 +33,7 @@ void asm_offsets(void)
OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]);
OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]);
OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags);
+ OFFSET(TASK_THREAD_STATUS, task_struct, thread.status);
OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count);
OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp);
@@ -331,6 +332,10 @@ void asm_offsets(void)
offsetof(struct task_struct, thread.s[11])
- offsetof(struct task_struct, thread.ra)
);
+ DEFINE(TASK_THREAD_STATUS_RA,
+ offsetof(struct task_struct, thread.status)
+ - offsetof(struct task_struct, thread.ra)
+ );
DEFINE(TASK_THREAD_F0_F0,
offsetof(struct task_struct, thread.fstate.f[0])
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index f6c3841df2f5a..2f8bc50c3b4ab 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -502,7 +502,16 @@ ENTRY(__switch_to)
REG_S s9, TASK_THREAD_S9_RA(a3)
REG_S s10, TASK_THREAD_S10_RA(a3)
REG_S s11, TASK_THREAD_S11_RA(a3)
+
+ /* save the user space access flag */
+ csrr s0, CSR_STATUS
+ REG_S s0, TASK_THREAD_STATUS_RA(a3)
+
/* Restore context from next->thread */
+ REG_L s0, TASK_THREAD_STATUS_RA(a4)
+ li s1, SR_SUM
+ and s0, s0, s1
+ csrs CSR_STATUS, s0
REG_L ra, TASK_THREAD_RA_RA(a4)
REG_L sp, TASK_THREAD_SP_RA(a4)
REG_L s0, TASK_THREAD_S0_RA(a4)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0803/1887] net: dsa: b53: do not enable EEE on bcm63xx
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (801 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0802/1887] riscv: save the SR_SUM status over switches Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0804/1887] hisi_acc_vfio_pci: bugfix live migration function without VF device driver Greg Kroah-Hartman
` (195 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Florian Fainelli,
Álvaro Fernández Rojas, Jonas Gorski, Paolo Abeni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <jonas.gorski@gmail.com>
[ Upstream commit 1237c2d4a8db79dfd4369bff6930b0e385ed7d5c ]
BCM63xx internal switches do not support EEE, but provide multiple RGMII
ports where external PHYs may be connected. If one of these PHYs are EEE
capable, we may try to enable EEE for the MACs, which then hangs the
system on access of the (non-existent) EEE registers.
Fix this by checking if the switch actually supports EEE before
attempting to configure it.
Fixes: 22256b0afb12 ("net: dsa: b53: Move EEE functions to b53")
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Tested-by: Álvaro Fernández Rojas <noltari@gmail.com>
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Link: https://patch.msgid.link/20250602193953.1010487-2-jonas.gorski@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/b53/b53_common.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index aaf9fbaefd6b9..7777d4cef351f 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2237,8 +2237,12 @@ EXPORT_SYMBOL(b53_eee_enable_set);
*/
int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
{
+ struct b53_device *dev = ds->priv;
int ret;
+ if (is5325(dev) || is5365(dev) || is63xx(dev))
+ return 0;
+
ret = phy_init_eee(phy, false);
if (ret)
return 0;
@@ -2255,7 +2259,7 @@ int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
struct ethtool_eee *p = &dev->ports[port].eee;
u16 reg;
- if (is5325(dev) || is5365(dev))
+ if (is5325(dev) || is5365(dev) || is63xx(dev))
return -EOPNOTSUPP;
b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, ®);
@@ -2271,7 +2275,7 @@ int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
struct b53_device *dev = ds->priv;
struct ethtool_eee *p = &dev->ports[port].eee;
- if (is5325(dev) || is5365(dev))
+ if (is5325(dev) || is5365(dev) || is63xx(dev))
return -EOPNOTSUPP;
p->eee_enabled = e->eee_enabled;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0804/1887] hisi_acc_vfio_pci: bugfix live migration function without VF device driver
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (802 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0803/1887] net: dsa: b53: do not enable EEE on bcm63xx Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0805/1887] s390/mm: Fix in_atomic() handling in do_secure_storage_access() Greg Kroah-Hartman
` (194 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Longfang Liu, Shameer Kolothum,
Alex Williamson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Longfang Liu <liulongfang@huawei.com>
[ Upstream commit 2777a40998deb36f96b6afc48bd397cf58a4edf0 ]
If the VF device driver is not loaded in the Guest OS and we attempt to
perform device data migration, the address of the migrated data will
be NULL.
The live migration recovery operation on the destination side will
access a null address value, which will cause access errors.
Therefore, live migration of VMs without added VF device drivers
does not require device data migration.
In addition, when the queue address data obtained by the destination
is empty, device queue recovery processing will not be performed.
Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
Signed-off-by: Longfang Liu <liulongfang@huawei.com>
Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20250510081155.55840-6-liulongfang@huawei.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 22 +++++++++++++------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
index e682c14614998..77ddf681b9dc2 100644
--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
@@ -426,13 +426,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
return -EINVAL;
}
- ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
- if (ret) {
- dev_err(dev, "failed to write QM_VF_STATE\n");
- return ret;
- }
-
- hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
return 0;
}
@@ -497,6 +490,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
if (migf->total_length < sizeof(struct acc_vf_data))
return -EINVAL;
+ if (!vf_data->eqe_dma || !vf_data->aeqe_dma ||
+ !vf_data->sqc_dma || !vf_data->cqc_dma) {
+ dev_info(dev, "resume dma addr is NULL!\n");
+ hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
+ return 0;
+ }
+
+ ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
+ if (ret) {
+ dev_err(dev, "failed to write QM_VF_STATE\n");
+ return -EINVAL;
+ }
+ hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
+
qm->eqe_dma = vf_data->eqe_dma;
qm->aeqe_dma = vf_data->aeqe_dma;
qm->sqc_dma = vf_data->sqc_dma;
@@ -1269,6 +1276,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
hisi_acc_vdev->pf_qm = pf_qm;
hisi_acc_vdev->vf_dev = pdev;
+ hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
mutex_init(&hisi_acc_vdev->state_mutex);
core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0805/1887] s390/mm: Fix in_atomic() handling in do_secure_storage_access()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (803 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0804/1887] hisi_acc_vfio_pci: bugfix live migration function without VF device driver Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0806/1887] bus: mhi: ep: Update read pointer only after buffer is written Greg Kroah-Hartman
` (193 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Claudio Imbrenda, Alexander Gordeev,
Christian Borntraeger, Heiko Carstens, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <hca@linux.ibm.com>
[ Upstream commit 11709abccf93b08adde95ef313c300b0d4bc28f1 ]
Kernel user spaces accesses to not exported pages in atomic context
incorrectly try to resolve the page fault.
With debug options enabled call traces like this can be seen:
BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1523
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 419074, name: qemu-system-s39
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
INFO: lockdep is turned off.
Preemption disabled at:
[<00000383ea47cfa2>] copy_page_from_iter_atomic+0xa2/0x8a0
CPU: 12 UID: 0 PID: 419074 Comm: qemu-system-s39
Tainted: G W 6.16.0-20250531.rc0.git0.69b3a602feac.63.fc42.s390x+debug #1 PREEMPT
Tainted: [W]=WARN
Hardware name: IBM 3931 A01 703 (LPAR)
Call Trace:
[<00000383e990d282>] dump_stack_lvl+0xa2/0xe8
[<00000383e99bf152>] __might_resched+0x292/0x2d0
[<00000383eaa7c374>] down_read+0x34/0x2d0
[<00000383e99432f8>] do_secure_storage_access+0x108/0x360
[<00000383eaa724b0>] __do_pgm_check+0x130/0x220
[<00000383eaa842e4>] pgm_check_handler+0x114/0x160
[<00000383ea47d028>] copy_page_from_iter_atomic+0x128/0x8a0
([<00000383ea47d016>] copy_page_from_iter_atomic+0x116/0x8a0)
[<00000383e9c45eae>] generic_perform_write+0x16e/0x310
[<00000383e9eb87f4>] ext4_buffered_write_iter+0x84/0x160
[<00000383e9da0de4>] vfs_write+0x1c4/0x460
[<00000383e9da123c>] ksys_write+0x7c/0x100
[<00000383eaa7284e>] __do_syscall+0x15e/0x280
[<00000383eaa8417e>] system_call+0x6e/0x90
INFO: lockdep is turned off.
It is not allowed to take the mmap_lock while in atomic context. Therefore
handle such a secure storage access fault as if the accessed page is not
mapped: the uaccess function will return -EFAULT, and the caller has to
deal with this. Usually this means that the access is retried in process
context, which allows to resolve the page fault (or in this case export the
page).
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Link: https://lore.kernel.org/r/20250603134936.1314139-1-hca@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/mm/fault.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2ab388179833e..be6122b0e6d15 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -818,6 +818,8 @@ void do_secure_storage_access(struct pt_regs *regs)
switch (get_fault_type(regs)) {
case GMAP_FAULT:
+ if (faulthandler_disabled())
+ return do_fault_error(regs, VM_FAULT_BADMAP);
mm = current->mm;
gmap = (struct gmap *)S390_lowcore.gmap;
mmap_read_lock(mm);
@@ -829,6 +831,8 @@ void do_secure_storage_access(struct pt_regs *regs)
}
fallthrough;
case USER_FAULT:
+ if (faulthandler_disabled())
+ return do_fault_error(regs, VM_FAULT_BADMAP);
mm = current->mm;
mmap_read_lock(mm);
vma = find_vma(mm, addr);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0806/1887] bus: mhi: ep: Update read pointer only after buffer is written
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (804 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0805/1887] s390/mm: Fix in_atomic() handling in do_secure_storage_access() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0807/1887] HID: nintendo: avoid bluetooth suspend/resume stalls Greg Kroah-Hartman
` (192 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Youssef Samir, Sumit Kumar,
Jeff Hugo, Krishna Chaitanya Chundru, Manivannan Sadhasivam,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Kumar <quic_sumk@quicinc.com>
[ Upstream commit 6f18d174b73d0ceeaa341f46c0986436b3aefc9a ]
Inside mhi_ep_ring_add_element, the read pointer (rd_offset) is updated
before the buffer is written, potentially causing race conditions where
the host sees an updated read pointer before the buffer is actually
written. Updating rd_offset prematurely can lead to the host accessing
an uninitialized or incomplete element, resulting in data corruption.
Invoke the buffer write before updating rd_offset to ensure the element
is fully written before signaling its availability.
Fixes: bbdcba57a1a2 ("bus: mhi: ep: Add support for ring management")
cc: stable@vger.kernel.org
Co-developed-by: Youssef Samir <quic_yabdulra@quicinc.com>
Signed-off-by: Youssef Samir <quic_yabdulra@quicinc.com>
Signed-off-by: Sumit Kumar <quic_sumk@quicinc.com>
Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://patch.msgid.link/20250409-rp_fix-v1-1-8cf1fa22ed28@quicinc.com
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bus/mhi/ep/ring.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c
index 115518ec76a43..926a158bb22d4 100644
--- a/drivers/bus/mhi/ep/ring.c
+++ b/drivers/bus/mhi/ep/ring.c
@@ -125,19 +125,19 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e
}
old_offset = ring->rd_offset;
- mhi_ep_ring_inc_index(ring);
dev_dbg(dev, "Adding an element to ring at offset (%zu)\n", ring->rd_offset);
-
- /* Update rp in ring context */
- rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase);
- memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64));
-
ret = mhi_cntrl->write_to_host(mhi_cntrl, el, ring->rbase + (old_offset * sizeof(*el)),
sizeof(*el));
if (ret < 0)
return ret;
+ mhi_ep_ring_inc_index(ring);
+
+ /* Update rp in ring context */
+ rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase);
+ memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64));
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0807/1887] HID: nintendo: avoid bluetooth suspend/resume stalls
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (805 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0806/1887] bus: mhi: ep: Update read pointer only after buffer is written Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0808/1887] rxrpc: Fix recv-recv race of completed call Greg Kroah-Hartman
` (191 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel J. Ogorchock, Silvan Jegen,
Jiri Kosina, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel J. Ogorchock <djogorchock@gmail.com>
[ Upstream commit 4a0381080397e77792a5168069f174d3e56175ff ]
Ensure we don't stall or panic the kernel when using bluetooth-connected
controllers. This was reported as an issue on android devices using
kernel 6.6 due to the resume hook which had been added for usb joycons.
First, set a new state value to JOYCON_CTLR_STATE_SUSPENDED in a
newly-added nintendo_hid_suspend. This makes sure we will not stall out
the kernel waiting for input reports during led classdev suspend. The
stalls could happen if connectivity is unreliable or lost to the
controller prior to suspend.
Second, since we lose connectivity during suspend, do not try
joycon_init() for bluetooth controllers in the nintendo_hid_resume path.
Tested via multiple suspend/resume flows when using the controller both
in USB and bluetooth modes.
Signed-off-by: Daniel J. Ogorchock <djogorchock@gmail.com>
Reviewed-by: Silvan Jegen <s.jegen@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-nintendo.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
index 44edc50be6e56..7a1bb4c876659 100644
--- a/drivers/hid/hid-nintendo.c
+++ b/drivers/hid/hid-nintendo.c
@@ -301,6 +301,7 @@ enum joycon_ctlr_state {
JOYCON_CTLR_STATE_INIT,
JOYCON_CTLR_STATE_READ,
JOYCON_CTLR_STATE_REMOVED,
+ JOYCON_CTLR_STATE_SUSPENDED,
};
/* Controller type received as part of device info */
@@ -2341,14 +2342,46 @@ static void nintendo_hid_remove(struct hid_device *hdev)
static int nintendo_hid_resume(struct hid_device *hdev)
{
- int ret = joycon_init(hdev);
+ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
+ int ret;
+
+ hid_dbg(hdev, "resume\n");
+ if (hdev->bus != BUS_USB) {
+ hid_dbg(hdev, "no-op resume for bt ctlr\n");
+ ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;
+ return 0;
+ }
+ ret = joycon_init(hdev);
if (ret)
- hid_err(hdev, "Failed to restore controller after resume");
+ hid_err(hdev,
+ "Failed to restore controller after resume: %d\n",
+ ret);
+ else
+ ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;
return ret;
}
+static int nintendo_hid_suspend(struct hid_device *hdev, pm_message_t message)
+{
+ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
+
+ hid_dbg(hdev, "suspend: %d\n", message.event);
+ /*
+ * Avoid any blocking loops in suspend/resume transitions.
+ *
+ * joycon_enforce_subcmd_rate() can result in repeated retries if for
+ * whatever reason the controller stops providing input reports.
+ *
+ * This has been observed with bluetooth controllers which lose
+ * connectivity prior to suspend (but not long enough to result in
+ * complete disconnection).
+ */
+ ctlr->ctlr_state = JOYCON_CTLR_STATE_SUSPENDED;
+ return 0;
+}
+
#endif
static const struct hid_device_id nintendo_hid_devices[] = {
@@ -2375,6 +2408,7 @@ static struct hid_driver nintendo_hid_driver = {
#ifdef CONFIG_PM
.resume = nintendo_hid_resume,
+ .suspend = nintendo_hid_suspend,
#endif
};
module_hid_driver(nintendo_hid_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0808/1887] rxrpc: Fix recv-recv race of completed call
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (806 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0807/1887] HID: nintendo: avoid bluetooth suspend/resume stalls Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0809/1887] iio: st_sensors: core and lsm9ds0 switch to devm_regulator_bulk_get_enable() Greg Kroah-Hartman
` (190 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junvyyang, Tencent Zhuque Lab,
David Howells, Jeffrey Altman, LePremierHomme, Marc Dionne,
Simon Horman, linux-afs, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 962fb1f651c2cf2083e0c3ef53ba69e3b96d3fbc ]
If a call receives an event (such as incoming data), the call gets placed
on the socket's queue and a thread in recvmsg can be awakened to go and
process it. Once the thread has picked up the call off of the queue,
further events will cause it to be requeued, and once the socket lock is
dropped (recvmsg uses call->user_mutex to allow the socket to be used in
parallel), a second thread can come in and its recvmsg can pop the call off
the socket queue again.
In such a case, the first thread will be receiving stuff from the call and
the second thread will be blocked on call->user_mutex. The first thread
can, at this point, process both the event that it picked call for and the
event that the second thread picked the call for and may see the call
terminate - in which case the call will be "released", decoupling the call
from the user call ID assigned to it (RXRPC_USER_CALL_ID in the control
message).
The first thread will return okay, but then the second thread will wake up
holding the user_mutex and, if it sees that the call has been released by
the first thread, it will BUG thusly:
kernel BUG at net/rxrpc/recvmsg.c:474!
Fix this by just dequeuing the call and ignoring it if it is seen to be
already released. We can't tell userspace about it anyway as the user call
ID has become stale.
Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Reported-by: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
cc: LePremierHomme <kwqcheii@proton.me>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-3-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rxrpc/recvmsg.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c
index 99c679f40e7b6..870fab693653f 100644
--- a/net/rxrpc/recvmsg.c
+++ b/net/rxrpc/recvmsg.c
@@ -546,6 +546,15 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
write_lock_bh(&rx->recvmsg_lock);
l = rx->recvmsg_q.next;
call = list_entry(l, struct rxrpc_call, recvmsg_link);
+
+ if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
+ list_del_init(&call->recvmsg_link);
+ write_unlock_bh(&rx->recvmsg_lock);
+ release_sock(&rx->sk);
+ rxrpc_put_call(call, rxrpc_call_put);
+ goto try_again;
+ }
+
if (!(flags & MSG_PEEK))
list_del_init(&call->recvmsg_link);
else
@@ -568,8 +577,11 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
release_sock(&rx->sk);
- if (test_bit(RXRPC_CALL_RELEASED, &call->flags))
- BUG();
+ if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
+ mutex_unlock(&call->user_mutex);
+ rxrpc_put_call(call, rxrpc_call_put);
+ goto try_again;
+ }
if (test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) {
if (flags & MSG_CMSG_COMPAT) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0809/1887] iio: st_sensors: core and lsm9ds0 switch to devm_regulator_bulk_get_enable()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (807 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0808/1887] rxrpc: Fix recv-recv race of completed call Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0810/1887] iio: st_sensors: relax WhoAmI check in st_sensors_verify_id() Greg Kroah-Hartman
` (189 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron, Linus Walleij,
Andy Shevchenko, Matti Vaittinen, Nuno Sá, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
[ Upstream commit 9e855d77b1ec57704d23e25761a97e6e64abed66 ]
These drivers only turns the power on at probe and off via a custom
devm_add_action_or_reset() callback. The two regulators were handled
separately so also switch to bulk registration.
The new devm_regulator_bulk_get_enable() replaces all this boilerplate
code.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20221016163409.320197-8-jic23@kernel.org
Stable-dep-of: 9f92e93e257b ("iio: common: st_sensors: Fix use of uninitialize device structs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../iio/common/st_sensors/st_sensors_core.c | 39 ++---------
drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c | 65 ++-----------------
include/linux/iio/common/st_sensors.h | 4 --
3 files changed, 14 insertions(+), 94 deletions(-)
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index dcc032f687403..6c3705f3838d1 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -219,47 +219,22 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
}
EXPORT_SYMBOL_NS(st_sensors_set_axis_enable, IIO_ST_SENSORS);
-static void st_reg_disable(void *reg)
-{
- regulator_disable(reg);
-}
int st_sensors_power_enable(struct iio_dev *indio_dev)
{
- struct st_sensor_data *pdata = iio_priv(indio_dev);
+ static const char * const regulator_names[] = { "vdd", "vddio" };
struct device *parent = indio_dev->dev.parent;
int err;
/* Regulators not mandatory, but if requested we should enable them. */
- pdata->vdd = devm_regulator_get(parent, "vdd");
- if (IS_ERR(pdata->vdd))
- return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd),
- "unable to get Vdd supply\n");
-
- err = regulator_enable(pdata->vdd);
- if (err != 0) {
- dev_warn(&indio_dev->dev,
- "Failed to enable specified Vdd supply\n");
- return err;
- }
-
- err = devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd);
+ err = devm_regulator_bulk_get_enable(parent,
+ ARRAY_SIZE(regulator_names),
+ regulator_names);
if (err)
- return err;
+ return dev_err_probe(&indio_dev->dev, err,
+ "unable to enable supplies\n");
- pdata->vdd_io = devm_regulator_get(parent, "vddio");
- if (IS_ERR(pdata->vdd_io))
- return dev_err_probe(&indio_dev->dev, PTR_ERR(pdata->vdd_io),
- "unable to get Vdd_IO supply\n");
-
- err = regulator_enable(pdata->vdd_io);
- if (err != 0) {
- dev_warn(&indio_dev->dev,
- "Failed to enable specified Vdd_IO supply\n");
- return err;
- }
-
- return devm_add_action_or_reset(parent, st_reg_disable, pdata->vdd_io);
+ return 0;
}
EXPORT_SYMBOL_NS(st_sensors_power_enable, IIO_ST_SENSORS);
diff --git a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c
index ae7bc815382fb..e887b45cdbcd7 100644
--- a/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c
+++ b/drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c
@@ -18,58 +18,6 @@
#include "st_lsm9ds0.h"
-static int st_lsm9ds0_power_enable(struct device *dev, struct st_lsm9ds0 *lsm9ds0)
-{
- int ret;
-
- /* Regulators not mandatory, but if requested we should enable them. */
- lsm9ds0->vdd = devm_regulator_get(dev, "vdd");
- if (IS_ERR(lsm9ds0->vdd))
- return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd),
- "unable to get Vdd supply\n");
-
- ret = regulator_enable(lsm9ds0->vdd);
- if (ret) {
- dev_warn(dev, "Failed to enable specified Vdd supply\n");
- return ret;
- }
-
- lsm9ds0->vdd_io = devm_regulator_get(dev, "vddio");
- if (IS_ERR(lsm9ds0->vdd_io)) {
- regulator_disable(lsm9ds0->vdd);
- return dev_err_probe(dev, PTR_ERR(lsm9ds0->vdd_io),
- "unable to get Vdd_IO supply\n");
- }
- ret = regulator_enable(lsm9ds0->vdd_io);
- if (ret) {
- dev_warn(dev, "Failed to enable specified Vdd_IO supply\n");
- regulator_disable(lsm9ds0->vdd);
- return ret;
- }
-
- return 0;
-}
-
-static void st_lsm9ds0_power_disable(void *data)
-{
- struct st_lsm9ds0 *lsm9ds0 = data;
-
- regulator_disable(lsm9ds0->vdd_io);
- regulator_disable(lsm9ds0->vdd);
-}
-
-static int devm_st_lsm9ds0_power_enable(struct st_lsm9ds0 *lsm9ds0)
-{
- struct device *dev = lsm9ds0->dev;
- int ret;
-
- ret = st_lsm9ds0_power_enable(dev, lsm9ds0);
- if (ret)
- return ret;
-
- return devm_add_action_or_reset(dev, st_lsm9ds0_power_disable, lsm9ds0);
-}
-
static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap)
{
const struct st_sensor_settings *settings;
@@ -92,8 +40,6 @@ static int st_lsm9ds0_probe_accel(struct st_lsm9ds0 *lsm9ds0, struct regmap *reg
data->sensor_settings = (struct st_sensor_settings *)settings;
data->irq = lsm9ds0->irq;
data->regmap = regmap;
- data->vdd = lsm9ds0->vdd;
- data->vdd_io = lsm9ds0->vdd_io;
return st_accel_common_probe(lsm9ds0->accel);
}
@@ -120,19 +66,22 @@ static int st_lsm9ds0_probe_magn(struct st_lsm9ds0 *lsm9ds0, struct regmap *regm
data->sensor_settings = (struct st_sensor_settings *)settings;
data->irq = lsm9ds0->irq;
data->regmap = regmap;
- data->vdd = lsm9ds0->vdd;
- data->vdd_io = lsm9ds0->vdd_io;
return st_magn_common_probe(lsm9ds0->magn);
}
int st_lsm9ds0_probe(struct st_lsm9ds0 *lsm9ds0, struct regmap *regmap)
{
+ struct device *dev = lsm9ds0->dev;
+ static const char * const regulator_names[] = { "vdd", "vddio" };
int ret;
- ret = devm_st_lsm9ds0_power_enable(lsm9ds0);
+ /* Regulators not mandatory, but if requested we should enable them. */
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
+ regulator_names);
if (ret)
- return ret;
+ return dev_err_probe(dev, ret,
+ "unable to enable Vdd supply\n");
/* Setup accelerometer device */
ret = st_lsm9ds0_probe_accel(lsm9ds0, regmap);
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index c34e648f07e28..ae8b755955358 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -224,8 +224,6 @@ struct st_sensor_settings {
* @mount_matrix: The mounting matrix of the sensor.
* @sensor_settings: Pointer to the specific sensor settings in use.
* @current_fullscale: Maximum range of measure by the sensor.
- * @vdd: Pointer to sensor's Vdd power supply
- * @vdd_io: Pointer to sensor's Vdd-IO power supply
* @regmap: Pointer to specific sensor regmap configuration.
* @enabled: Status of the sensor (false->off, true->on).
* @odr: Output data rate of the sensor [Hz].
@@ -244,8 +242,6 @@ struct st_sensor_data {
struct iio_mount_matrix mount_matrix;
struct st_sensor_settings *sensor_settings;
struct st_sensor_fullscale_avl *current_fullscale;
- struct regulator *vdd;
- struct regulator *vdd_io;
struct regmap *regmap;
bool enabled;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0810/1887] iio: st_sensors: relax WhoAmI check in st_sensors_verify_id()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (808 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0809/1887] iio: st_sensors: core and lsm9ds0 switch to devm_regulator_bulk_get_enable() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0811/1887] iio: common: st_sensors: Fix use of uninitialize device structs Greg Kroah-Hartman
` (188 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron,
Kaustabh Chakraborty, Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaustabh Chakraborty <kauschluss@disroot.org>
[ Upstream commit a3c2c5c937ed7562b6d120670f2743e979c05881 ]
Hard matching against the WhoAmI values isn't ideal for using devices
which are compatible with existing ones. Instead of raising an error,
issue a warning instead, thus allowing the driver to continue probing.
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Link: https://patch.msgid.link/20240625082800.62305-1-kauschluss@disroot.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Stable-dep-of: 9f92e93e257b ("iio: common: st_sensors: Fix use of uninitialize device structs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/common/st_sensors/st_sensors_core.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 6c3705f3838d1..42bfd212b90bc 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -617,10 +617,9 @@ int st_sensors_verify_id(struct iio_dev *indio_dev)
}
if (sdata->sensor_settings->wai != wai) {
- dev_err(&indio_dev->dev,
+ dev_warn(&indio_dev->dev,
"%s: WhoAmI mismatch (0x%x).\n",
indio_dev->name, wai);
- return -EINVAL;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0811/1887] iio: common: st_sensors: Fix use of uninitialize device structs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (809 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0810/1887] iio: st_sensors: relax WhoAmI check in st_sensors_verify_id() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0812/1887] rxrpc: Fix bug due to prealloc collision Greg Kroah-Hartman
` (187 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maud Spierings, Andy Shevchenko,
Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maud Spierings <maudspierings@gocontroll.com>
[ Upstream commit 9f92e93e257b33e73622640a9205f8642ec16ddd ]
Throughout the various probe functions &indio_dev->dev is used before it
is initialized. This caused a kernel panic in st_sensors_power_enable()
when the call to devm_regulator_bulk_get_enable() fails and then calls
dev_err_probe() with the uninitialized device.
This seems to only cause a panic with dev_err_probe(), dev_err(),
dev_warn() and dev_info() don't seem to cause a panic, but are fixed
as well.
The issue is reported and traced here: [1]
Link: https://lore.kernel.org/all/AM7P189MB100986A83D2F28AF3FFAF976E39EA@AM7P189MB1009.EURP189.PROD.OUTLOOK.COM/ [1]
Cc: stable@vger.kernel.org
Signed-off-by: Maud Spierings <maudspierings@gocontroll.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://... [1]
Link: https://patch.msgid.link/20250527-st_iio_fix-v4-1-12d89801c761@gocontroll.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/accel/st_accel_core.c | 10 +++---
.../iio/common/st_sensors/st_sensors_core.c | 36 +++++++++----------
.../common/st_sensors/st_sensors_trigger.c | 20 +++++------
3 files changed, 31 insertions(+), 35 deletions(-)
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index c4143c5678746..a5c0ecbae271f 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -1269,6 +1269,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
union acpi_object *ont;
union acpi_object *elements;
acpi_status status;
+ struct device *parent = indio_dev->dev.parent;
int ret = -EINVAL;
unsigned int val;
int i, j;
@@ -1287,7 +1288,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
};
- adev = ACPI_COMPANION(indio_dev->dev.parent);
+ adev = ACPI_COMPANION(parent);
if (!adev)
return -ENXIO;
@@ -1296,8 +1297,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
if (status == AE_NOT_FOUND) {
return -ENXIO;
} else if (ACPI_FAILURE(status)) {
- dev_warn(&indio_dev->dev, "failed to execute _ONT: %d\n",
- status);
+ dev_warn(parent, "failed to execute _ONT: %d\n", status);
return status;
}
@@ -1373,12 +1373,12 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
}
ret = 0;
- dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n");
+ dev_info(parent, "computed mount matrix from ACPI\n");
out:
kfree(buffer.pointer);
if (ret)
- dev_dbg(&indio_dev->dev,
+ dev_dbg(parent,
"failed to apply ACPI orientation data: %d\n", ret);
return ret;
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 42bfd212b90bc..2a645c359fb58 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -154,7 +154,7 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
return err;
st_accel_set_fullscale_error:
- dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
+ dev_err(indio_dev->dev.parent, "failed to set new fullscale.\n");
return err;
}
@@ -231,8 +231,7 @@ int st_sensors_power_enable(struct iio_dev *indio_dev)
ARRAY_SIZE(regulator_names),
regulator_names);
if (err)
- return dev_err_probe(&indio_dev->dev, err,
- "unable to enable supplies\n");
+ return dev_err_probe(parent, err, "unable to enable supplies\n");
return 0;
}
@@ -241,13 +240,14 @@ EXPORT_SYMBOL_NS(st_sensors_power_enable, IIO_ST_SENSORS);
static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
+ struct device *parent = indio_dev->dev.parent;
struct st_sensor_data *sdata = iio_priv(indio_dev);
/* Sensor does not support interrupts */
if (!sdata->sensor_settings->drdy_irq.int1.addr &&
!sdata->sensor_settings->drdy_irq.int2.addr) {
if (pdata->drdy_int_pin)
- dev_info(&indio_dev->dev,
+ dev_info(parent,
"DRDY on pin INT%d specified, but sensor does not support interrupts\n",
pdata->drdy_int_pin);
return 0;
@@ -256,29 +256,27 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
switch (pdata->drdy_int_pin) {
case 1:
if (!sdata->sensor_settings->drdy_irq.int1.mask) {
- dev_err(&indio_dev->dev,
- "DRDY on INT1 not available.\n");
+ dev_err(parent, "DRDY on INT1 not available.\n");
return -EINVAL;
}
sdata->drdy_int_pin = 1;
break;
case 2:
if (!sdata->sensor_settings->drdy_irq.int2.mask) {
- dev_err(&indio_dev->dev,
- "DRDY on INT2 not available.\n");
+ dev_err(parent, "DRDY on INT2 not available.\n");
return -EINVAL;
}
sdata->drdy_int_pin = 2;
break;
default:
- dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
+ dev_err(parent, "DRDY on pdata not valid.\n");
return -EINVAL;
}
if (pdata->open_drain) {
if (!sdata->sensor_settings->drdy_irq.int1.addr_od &&
!sdata->sensor_settings->drdy_irq.int2.addr_od)
- dev_err(&indio_dev->dev,
+ dev_err(parent,
"open drain requested but unsupported.\n");
else
sdata->int_pin_open_drain = true;
@@ -336,6 +334,7 @@ EXPORT_SYMBOL_NS(st_sensors_dev_name_probe, IIO_ST_SENSORS);
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
+ struct device *parent = indio_dev->dev.parent;
struct st_sensor_data *sdata = iio_priv(indio_dev);
struct st_sensors_platform_data *of_pdata;
int err = 0;
@@ -343,7 +342,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
mutex_init(&sdata->odr_lock);
/* If OF/DT pdata exists, it will take precedence of anything else */
- of_pdata = st_sensors_dev_probe(indio_dev->dev.parent, pdata);
+ of_pdata = st_sensors_dev_probe(parent, pdata);
if (IS_ERR(of_pdata))
return PTR_ERR(of_pdata);
if (of_pdata)
@@ -370,7 +369,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
if (err < 0)
return err;
} else
- dev_info(&indio_dev->dev, "Full-scale not possible\n");
+ dev_info(parent, "Full-scale not possible\n");
err = st_sensors_set_odr(indio_dev, sdata->odr);
if (err < 0)
@@ -405,7 +404,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
mask = sdata->sensor_settings->drdy_irq.int2.mask_od;
}
- dev_info(&indio_dev->dev,
+ dev_info(parent,
"set interrupt line to open drain mode on pin %d\n",
sdata->drdy_int_pin);
err = st_sensors_write_data_with_mask(indio_dev, addr,
@@ -605,21 +604,20 @@ EXPORT_SYMBOL_NS(st_sensors_get_settings_index, IIO_ST_SENSORS);
int st_sensors_verify_id(struct iio_dev *indio_dev)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct device *parent = indio_dev->dev.parent;
int wai, err;
if (sdata->sensor_settings->wai_addr) {
err = regmap_read(sdata->regmap,
sdata->sensor_settings->wai_addr, &wai);
if (err < 0) {
- dev_err(&indio_dev->dev,
- "failed to read Who-Am-I register.\n");
- return err;
+ return dev_err_probe(parent, err,
+ "failed to read Who-Am-I register.\n");
}
if (sdata->sensor_settings->wai != wai) {
- dev_warn(&indio_dev->dev,
- "%s: WhoAmI mismatch (0x%x).\n",
- indio_dev->name, wai);
+ dev_warn(parent, "%s: WhoAmI mismatch (0x%x).\n",
+ indio_dev->name, wai);
}
}
diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c
index 899b640c0a70c..6672946702edd 100644
--- a/drivers/iio/common/st_sensors/st_sensors_trigger.c
+++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c
@@ -127,7 +127,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->trig = devm_iio_trigger_alloc(parent, "%s-trigger",
indio_dev->name);
if (sdata->trig == NULL) {
- dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n");
+ dev_err(parent, "failed to allocate iio trigger.\n");
return -ENOMEM;
}
@@ -143,7 +143,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
case IRQF_TRIGGER_FALLING:
case IRQF_TRIGGER_LOW:
if (!sdata->sensor_settings->drdy_irq.addr_ihl) {
- dev_err(&indio_dev->dev,
+ dev_err(parent,
"falling/low specified for IRQ but hardware supports only rising/high: will request rising/high\n");
if (irq_trig == IRQF_TRIGGER_FALLING)
irq_trig = IRQF_TRIGGER_RISING;
@@ -156,21 +156,19 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->sensor_settings->drdy_irq.mask_ihl, 1);
if (err < 0)
return err;
- dev_info(&indio_dev->dev,
+ dev_info(parent,
"interrupts on the falling edge or active low level\n");
}
break;
case IRQF_TRIGGER_RISING:
- dev_info(&indio_dev->dev,
- "interrupts on the rising edge\n");
+ dev_info(parent, "interrupts on the rising edge\n");
break;
case IRQF_TRIGGER_HIGH:
- dev_info(&indio_dev->dev,
- "interrupts active high level\n");
+ dev_info(parent, "interrupts active high level\n");
break;
default:
/* This is the most preferred mode, if possible */
- dev_err(&indio_dev->dev,
+ dev_err(parent,
"unsupported IRQ trigger specified (%lx), enforce rising edge\n", irq_trig);
irq_trig = IRQF_TRIGGER_RISING;
}
@@ -179,7 +177,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
if (irq_trig == IRQF_TRIGGER_FALLING ||
irq_trig == IRQF_TRIGGER_RISING) {
if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) {
- dev_err(&indio_dev->dev,
+ dev_err(parent,
"edge IRQ not supported w/o stat register.\n");
return -EOPNOTSUPP;
}
@@ -214,13 +212,13 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->trig->name,
sdata->trig);
if (err) {
- dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n");
+ dev_err(parent, "failed to request trigger IRQ.\n");
return err;
}
err = devm_iio_trigger_register(parent, sdata->trig);
if (err < 0) {
- dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
+ dev_err(parent, "failed to register iio trigger.\n");
return err;
}
indio_dev->trig = iio_trigger_get(sdata->trig);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0812/1887] rxrpc: Fix bug due to prealloc collision
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (810 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0811/1887] iio: common: st_sensors: Fix use of uninitialize device structs Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0813/1887] RDMA/hns: Fix double destruction of rsv_qp Greg Kroah-Hartman
` (186 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junvyyang, Tencent Zhuque Lab,
David Howells, LePremierHomme, Marc Dionne, Simon Horman,
linux-afs, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 69e4186773c6445b258fb45b6e1df18df831ec45 ]
When userspace is using AF_RXRPC to provide a server, it has to preallocate
incoming calls and assign to them call IDs that will be used to thread
related recvmsg() and sendmsg() together. The preallocated call IDs will
automatically be attached to calls as they come in until the pool is empty.
To the kernel, the call IDs are just arbitrary numbers, but userspace can
use the call ID to hold a pointer to prepared structs. In any case, the
user isn't permitted to create two calls with the same call ID (call IDs
become available again when the call ends) and EBADSLT should result from
sendmsg() if an attempt is made to preallocate a call with an in-use call
ID.
However, the cleanup in the error handling will trigger both assertions in
rxrpc_cleanup_call() because the call isn't marked complete and isn't
marked as having been released.
Fix this by setting the call state in rxrpc_service_prealloc_one() and then
marking it as being released before calling the cleanup function.
Fixes: 00e907127e6f ("rxrpc: Preallocate peers, conns and calls for incoming service requests")
Reported-by: Junvyyang, Tencent Zhuque Lab <zhuque@tencent.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: LePremierHomme <kwqcheii@proton.me>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250708211506.2699012-2-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rxrpc/call_accept.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
index 4a1e5d7a07262..8001c330b2be6 100644
--- a/net/rxrpc/call_accept.c
+++ b/net/rxrpc/call_accept.c
@@ -151,6 +151,11 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
id_in_use:
write_unlock(&rx->call_lock);
+ call->abort_code = RX_CALL_DEAD;
+ call->error = -EBADSLT;
+ call->completion = RXRPC_CALL_LOCAL_ERROR;
+ call->state = RXRPC_CALL_COMPLETE;
+ set_bit(RXRPC_CALL_RELEASED, &call->flags);
rxrpc_cleanup_call(call);
_leave(" = -EBADSLT");
return -EBADSLT;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0813/1887] RDMA/hns: Fix double destruction of rsv_qp
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (811 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0812/1887] rxrpc: Fix bug due to prealloc collision Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0814/1887] net/mlx5e: Provide intermediate pointer to access IPsec struct Greg Kroah-Hartman
` (185 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, wenglianfa, Junxian Huang,
Leon Romanovsky, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <wenglianfa@huawei.com>
[ Upstream commit c6957b95ecc5b63c5a4bb4ecc28af326cf8f6dc8 ]
rsv_qp may be double destroyed in error flow, first in free_mr_init(),
and then in hns_roce_exit(). Fix it by moving the free_mr_init() call
into hns_roce_v2_init().
list_del corruption, ffff589732eb9b50->next is LIST_POISON1 (dead000000000100)
WARNING: CPU: 8 PID: 1047115 at lib/list_debug.c:53 __list_del_entry_valid+0x148/0x240
...
Call trace:
__list_del_entry_valid+0x148/0x240
hns_roce_qp_remove+0x4c/0x3f0 [hns_roce_hw_v2]
hns_roce_v2_destroy_qp_common+0x1dc/0x5f4 [hns_roce_hw_v2]
hns_roce_v2_destroy_qp+0x22c/0x46c [hns_roce_hw_v2]
free_mr_exit+0x6c/0x120 [hns_roce_hw_v2]
hns_roce_v2_exit+0x170/0x200 [hns_roce_hw_v2]
hns_roce_exit+0x118/0x350 [hns_roce_hw_v2]
__hns_roce_hw_v2_init_instance+0x1c8/0x304 [hns_roce_hw_v2]
hns_roce_hw_v2_reset_notify_init+0x170/0x21c [hns_roce_hw_v2]
hns_roce_hw_v2_reset_notify+0x6c/0x190 [hns_roce_hw_v2]
hclge_notify_roce_client+0x6c/0x160 [hclge]
hclge_reset_rebuild+0x150/0x5c0 [hclge]
hclge_reset+0x10c/0x140 [hclge]
hclge_reset_subtask+0x80/0x104 [hclge]
hclge_reset_service_task+0x168/0x3ac [hclge]
hclge_service_task+0x50/0x100 [hclge]
process_one_work+0x250/0x9a0
worker_thread+0x324/0x990
kthread+0x190/0x210
ret_from_fork+0x10/0x18
Fixes: fd8489294dd2 ("RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08")
Signed-off-by: wenglianfa <wenglianfa@huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20250703113905.3597124-2-huangjunxian6@hisilicon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 25 +++++++++++-----------
drivers/infiniband/hw/hns/hns_roce_main.c | 5 +++--
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 1c180a6b1c078..122be4aae304d 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -3013,14 +3013,22 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
{
int ret;
+ if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
+ ret = free_mr_init(hr_dev);
+ if (ret) {
+ dev_err(hr_dev->dev, "failed to init free mr!\n");
+ return ret;
+ }
+ }
+
/* The hns ROCEE requires the extdb info to be cleared before using */
ret = hns_roce_clear_extdb_list_info(hr_dev);
if (ret)
- return ret;
+ goto err_clear_extdb_failed;
ret = get_hem_table(hr_dev);
if (ret)
- return ret;
+ goto err_clear_extdb_failed;
if (hr_dev->is_vf)
return 0;
@@ -3035,6 +3043,9 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
err_llm_init_failed:
put_hem_table(hr_dev);
+err_clear_extdb_failed:
+ if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08)
+ free_mr_exit(hr_dev);
return ret;
}
@@ -6939,21 +6950,11 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
goto error_failed_roce_init;
}
- if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
- ret = free_mr_init(hr_dev);
- if (ret) {
- dev_err(hr_dev->dev, "failed to init free mr!\n");
- goto error_failed_free_mr_init;
- }
- }
handle->priv = hr_dev;
return 0;
-error_failed_free_mr_init:
- hns_roce_exit(hr_dev);
-
error_failed_roce_init:
kfree(hr_dev->priv);
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index 5702176a733ab..e6eca4105c1a9 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -835,6 +835,9 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
spin_lock_init(&hr_dev->sm_lock);
+ INIT_LIST_HEAD(&hr_dev->qp_list);
+ spin_lock_init(&hr_dev->qp_list_lock);
+
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_CQ_RECORD_DB ||
hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_RECORD_DB) {
INIT_LIST_HEAD(&hr_dev->pgdir_list);
@@ -979,8 +982,6 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
}
}
- INIT_LIST_HEAD(&hr_dev->qp_list);
- spin_lock_init(&hr_dev->qp_list_lock);
INIT_LIST_HEAD(&hr_dev->dip_list);
spin_lock_init(&hr_dev->dip_list_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0814/1887] net/mlx5e: Provide intermediate pointer to access IPsec struct
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (812 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0813/1887] RDMA/hns: Fix double destruction of rsv_qp Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0815/1887] net/mlx5e: Remove skb secpath if xfrm state is not found Greg Kroah-Hartman
` (184 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Saeed Mahameed, Leon Romanovsky,
Steffen Klassert, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <leonro@nvidia.com>
[ Upstream commit 7bddb659bd0fc4e9022d3a3a2260540c01856e68 ]
Improve readability by providing direct pointer to struct mlx5e_ipsec.
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Stable-dep-of: 6d19c44b5c6d ("net/mlx5e: Remove skb secpath if xfrm state is not found")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
index c4a84f0a3b733..318695a6aba2c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
@@ -314,23 +314,23 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
struct mlx5_cqe64 *cqe)
{
u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
- struct mlx5e_priv *priv;
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5e_ipsec *ipsec = priv->ipsec;
struct xfrm_offload *xo;
struct xfrm_state *xs;
struct sec_path *sp;
u32 sa_handle;
sa_handle = MLX5_IPSEC_METADATA_HANDLE(ipsec_meta_data);
- priv = netdev_priv(netdev);
sp = secpath_set(skb);
if (unlikely(!sp)) {
- atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sp_alloc);
+ atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_sp_alloc);
return;
}
- xs = mlx5e_ipsec_sadb_rx_lookup(priv->ipsec, sa_handle);
+ xs = mlx5e_ipsec_sadb_rx_lookup(ipsec, sa_handle);
if (unlikely(!xs)) {
- atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
+ atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
return;
}
@@ -351,6 +351,6 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
xo->status = CRYPTO_INVALID_PACKET_SYNTAX;
break;
default:
- atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome);
+ atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_syndrome);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0815/1887] net/mlx5e: Remove skb secpath if xfrm state is not found
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (813 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0814/1887] net/mlx5e: Provide intermediate pointer to access IPsec struct Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0816/1887] xen: fix UAF in dmabuf_exp_from_pages() Greg Kroah-Hartman
` (183 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jianbo Liu, Dragos Tatulea,
Yael Chemla, Tariq Toukan, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <jianbol@nvidia.com>
[ Upstream commit 6d19c44b5c6dd72f9a357d0399604ec16a77de3c ]
Hardware returns a unique identifier for a decrypted packet's xfrm
state, this state is looked up in an xarray. However, the state might
have been freed by the time of this lookup.
Currently, if the state is not found, only a counter is incremented.
The secpath (sp) extension on the skb is not removed, resulting in
sp->len becoming 0.
Subsequently, functions like __xfrm_policy_check() attempt to access
fields such as xfrm_input_state(skb)->xso.type (which dereferences
sp->xvec[sp->len - 1]) without first validating sp->len. This leads to
a crash when dereferencing an invalid state pointer.
This patch prevents the crash by explicitly removing the secpath
extension from the skb if the xfrm state is not found after hardware
decryption. This ensures downstream functions do not operate on a
zero-length secpath.
BUG: unable to handle page fault for address: ffffffff000002c8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 282e067 P4D 282e067 PUD 0
Oops: Oops: 0000 [#1] SMP
CPU: 12 UID: 0 PID: 0 Comm: swapper/12 Not tainted 6.15.0-rc7_for_upstream_min_debug_2025_05_27_22_44 #1 NONE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:__xfrm_policy_check+0x61a/0xa30
Code: b6 77 7f 83 e6 02 74 14 4d 8b af d8 00 00 00 41 0f b6 45 05 c1 e0 03 48 98 49 01 c5 41 8b 45 00 83 e8 01 48 98 49 8b 44 c5 10 <0f> b6 80 c8 02 00 00 83 e0 0c 3c 04 0f 84 0c 02 00 00 31 ff 80 fa
RSP: 0018:ffff88885fb04918 EFLAGS: 00010297
RAX: ffffffff00000000 RBX: 0000000000000002 RCX: 0000000000000000
RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000000
RBP: ffffffff8311af80 R08: 0000000000000020 R09: 00000000c2eda353
R10: ffff88812be2bbc8 R11: 000000001faab533 R12: ffff88885fb049c8
R13: ffff88812be2bbc8 R14: 0000000000000000 R15: ffff88811896ae00
FS: 0000000000000000(0000) GS:ffff8888dca82000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffff000002c8 CR3: 0000000243050002 CR4: 0000000000372eb0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<IRQ>
? try_to_wake_up+0x108/0x4c0
? udp4_lib_lookup2+0xbe/0x150
? udp_lib_lport_inuse+0x100/0x100
? __udp4_lib_lookup+0x2b0/0x410
__xfrm_policy_check2.constprop.0+0x11e/0x130
udp_queue_rcv_one_skb+0x1d/0x530
udp_unicast_rcv_skb+0x76/0x90
__udp4_lib_rcv+0xa64/0xe90
ip_protocol_deliver_rcu+0x20/0x130
ip_local_deliver_finish+0x75/0xa0
ip_local_deliver+0xc1/0xd0
? ip_protocol_deliver_rcu+0x130/0x130
ip_sublist_rcv+0x1f9/0x240
? ip_rcv_finish_core+0x430/0x430
ip_list_rcv+0xfc/0x130
__netif_receive_skb_list_core+0x181/0x1e0
netif_receive_skb_list_internal+0x200/0x360
? mlx5e_build_rx_skb+0x1bc/0xda0 [mlx5_core]
gro_receive_skb+0xfd/0x210
mlx5e_handle_rx_cqe_mpwrq+0x141/0x280 [mlx5_core]
mlx5e_poll_rx_cq+0xcc/0x8e0 [mlx5_core]
? mlx5e_handle_rx_dim+0x91/0xd0 [mlx5_core]
mlx5e_napi_poll+0x114/0xab0 [mlx5_core]
__napi_poll+0x25/0x170
net_rx_action+0x32d/0x3a0
? mlx5_eq_comp_int+0x8d/0x280 [mlx5_core]
? notifier_call_chain+0x33/0xa0
handle_softirqs+0xda/0x250
irq_exit_rcu+0x6d/0xc0
common_interrupt+0x81/0xa0
</IRQ>
Fixes: b2ac7541e377 ("net/mlx5e: IPsec: Add Connect-X IPsec Rx data path offload")
Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Yael Chemla <ychemla@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/1753256672-337784-3-git-send-email-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
index 318695a6aba2c..9646abc630ae1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
@@ -331,6 +331,10 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
xs = mlx5e_ipsec_sadb_rx_lookup(ipsec, sa_handle);
if (unlikely(!xs)) {
atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
+ /* Clear secpath to prevent invalid dereference
+ * in downstream XFRM policy checks.
+ */
+ secpath_reset(skb);
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0816/1887] xen: fix UAF in dmabuf_exp_from_pages()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (814 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0815/1887] net/mlx5e: Remove skb secpath if xfrm state is not found Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0817/1887] drm/rockchip: vop2: fail cleanly if missing a primary plane for a video-port Greg Kroah-Hartman
` (182 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Al Viro, Juergen Gross, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
[ Upstream commit 532c8b51b3a8676cbf533a291f8156774f30ea87 ]
[dma_buf_fd() fixes; no preferences regarding the tree it goes through -
up to xen folks]
As soon as we'd inserted a file reference into descriptor table, another
thread could close it. That's fine for the case when all we are doing is
returning that descriptor to userland (it's a race, but it's a userland
race and there's nothing the kernel can do about it). However, if we
follow fd_install() with any kind of access to objects that would be
destroyed on close (be it the struct file itself or anything destroyed
by its ->release()), we have a UAF.
dma_buf_fd() is a combination of reserving a descriptor and fd_install().
gntdev dmabuf_exp_from_pages() calls it and then proceeds to access the
objects destroyed on close - starting with gntdev_dmabuf itself.
Fix that by doing reserving descriptor before anything else and do
fd_install() only when everything had been set up.
Fixes: a240d6e42e28 ("xen/gntdev: Implement dma-buf export functionality")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Juergen Gross <jgross@suse.com>
Message-ID: <20250712050916.GY1880847@ZenIV>
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/gntdev-dmabuf.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 335451309566a..7df26330af424 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -357,8 +357,12 @@ struct gntdev_dmabuf_export_args {
static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
{
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
- struct gntdev_dmabuf *gntdev_dmabuf;
- int ret;
+ struct gntdev_dmabuf *gntdev_dmabuf __free(kfree) = NULL;
+ CLASS(get_unused_fd, ret)(O_CLOEXEC);
+ int fd;
+
+ if (ret < 0)
+ return ret;
gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL);
if (!gntdev_dmabuf)
@@ -383,32 +387,23 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args)
exp_info.priv = gntdev_dmabuf;
gntdev_dmabuf->dmabuf = dma_buf_export(&exp_info);
- if (IS_ERR(gntdev_dmabuf->dmabuf)) {
- ret = PTR_ERR(gntdev_dmabuf->dmabuf);
- gntdev_dmabuf->dmabuf = NULL;
- goto fail;
- }
-
- ret = dma_buf_fd(gntdev_dmabuf->dmabuf, O_CLOEXEC);
- if (ret < 0)
- goto fail;
+ if (IS_ERR(gntdev_dmabuf->dmabuf))
+ return PTR_ERR(gntdev_dmabuf->dmabuf);
gntdev_dmabuf->fd = ret;
args->fd = ret;
pr_debug("Exporting DMA buffer with fd %d\n", ret);
+ get_file(gntdev_dmabuf->priv->filp);
mutex_lock(&args->dmabuf_priv->lock);
list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list);
mutex_unlock(&args->dmabuf_priv->lock);
- get_file(gntdev_dmabuf->priv->filp);
- return 0;
-fail:
- if (gntdev_dmabuf->dmabuf)
- dma_buf_put(gntdev_dmabuf->dmabuf);
- kfree(gntdev_dmabuf);
- return ret;
+ fd = ret;
+ ret = -EBADF;
+ fd_install(fd, no_free_ptr(gntdev_dmabuf)->dmabuf->file);
+ return 0;
}
static struct gntdev_grant_map *
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0817/1887] drm/rockchip: vop2: fail cleanly if missing a primary plane for a video-port
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (815 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0816/1887] xen: fix UAF in dmabuf_exp_from_pages() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0818/1887] fs/ntfs3: cancle set bad inode after removing name fails Greg Kroah-Hartman
` (181 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Andy Yan, Heiko Stuebner,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Stuebner <heiko@sntech.de>
[ Upstream commit f9f68bf1d0efeadb6c427c9dbb30f307a7def19b ]
Each window of a vop2 is usable by a specific set of video ports, so while
binding the vop2, we look through the list of available windows trying to
find one designated as primary-plane and usable by that specific port.
The code later wants to use drm_crtc_init_with_planes with that found
primary plane, but nothing has checked so far if a primary plane was
actually found.
For whatever reason, the rk3576 vp2 does not have a usable primary window
(if vp0 is also in use) which brought the issue to light and ended in a
null-pointer dereference further down.
As we expect a primary-plane to exist for a video-port, add a check at
the end of the window-iteration and fail probing if none was found.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reviewed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20250610212748.1062375-1-heiko@sntech.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 1a17e9c1e8335..608b0d681b217 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2409,6 +2409,10 @@ static int vop2_create_crtc(struct vop2 *vop2)
if (!vp->crtc.port)
continue;
+ if (!vp->primary_plane)
+ return dev_err_probe(drm->dev, -ENOENT,
+ "no primary plane for vp %d\n", i);
+
plane = &vp->primary_plane->base;
ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0818/1887] fs/ntfs3: cancle set bad inode after removing name fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (816 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0817/1887] drm/rockchip: vop2: fail cleanly if missing a primary plane for a video-port Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0819/1887] rv: Use strings in da monitors tracepoints Greg Kroah-Hartman
` (180 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1aa90f0eb1fc3e77d969,
Edward Adam Davis, Konstantin Komarov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit d99208b91933fd2a58ed9ed321af07dacd06ddc3 ]
The reproducer uses a file0 on a ntfs3 file system with a corrupted i_link.
When renaming, the file0's inode is marked as a bad inode because the file
name cannot be deleted.
The underlying bug is that make_bad_inode() is called on a live inode.
In some cases it's "icache lookup finds a normal inode, d_splice_alias()
is called to attach it to dentry, while another thread decides to call
make_bad_inode() on it - that would evict it from icache, but we'd already
found it there earlier".
In some it's outright "we have an inode attached to dentry - that's how we
got it in the first place; let's call make_bad_inode() on it just for shits
and giggles".
Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations")
Reported-by: syzbot+1aa90f0eb1fc3e77d969@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1aa90f0eb1fc3e77d969
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/frecord.c | 7 +++----
fs/ntfs3/namei.c | 10 +++-------
fs/ntfs3/ntfs_fs.h | 3 +--
3 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 240983bac9c3c..a44b7338621e0 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -3170,8 +3170,7 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
* ni_rename - Remove one name and insert new name.
*/
int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
- struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
- bool *is_bad)
+ struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de)
{
int err;
struct NTFS_DE *de2 = NULL;
@@ -3194,8 +3193,8 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
err = ni_add_name(new_dir_ni, ni, new_de);
if (!err) {
err = ni_remove_name(dir_ni, ni, de, &de2, &undo);
- if (err && ni_remove_name(new_dir_ni, ni, new_de, &de2, &undo))
- *is_bad = true;
+ WARN_ON(err && ni_remove_name(new_dir_ni, ni, new_de, &de2,
+ &undo));
}
/*
diff --git a/fs/ntfs3/namei.c b/fs/ntfs3/namei.c
index 7b7634b38eea8..1adbc4af6aba8 100644
--- a/fs/ntfs3/namei.c
+++ b/fs/ntfs3/namei.c
@@ -250,7 +250,7 @@ static int ntfs_rename(struct user_namespace *mnt_userns, struct inode *dir,
struct ntfs_inode *ni = ntfs_i(inode);
struct inode *new_inode = d_inode(new_dentry);
struct NTFS_DE *de, *new_de;
- bool is_same, is_bad;
+ bool is_same;
/*
* de - memory of PATH_MAX bytes:
* [0-1024) - original name (dentry->d_name)
@@ -314,12 +314,8 @@ static int ntfs_rename(struct user_namespace *mnt_userns, struct inode *dir,
ni_lock_dir(dir_ni);
ni_lock(ni);
- is_bad = false;
- err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de, &is_bad);
- if (is_bad) {
- /* Restore after failed rename failed too. */
- _ntfs_bad_inode(inode);
- } else if (!err) {
+ err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de);
+ if (!err) {
inode->i_ctime = dir->i_ctime = dir->i_mtime =
current_time(dir);
mark_inode_dirty(inode);
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index d29fdefb477bf..34179fba57db8 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -573,8 +573,7 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
struct NTFS_DE *de);
int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
- struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
- bool *is_bad);
+ struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de);
bool ni_is_dirty(struct inode *inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0819/1887] rv: Use strings in da monitors tracepoints
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (817 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0818/1887] fs/ntfs3: cancle set bad inode after removing name fails Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0820/1887] exfat: remove unnecessary arguments from exfat_find_dir_entry() Greg Kroah-Hartman
` (179 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Ingo Molnar,
Peter Zijlstra, Tomas Glozar, Juri Lelli, Clark Williams,
John Kacur, Nam Cao, Gabriele Monaco, Steven Rostedt (Google),
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriele Monaco <gmonaco@redhat.com>
[ Upstream commit 7f904ff6e58d398c4336f3c19c42b338324451f7 ]
Using DA monitors tracepoints with KASAN enabled triggers the following
warning:
BUG: KASAN: global-out-of-bounds in do_trace_event_raw_event_event_da_monitor+0xd6/0x1a0
Read of size 32 at addr ffffffffaada8980 by task ...
Call Trace:
<TASK>
[...]
do_trace_event_raw_event_event_da_monitor+0xd6/0x1a0
? __pfx_do_trace_event_raw_event_event_da_monitor+0x10/0x10
? trace_event_sncid+0x83/0x200
trace_event_sncid+0x163/0x200
[...]
The buggy address belongs to the variable:
automaton_snep+0x4e0/0x5e0
This is caused by the tracepoints reading 32 bytes __array instead of
__string from the automata definition. Such strings are literals and
reading 32 bytes ends up in out of bound memory accesses (e.g. the next
automaton's data in this case).
The error is harmless as, while printing the string, we stop at the null
terminator, but it should still be fixed.
Use the __string facilities while defining the tracepoints to avoid
reading out of bound memory.
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tomas Glozar <tglozar@redhat.com>
Cc: Juri Lelli <jlelli@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
Link: https://lore.kernel.org/20250728135022.255578-4-gmonaco@redhat.com
Fixes: 792575348ff7 ("rv/include: Add deterministic automata monitor definition via C macros")
Reviewed-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/trace/events/rv.h | 76 +++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/include/trace/events/rv.h b/include/trace/events/rv.h
index 56592da9301c0..da213b91da330 100644
--- a/include/trace/events/rv.h
+++ b/include/trace/events/rv.h
@@ -16,23 +16,23 @@ DECLARE_EVENT_CLASS(event_da_monitor,
TP_ARGS(state, event, next_state, final_state),
TP_STRUCT__entry(
- __array( char, state, MAX_DA_NAME_LEN )
- __array( char, event, MAX_DA_NAME_LEN )
- __array( char, next_state, MAX_DA_NAME_LEN )
- __field( bool, final_state )
+ __string( state, state )
+ __string( event, event )
+ __string( next_state, next_state )
+ __field( bool, final_state )
),
TP_fast_assign(
- memcpy(__entry->state, state, MAX_DA_NAME_LEN);
- memcpy(__entry->event, event, MAX_DA_NAME_LEN);
- memcpy(__entry->next_state, next_state, MAX_DA_NAME_LEN);
- __entry->final_state = final_state;
+ __assign_str(state, state);
+ __assign_str(event, event);
+ __assign_str(next_state, next_state);
+ __entry->final_state = final_state;
),
TP_printk("%s x %s -> %s %s",
- __entry->state,
- __entry->event,
- __entry->next_state,
+ __get_str(state),
+ __get_str(event),
+ __get_str(next_state),
__entry->final_state ? "(final)" : "")
);
@@ -43,18 +43,18 @@ DECLARE_EVENT_CLASS(error_da_monitor,
TP_ARGS(state, event),
TP_STRUCT__entry(
- __array( char, state, MAX_DA_NAME_LEN )
- __array( char, event, MAX_DA_NAME_LEN )
+ __string( state, state )
+ __string( event, event )
),
TP_fast_assign(
- memcpy(__entry->state, state, MAX_DA_NAME_LEN);
- memcpy(__entry->event, event, MAX_DA_NAME_LEN);
+ __assign_str(state, state);
+ __assign_str(event, event);
),
TP_printk("event %s not expected in the state %s",
- __entry->event,
- __entry->state)
+ __get_str(event),
+ __get_str(state))
);
#ifdef CONFIG_RV_MON_WIP
@@ -76,26 +76,26 @@ DECLARE_EVENT_CLASS(event_da_monitor_id,
TP_ARGS(id, state, event, next_state, final_state),
TP_STRUCT__entry(
- __field( int, id )
- __array( char, state, MAX_DA_NAME_LEN )
- __array( char, event, MAX_DA_NAME_LEN )
- __array( char, next_state, MAX_DA_NAME_LEN )
- __field( bool, final_state )
+ __field( int, id )
+ __string( state, state )
+ __string( event, event )
+ __string( next_state, next_state )
+ __field( bool, final_state )
),
TP_fast_assign(
- memcpy(__entry->state, state, MAX_DA_NAME_LEN);
- memcpy(__entry->event, event, MAX_DA_NAME_LEN);
- memcpy(__entry->next_state, next_state, MAX_DA_NAME_LEN);
- __entry->id = id;
- __entry->final_state = final_state;
+ __assign_str(state, state);
+ __assign_str(event, event);
+ __assign_str(next_state, next_state);
+ __entry->id = id;
+ __entry->final_state = final_state;
),
TP_printk("%d: %s x %s -> %s %s",
__entry->id,
- __entry->state,
- __entry->event,
- __entry->next_state,
+ __get_str(state),
+ __get_str(event),
+ __get_str(next_state),
__entry->final_state ? "(final)" : "")
);
@@ -106,21 +106,21 @@ DECLARE_EVENT_CLASS(error_da_monitor_id,
TP_ARGS(id, state, event),
TP_STRUCT__entry(
- __field( int, id )
- __array( char, state, MAX_DA_NAME_LEN )
- __array( char, event, MAX_DA_NAME_LEN )
+ __field( int, id )
+ __string( state, state )
+ __string( event, event )
),
TP_fast_assign(
- memcpy(__entry->state, state, MAX_DA_NAME_LEN);
- memcpy(__entry->event, event, MAX_DA_NAME_LEN);
- __entry->id = id;
+ __assign_str(state, state);
+ __assign_str(event, event);
+ __entry->id = id;
),
TP_printk("%d: event %s not expected in the state %s",
__entry->id,
- __entry->event,
- __entry->state)
+ __get_str(event),
+ __get_str(state))
);
#ifdef CONFIG_RV_MON_WWNR
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0820/1887] exfat: remove unnecessary arguments from exfat_find_dir_entry()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (818 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0819/1887] rv: Use strings in da monitors tracepoints Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0821/1887] exfat: add cluster chain loop check for dir Greg Kroah-Hartman
` (178 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuezhang Mo, Andy Wu, Aoyama Wataru,
Sungjong Seo, Namjae Jeon, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <Yuezhang.Mo@sony.com>
[ Upstream commit 72880cb5f157514d797d5f6ab3184bbde671a18a ]
This commit removes argument 'num_entries' and 'type' from
exfat_find_dir_entry().
Code refinement, no functional changes.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: 99f9a97dce39 ("exfat: add cluster chain loop check for dir")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/exfat/dir.c | 12 +++++++-----
fs/exfat/exfat_fs.h | 3 +--
fs/exfat/namei.c | 10 ++--------
3 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index dc12e463be1a0..dda10bca9ac98 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -931,7 +931,7 @@ enum {
*/
int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
- int num_entries, unsigned int type, struct exfat_hint *hint_opt)
+ struct exfat_hint *hint_opt)
{
int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
int order, step, name_len = 0;
@@ -942,6 +942,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_hint *hint_stat = &ei->hint_stat;
struct exfat_hint_femp candi_empty;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ int num_entries = exfat_calc_num_entries(p_uniname);
+
+ if (num_entries < 0)
+ return num_entries;
dentries_per_clu = sbi->dentries_per_clu;
@@ -1010,10 +1014,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
step = DIRENT_STEP_FILE;
hint_opt->clu = clu.dir;
hint_opt->eidx = i;
- if (type == TYPE_ALL || type == entry_type) {
- num_ext = ep->dentry.file.num_ext;
- step = DIRENT_STEP_STRM;
- }
+ num_ext = ep->dentry.file.num_ext;
+ step = DIRENT_STEP_STRM;
brelse(bh);
continue;
}
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 5a1251207ab22..eae52c5b20b2b 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -62,7 +62,6 @@ enum {
#define TYPE_PADDING 0x0402
#define TYPE_ACLTAB 0x0403
#define TYPE_BENIGN_SEC 0x0800
-#define TYPE_ALL 0x0FFF
#define MAX_CHARSET_SIZE 6 /* max size of multi-byte character */
#define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */
@@ -467,7 +466,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es);
int exfat_calc_num_entries(struct exfat_uni_name *p_uniname);
int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
- int num_entries, unsigned int type, struct exfat_hint *hint_opt);
+ struct exfat_hint *hint_opt);
int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu);
struct exfat_dentry *exfat_get_dentry(struct super_block *sb,
struct exfat_chain *p_dir, int entry, struct buffer_head **bh);
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index ae36930408e6b..7f84ea80c8a6c 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -600,7 +600,7 @@ static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir,
static int exfat_find(struct inode *dir, struct qstr *qname,
struct exfat_dir_entry *info)
{
- int ret, dentry, num_entries, count;
+ int ret, dentry, count;
struct exfat_chain cdir;
struct exfat_uni_name uni_name;
struct super_block *sb = dir->i_sb;
@@ -619,10 +619,6 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
if (ret)
return ret;
- num_entries = exfat_calc_num_entries(&uni_name);
- if (num_entries < 0)
- return num_entries;
-
/* check the validation of hint_stat and initialize it if required */
if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
ei->hint_stat.clu = cdir.dir;
@@ -632,9 +628,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
}
/* search the file name for directories */
- dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
- num_entries, TYPE_ALL, &hint_opt);
-
+ dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, &hint_opt);
if (dentry < 0)
return dentry; /* -error value */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0821/1887] exfat: add cluster chain loop check for dir
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (819 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0820/1887] exfat: remove unnecessary arguments from exfat_find_dir_entry() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0822/1887] drm/amd/pm: fix null pointer access Greg Kroah-Hartman
` (177 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuezhang Mo, Namjae Jeon,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <Yuezhang.Mo@sony.com>
[ Upstream commit 99f9a97dce39ad413c39b92c90393bbd6778f3fd ]
An infinite loop may occur if the following conditions occur due to
file system corruption.
(1) Condition for exfat_count_dir_entries() to loop infinitely.
- The cluster chain includes a loop.
- There is no UNUSED entry in the cluster chain.
(2) Condition for exfat_create_upcase_table() to loop infinitely.
- The cluster chain of the root directory includes a loop.
- There are no UNUSED entry and up-case table entry in the cluster
chain of the root directory.
(3) Condition for exfat_load_bitmap() to loop infinitely.
- The cluster chain of the root directory includes a loop.
- There are no UNUSED entry and bitmap entry in the cluster chain
of the root directory.
(4) Condition for exfat_find_dir_entry() to loop infinitely.
- The cluster chain includes a loop.
- The unused directory entries were exhausted by some operation.
(5) Condition for exfat_check_dir_empty() to loop infinitely.
- The cluster chain includes a loop.
- The unused directory entries were exhausted by some operation.
- All files and sub-directories under the directory are deleted.
This commit adds checks to break the above infinite loop.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/exfat/dir.c | 12 ++++++++++++
fs/exfat/fatent.c | 10 ++++++++++
fs/exfat/namei.c | 5 +++++
fs/exfat/super.c | 32 +++++++++++++++++++++-----------
4 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index dda10bca9ac98..d8c789d768076 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -943,6 +943,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_hint_femp candi_empty;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
int num_entries = exfat_calc_num_entries(p_uniname);
+ unsigned int clu_count = 0;
if (num_entries < 0)
return num_entries;
@@ -1100,6 +1101,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
} else {
if (exfat_get_next_cluster(sb, &clu.dir))
return -EIO;
+
+ /* break if the cluster chain includes a loop */
+ if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi)))
+ goto not_found;
}
}
@@ -1178,6 +1183,7 @@ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)
int i, count = 0;
int dentries_per_clu;
unsigned int entry_type;
+ unsigned int clu_count = 0;
struct exfat_chain clu;
struct exfat_dentry *ep;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -1210,6 +1216,12 @@ int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir)
} else {
if (exfat_get_next_cluster(sb, &(clu.dir)))
return -EIO;
+
+ if (unlikely(++clu_count > sbi->used_clusters)) {
+ exfat_fs_error(sb, "FAT or bitmap is corrupted");
+ return -EIO;
+ }
+
}
}
diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c
index e7e160d022566..bacd68bc7b8a0 100644
--- a/fs/exfat/fatent.c
+++ b/fs/exfat/fatent.c
@@ -470,5 +470,15 @@ int exfat_count_num_clusters(struct super_block *sb,
}
*ret_count = count;
+
+ /*
+ * since exfat_count_used_clusters() is not called, sbi->used_clusters
+ * cannot be used here.
+ */
+ if (unlikely(i == sbi->num_clusters && clu != EXFAT_EOF_CLUSTER)) {
+ exfat_fs_error(sb, "The cluster chain has a loop");
+ return -EIO;
+ }
+
return 0;
}
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index 7f84ea80c8a6c..605c9d617d7c4 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -892,6 +892,7 @@ static int exfat_check_dir_empty(struct super_block *sb,
{
int i, dentries_per_clu;
unsigned int type;
+ unsigned int clu_count = 0;
struct exfat_chain clu;
struct exfat_dentry *ep;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -928,6 +929,10 @@ static int exfat_check_dir_empty(struct super_block *sb,
} else {
if (exfat_get_next_cluster(sb, &(clu.dir)))
return -EIO;
+
+ /* break if the cluster chain includes a loop */
+ if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi)))
+ break;
}
}
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 52b852a4121b0..e377fbc6e847e 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -336,13 +336,12 @@ static void exfat_hash_init(struct super_block *sb)
INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);
}
-static int exfat_read_root(struct inode *inode)
+static int exfat_read_root(struct inode *inode, struct exfat_chain *root_clu)
{
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
struct exfat_inode_info *ei = EXFAT_I(inode);
- struct exfat_chain cdir;
- int num_subdirs, num_clu = 0;
+ int num_subdirs;
exfat_chain_set(&ei->dir, sbi->root_dir, 0, ALLOC_FAT_CHAIN);
ei->entry = -1;
@@ -355,12 +354,9 @@ static int exfat_read_root(struct inode *inode)
ei->hint_stat.clu = sbi->root_dir;
ei->hint_femp.eidx = EXFAT_HINT_NONE;
- exfat_chain_set(&cdir, sbi->root_dir, 0, ALLOC_FAT_CHAIN);
- if (exfat_count_num_clusters(sb, &cdir, &num_clu))
- return -EIO;
- i_size_write(inode, num_clu << sbi->cluster_size_bits);
+ i_size_write(inode, EXFAT_CLU_TO_B(root_clu->size, sbi));
- num_subdirs = exfat_count_dir_entries(sb, &cdir);
+ num_subdirs = exfat_count_dir_entries(sb, root_clu);
if (num_subdirs < 0)
return -EIO;
set_nlink(inode, num_subdirs + EXFAT_MIN_SUBDIR);
@@ -580,7 +576,8 @@ static int exfat_verify_boot_region(struct super_block *sb)
}
/* mount the file system volume */
-static int __exfat_fill_super(struct super_block *sb)
+static int __exfat_fill_super(struct super_block *sb,
+ struct exfat_chain *root_clu)
{
int ret;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
@@ -597,6 +594,18 @@ static int __exfat_fill_super(struct super_block *sb)
goto free_bh;
}
+ /*
+ * Call exfat_count_num_cluster() before searching for up-case and
+ * bitmap directory entries to avoid infinite loop if they are missing
+ * and the cluster chain includes a loop.
+ */
+ exfat_chain_set(root_clu, sbi->root_dir, 0, ALLOC_FAT_CHAIN);
+ ret = exfat_count_num_clusters(sb, root_clu, &root_clu->size);
+ if (ret) {
+ exfat_err(sb, "failed to count the number of clusters in root");
+ goto free_bh;
+ }
+
ret = exfat_create_upcase_table(sb);
if (ret) {
exfat_err(sb, "failed to load upcase table");
@@ -631,6 +640,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
struct exfat_sb_info *sbi = sb->s_fs_info;
struct exfat_mount_options *opts = &sbi->options;
struct inode *root_inode;
+ struct exfat_chain root_clu;
int err;
if (opts->allow_utime == (unsigned short)-1)
@@ -649,7 +659,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;
sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS;
- err = __exfat_fill_super(sb);
+ err = __exfat_fill_super(sb, &root_clu);
if (err) {
exfat_err(sb, "failed to recognize exfat type");
goto check_nls_io;
@@ -684,7 +694,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
root_inode->i_ino = EXFAT_ROOT_INO;
inode_set_iversion(root_inode, 1);
- err = exfat_read_root(root_inode);
+ err = exfat_read_root(root_inode, &root_clu);
if (err) {
exfat_err(sb, "failed to initialize root inode");
goto put_inode;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0822/1887] drm/amd/pm: fix null pointer access
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (820 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0821/1887] exfat: add cluster chain loop check for dir Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0823/1887] loop: Avoid updating block size under exclusive owner Greg Kroah-Hartman
` (176 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Umio Yasuno, Alex Deucher,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Umio Yasuno <coelacanth_dream@protonmail.com>
[ Upstream commit d524d40e3a6152a3ea1125af729f8cd8ca65efde ]
Writing a string without delimiters (' ', '\n', '\0') to the under
gpu_od/fan_ctrl sysfs or pp_power_profile_mode for the CUSTOM profile
will result in a null pointer dereference.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4401
Signed-off-by: Umio Yasuno <coelacanth_dream@protonmail.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 500cbd1572374..1eaf20cad9fa1 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -1436,6 +1436,8 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
if (ret)
return -EINVAL;
parameter_size++;
+ if (!tmp_str)
+ break;
while (isspace(*tmp_str))
tmp_str++;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0823/1887] loop: Avoid updating block size under exclusive owner
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (821 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0822/1887] drm/amd/pm: fix null pointer access Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0824/1887] pagemap: add filemap_grab_folio() Greg Kroah-Hartman
` (175 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+01ef7a8da81a975e1ccd,
Jan Kara, Jens Axboe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
[ Upstream commit 7e49538288e523427beedd26993d446afef1a6fb ]
Syzbot came up with a reproducer where a loop device block size is
changed underneath a mounted filesystem. This causes a mismatch between
the block device block size and the block size stored in the superblock
causing confusion in various places such as fs/buffer.c. The particular
issue triggered by syzbot was a warning in __getblk_slow() due to
requested buffer size not matching block device block size.
Fix the problem by getting exclusive hold of the loop device to change
its block size. This fails if somebody (such as filesystem) has already
an exclusive ownership of the block device and thus prevents modifying
the loop device under some exclusive owner which doesn't expect it.
Reported-by: syzbot+01ef7a8da81a975e1ccd@syzkaller.appspotmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Tested-by: syzbot+01ef7a8da81a975e1ccd@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/20250711163202.19623-2-jack@suse.cz
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/loop.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index e3e5d533a7eca..20ecd689c2e63 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1472,19 +1472,36 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)
return error;
}
-static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
+static int loop_set_block_size(struct loop_device *lo, fmode_t mode,
+ struct block_device *bdev, unsigned long arg)
{
int err = 0;
- if (lo->lo_state != Lo_bound)
- return -ENXIO;
+ /*
+ * If we don't hold exclusive handle for the device, upgrade to it
+ * here to avoid changing device under exclusive owner.
+ */
+ if (!(mode & FMODE_EXCL)) {
+ err = bd_prepare_to_claim(bdev, loop_set_block_size);
+ if (err)
+ return err;
+ }
+
+ err = mutex_lock_killable(&lo->lo_mutex);
+ if (err)
+ goto abort_claim;
+
+ if (lo->lo_state != Lo_bound) {
+ err = -ENXIO;
+ goto unlock;
+ }
err = blk_validate_block_size(arg);
if (err)
- return err;
+ goto unlock;
if (lo->lo_queue->limits.logical_block_size == arg)
- return 0;
+ goto unlock;
sync_blockdev(lo->lo_device);
invalidate_bdev(lo->lo_device);
@@ -1496,6 +1513,11 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
loop_update_dio(lo);
blk_mq_unfreeze_queue(lo->lo_queue);
+unlock:
+ mutex_unlock(&lo->lo_mutex);
+abort_claim:
+ if (!(mode & FMODE_EXCL))
+ bd_abort_claiming(bdev, loop_set_block_size);
return err;
}
@@ -1514,9 +1536,6 @@ static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd,
case LOOP_SET_DIRECT_IO:
err = loop_set_dio(lo, arg);
break;
- case LOOP_SET_BLOCK_SIZE:
- err = loop_set_block_size(lo, arg);
- break;
default:
err = -EINVAL;
}
@@ -1573,9 +1592,12 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
break;
case LOOP_GET_STATUS64:
return loop_get_status64(lo, argp);
+ case LOOP_SET_BLOCK_SIZE:
+ if (!(mode & FMODE_WRITE) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return loop_set_block_size(lo, mode, bdev, arg);
case LOOP_SET_CAPACITY:
case LOOP_SET_DIRECT_IO:
- case LOOP_SET_BLOCK_SIZE:
if (!(mode & FMODE_WRITE) && !capable(CAP_SYS_ADMIN))
return -EPERM;
fallthrough;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0824/1887] pagemap: add filemap_grab_folio()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (822 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0823/1887] loop: Avoid updating block size under exclusive owner Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0825/1887] highmem: add memcpy_to_folio() and memcpy_from_folio() Greg Kroah-Hartman
` (174 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vishal Moola (Oracle),
Matthew Wilcox (Oracle), Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishal Moola (Oracle) <vishal.moola@gmail.com>
[ Upstream commit ee7a5906ff08e435ed95ec9fe7c7eed2c11015d2 ]
Patch series "Convert to filemap_get_folios_tag()", v5.
This patch series replaces find_get_pages_range_tag() with
filemap_get_folios_tag(). This also allows the removal of multiple calls
to compound_head() throughout.
It also makes a good chunk of the straightforward conversions to folios,
and takes the opportunity to introduce a function that grabs a folio from
the pagecache.
This patch (of 23):
Add function filemap_grab_folio() to grab a folio from the page cache.
This function is meant to serve as a folio replacement for
grab_cache_page, and is used to facilitate the removal of
find_get_pages_range_tag().
Link: https://lkml.kernel.org/r/20230104211448.4804-1-vishal.moola@gmail.com
Link: https://lkml.kernel.org/r/20230104211448.4804-2-vishal.moola@gmail.com
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 736a0516a162 ("hfs: fix general protection fault in hfs_find_init()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/pagemap.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index a40afc0aea3e2..a1f481f51afdb 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -610,6 +610,26 @@ static inline struct folio *filemap_lock_folio(struct address_space *mapping,
return __filemap_get_folio(mapping, index, FGP_LOCK, 0);
}
+/**
+ * filemap_grab_folio - grab a folio from the page cache
+ * @mapping: The address space to search
+ * @index: The page index
+ *
+ * Looks up the page cache entry at @mapping & @index. If no folio is found,
+ * a new folio is created. The folio is locked, marked as accessed, and
+ * returned.
+ *
+ * Return: A found or created folio. NULL if no folio is found and failed to
+ * create a folio.
+ */
+static inline struct folio *filemap_grab_folio(struct address_space *mapping,
+ pgoff_t index)
+{
+ return __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+ mapping_gfp_mask(mapping));
+}
+
/**
* find_get_page - find and get a page reference
* @mapping: the address_space to search
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0825/1887] highmem: add memcpy_to_folio() and memcpy_from_folio()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (823 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0824/1887] pagemap: add filemap_grab_folio() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0826/1887] hfs: fix general protection fault in hfs_find_init() Greg Kroah-Hartman
` (173 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Wilcox (Oracle),
David Sterba, Jan Kara, Konstantin Komarov, Pankaj Raghav,
Theodore Tso, Alexander Viro, Christian Brauner,
Nathan Chancellor, Nick Desaulniers, Tom Rix, Andreas Gruenbacher,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit b23d03ef7af567929bcd3fca7eea6f4f347387d3 ]
Patch series "More filesystem folio conversions for 6.6".
Remove the only spots in affs which actually use a struct page; there
are a few places where one is mentioned, but it's part of the interface.
The rest of this is removing the remaining calls to set_bh_page(),
and then removing the function before any new users show up.
This patch (of 7):
These are the folio equivalent of memcpy_to_page() and memcpy_from_page().
[agruenba@redhat.com: use correct chunk size in memcpy()]
Link: https://lkml.kernel.org/r/20230802144354.1023099-1-agruenba@redhat.com
Link: https://lkml.kernel.org/r/20230713035512.4139457-1-willy@infradead.org
Link: https://lkml.kernel.org/r/20230713035512.4139457-2-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: David Sterba <dsterba@suse.com>
Cc: Jan Kara <jack@suse.com>
Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Cc: Pankaj Raghav <p.raghav@samsung.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Tom Rix <trix@redhat.com>
Cc: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 736a0516a162 ("hfs: fix general protection fault in hfs_find_init()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/highmem.h | 44 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 44242268f53bd..c4d6ae968dfc3 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -415,6 +415,50 @@ static inline void memzero_page(struct page *page, size_t offset, size_t len)
kunmap_local(addr);
}
+static inline void memcpy_from_folio(char *to, struct folio *folio,
+ size_t offset, size_t len)
+{
+ VM_BUG_ON(offset + len > folio_size(folio));
+
+ do {
+ const char *from = kmap_local_folio(folio, offset);
+ size_t chunk = len;
+
+ if (folio_test_highmem(folio) &&
+ chunk > PAGE_SIZE - offset_in_page(offset))
+ chunk = PAGE_SIZE - offset_in_page(offset);
+ memcpy(to, from, chunk);
+ kunmap_local(from);
+
+ from += chunk;
+ offset += chunk;
+ len -= chunk;
+ } while (len > 0);
+}
+
+static inline void memcpy_to_folio(struct folio *folio, size_t offset,
+ const char *from, size_t len)
+{
+ VM_BUG_ON(offset + len > folio_size(folio));
+
+ do {
+ char *to = kmap_local_folio(folio, offset);
+ size_t chunk = len;
+
+ if (folio_test_highmem(folio) &&
+ chunk > PAGE_SIZE - offset_in_page(offset))
+ chunk = PAGE_SIZE - offset_in_page(offset);
+ memcpy(to, from, chunk);
+ kunmap_local(to);
+
+ from += chunk;
+ offset += chunk;
+ len -= chunk;
+ } while (len > 0);
+
+ flush_dcache_folio(folio);
+}
+
/**
* folio_zero_segments() - Zero two byte ranges in a folio.
* @folio: The folio to write to.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0826/1887] hfs: fix general protection fault in hfs_find_init()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (824 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0825/1887] highmem: add memcpy_to_folio() and memcpy_from_folio() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0827/1887] habanalabs: remove support to export dmabuf from handle Greg Kroah-Hartman
` (172 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wenzhi Wang, Viacheslav Dubeyko,
John Paul Adrian Glaubitz, Yangtao Li, linux-fsdevel, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <slava@dubeyko.com>
[ Upstream commit 736a0516a16268995f4898eded49bfef077af709 ]
The hfs_find_init() method can trigger the crash
if tree pointer is NULL:
[ 45.746290][ T9787] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000008: 0000 [#1] SMP KAI
[ 45.747287][ T9787] KASAN: null-ptr-deref in range [0x0000000000000040-0x0000000000000047]
[ 45.748716][ T9787] CPU: 2 UID: 0 PID: 9787 Comm: repro Not tainted 6.16.0-rc3 #10 PREEMPT(full)
[ 45.750250][ T9787] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 45.751983][ T9787] RIP: 0010:hfs_find_init+0x86/0x230
[ 45.752834][ T9787] Code: c1 ea 03 80 3c 02 00 0f 85 9a 01 00 00 4c 8d 6b 40 48 c7 45 18 00 00 00 00 48 b8 00 00 00 00 00 fc
[ 45.755574][ T9787] RSP: 0018:ffffc90015157668 EFLAGS: 00010202
[ 45.756432][ T9787] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff819a4d09
[ 45.757457][ T9787] RDX: 0000000000000008 RSI: ffffffff819acd3a RDI: ffffc900151576e8
[ 45.758282][ T9787] RBP: ffffc900151576d0 R08: 0000000000000005 R09: 0000000000000000
[ 45.758943][ T9787] R10: 0000000080000000 R11: 0000000000000001 R12: 0000000000000004
[ 45.759619][ T9787] R13: 0000000000000040 R14: ffff88802c50814a R15: 0000000000000000
[ 45.760293][ T9787] FS: 00007ffb72734540(0000) GS:ffff8880cec64000(0000) knlGS:0000000000000000
[ 45.761050][ T9787] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 45.761606][ T9787] CR2: 00007f9bd8225000 CR3: 000000010979a000 CR4: 00000000000006f0
[ 45.762286][ T9787] Call Trace:
[ 45.762570][ T9787] <TASK>
[ 45.762824][ T9787] hfs_ext_read_extent+0x190/0x9d0
[ 45.763269][ T9787] ? submit_bio_noacct_nocheck+0x2dd/0xce0
[ 45.763766][ T9787] ? __pfx_hfs_ext_read_extent+0x10/0x10
[ 45.764250][ T9787] hfs_get_block+0x55f/0x830
[ 45.764646][ T9787] block_read_full_folio+0x36d/0x850
[ 45.765105][ T9787] ? __pfx_hfs_get_block+0x10/0x10
[ 45.765541][ T9787] ? const_folio_flags+0x5b/0x100
[ 45.765972][ T9787] ? __pfx_hfs_read_folio+0x10/0x10
[ 45.766415][ T9787] filemap_read_folio+0xbe/0x290
[ 45.766840][ T9787] ? __pfx_filemap_read_folio+0x10/0x10
[ 45.767325][ T9787] ? __filemap_get_folio+0x32b/0xbf0
[ 45.767780][ T9787] do_read_cache_folio+0x263/0x5c0
[ 45.768223][ T9787] ? __pfx_hfs_read_folio+0x10/0x10
[ 45.768666][ T9787] read_cache_page+0x5b/0x160
[ 45.769070][ T9787] hfs_btree_open+0x491/0x1740
[ 45.769481][ T9787] hfs_mdb_get+0x15e2/0x1fb0
[ 45.769877][ T9787] ? __pfx_hfs_mdb_get+0x10/0x10
[ 45.770316][ T9787] ? find_held_lock+0x2b/0x80
[ 45.770731][ T9787] ? lockdep_init_map_type+0x5c/0x280
[ 45.771200][ T9787] ? lockdep_init_map_type+0x5c/0x280
[ 45.771674][ T9787] hfs_fill_super+0x38e/0x720
[ 45.772092][ T9787] ? __pfx_hfs_fill_super+0x10/0x10
[ 45.772549][ T9787] ? snprintf+0xbe/0x100
[ 45.772931][ T9787] ? __pfx_snprintf+0x10/0x10
[ 45.773350][ T9787] ? do_raw_spin_lock+0x129/0x2b0
[ 45.773796][ T9787] ? find_held_lock+0x2b/0x80
[ 45.774215][ T9787] ? set_blocksize+0x40a/0x510
[ 45.774636][ T9787] ? sb_set_blocksize+0x176/0x1d0
[ 45.775087][ T9787] ? setup_bdev_super+0x369/0x730
[ 45.775533][ T9787] get_tree_bdev_flags+0x384/0x620
[ 45.775985][ T9787] ? __pfx_hfs_fill_super+0x10/0x10
[ 45.776453][ T9787] ? __pfx_get_tree_bdev_flags+0x10/0x10
[ 45.776950][ T9787] ? bpf_lsm_capable+0x9/0x10
[ 45.777365][ T9787] ? security_capable+0x80/0x260
[ 45.777803][ T9787] vfs_get_tree+0x8e/0x340
[ 45.778203][ T9787] path_mount+0x13de/0x2010
[ 45.778604][ T9787] ? kmem_cache_free+0x2b0/0x4c0
[ 45.779052][ T9787] ? __pfx_path_mount+0x10/0x10
[ 45.779480][ T9787] ? getname_flags.part.0+0x1c5/0x550
[ 45.779954][ T9787] ? putname+0x154/0x1a0
[ 45.780335][ T9787] __x64_sys_mount+0x27b/0x300
[ 45.780758][ T9787] ? __pfx___x64_sys_mount+0x10/0x10
[ 45.781232][ T9787] do_syscall_64+0xc9/0x480
[ 45.781631][ T9787] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 45.782149][ T9787] RIP: 0033:0x7ffb7265b6ca
[ 45.782539][ T9787] Code: 48 8b 0d c9 17 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48
[ 45.784212][ T9787] RSP: 002b:00007ffc0c10cfb8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[ 45.784935][ T9787] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ffb7265b6ca
[ 45.785626][ T9787] RDX: 0000200000000240 RSI: 0000200000000280 RDI: 00007ffc0c10d100
[ 45.786316][ T9787] RBP: 00007ffc0c10d190 R08: 00007ffc0c10d000 R09: 0000000000000000
[ 45.787011][ T9787] R10: 0000000000000048 R11: 0000000000000206 R12: 0000560246733250
[ 45.787697][ T9787] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[ 45.788393][ T9787] </TASK>
[ 45.788665][ T9787] Modules linked in:
[ 45.789058][ T9787] ---[ end trace 0000000000000000 ]---
[ 45.789554][ T9787] RIP: 0010:hfs_find_init+0x86/0x230
[ 45.790028][ T9787] Code: c1 ea 03 80 3c 02 00 0f 85 9a 01 00 00 4c 8d 6b 40 48 c7 45 18 00 00 00 00 48 b8 00 00 00 00 00 fc
[ 45.792364][ T9787] RSP: 0018:ffffc90015157668 EFLAGS: 00010202
[ 45.793155][ T9787] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff819a4d09
[ 45.794123][ T9787] RDX: 0000000000000008 RSI: ffffffff819acd3a RDI: ffffc900151576e8
[ 45.795105][ T9787] RBP: ffffc900151576d0 R08: 0000000000000005 R09: 0000000000000000
[ 45.796135][ T9787] R10: 0000000080000000 R11: 0000000000000001 R12: 0000000000000004
[ 45.797114][ T9787] R13: 0000000000000040 R14: ffff88802c50814a R15: 0000000000000000
[ 45.798024][ T9787] FS: 00007ffb72734540(0000) GS:ffff8880cec64000(0000) knlGS:0000000000000000
[ 45.799019][ T9787] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 45.799822][ T9787] CR2: 00007f9bd8225000 CR3: 000000010979a000 CR4: 00000000000006f0
[ 45.800747][ T9787] Kernel panic - not syncing: Fatal exception
The hfs_fill_super() calls hfs_mdb_get() method that tries
to construct Extents Tree and Catalog Tree:
HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp);
if (!HFS_SB(sb)->ext_tree) {
pr_err("unable to open extent tree\n");
goto out;
}
HFS_SB(sb)->cat_tree = hfs_btree_open(sb, HFS_CAT_CNID, hfs_cat_keycmp);
if (!HFS_SB(sb)->cat_tree) {
pr_err("unable to open catalog tree\n");
goto out;
}
However, hfs_btree_open() calls read_mapping_page() that
calls hfs_get_block(). And this method calls hfs_ext_read_extent():
static int hfs_ext_read_extent(struct inode *inode, u16 block)
{
struct hfs_find_data fd;
int res;
if (block >= HFS_I(inode)->cached_start &&
block < HFS_I(inode)->cached_start + HFS_I(inode)->cached_blocks)
return 0;
res = hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd);
if (!res) {
res = __hfs_ext_cache_extent(&fd, inode, block);
hfs_find_exit(&fd);
}
return res;
}
The problem here that hfs_find_init() is trying to use
HFS_SB(inode->i_sb)->ext_tree that is not initialized yet.
It will be initailized when hfs_btree_open() finishes
the execution.
The patch adds checking of tree pointer in hfs_find_init()
and it reworks the logic of hfs_btree_open() by reading
the b-tree's header directly from the volume. The read_mapping_page()
is exchanged on filemap_grab_folio() that grab the folio from
mapping. Then, sb_bread() extracts the b-tree's header
content and copy it into the folio.
Reported-by: Wenzhi Wang <wenzhi.wang@uwaterloo.ca>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
cc: Yangtao Li <frank.li@vivo.com>
cc: linux-fsdevel@vger.kernel.org
Link: https://lore.kernel.org/r/20250710213657.108285-1-slava@dubeyko.com
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/hfs/bfind.c | 3 +++
fs/hfs/btree.c | 57 +++++++++++++++++++++++++++++++++++++++----------
fs/hfs/extent.c | 2 +-
fs/hfs/hfs_fs.h | 1 +
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c
index be4cb0e3a68fe..245c2b9671892 100644
--- a/fs/hfs/bfind.c
+++ b/fs/hfs/bfind.c
@@ -16,6 +16,9 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
{
void *ptr;
+ if (!tree || !fd)
+ return -EINVAL;
+
fd->tree = tree;
fd->bnode = NULL;
ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL);
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 6f754b9347529..e748d92d84105 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -21,8 +21,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
struct hfs_btree *tree;
struct hfs_btree_header_rec *head;
struct address_space *mapping;
- struct page *page;
+ struct folio *folio;
+ struct buffer_head *bh;
unsigned int size;
+ u16 dblock;
+ sector_t start_block;
+ loff_t offset;
tree = kzalloc(sizeof(*tree), GFP_KERNEL);
if (!tree)
@@ -75,12 +79,40 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
unlock_new_inode(tree->inode);
mapping = tree->inode->i_mapping;
- page = read_mapping_page(mapping, 0, NULL);
- if (IS_ERR(page))
+ folio = filemap_grab_folio(mapping, 0);
+ if (IS_ERR(folio))
goto free_inode;
+ folio_zero_range(folio, 0, folio_size(folio));
+
+ dblock = hfs_ext_find_block(HFS_I(tree->inode)->first_extents, 0);
+ start_block = HFS_SB(sb)->fs_start + (dblock * HFS_SB(sb)->fs_div);
+
+ size = folio_size(folio);
+ offset = 0;
+ while (size > 0) {
+ size_t len;
+
+ bh = sb_bread(sb, start_block);
+ if (!bh) {
+ pr_err("unable to read tree header\n");
+ goto put_folio;
+ }
+
+ len = min_t(size_t, folio_size(folio), sb->s_blocksize);
+ memcpy_to_folio(folio, offset, bh->b_data, sb->s_blocksize);
+
+ brelse(bh);
+
+ start_block++;
+ offset += len;
+ size -= len;
+ }
+
+ folio_mark_uptodate(folio);
+
/* Load the header */
- head = (struct hfs_btree_header_rec *)(kmap_local_page(page) +
+ head = (struct hfs_btree_header_rec *)(kmap_local_folio(folio, 0) +
sizeof(struct hfs_bnode_desc));
tree->root = be32_to_cpu(head->root);
tree->leaf_count = be32_to_cpu(head->leaf_count);
@@ -95,22 +127,22 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
size = tree->node_size;
if (!is_power_of_2(size))
- goto fail_page;
+ goto fail_folio;
if (!tree->node_count)
- goto fail_page;
+ goto fail_folio;
switch (id) {
case HFS_EXT_CNID:
if (tree->max_key_len != HFS_MAX_EXT_KEYLEN) {
pr_err("invalid extent max_key_len %d\n",
tree->max_key_len);
- goto fail_page;
+ goto fail_folio;
}
break;
case HFS_CAT_CNID:
if (tree->max_key_len != HFS_MAX_CAT_KEYLEN) {
pr_err("invalid catalog max_key_len %d\n",
tree->max_key_len);
- goto fail_page;
+ goto fail_folio;
}
break;
default:
@@ -121,12 +153,15 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
tree->pages_per_bnode = (tree->node_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
kunmap_local(head);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return tree;
-fail_page:
+fail_folio:
kunmap_local(head);
- put_page(page);
+put_folio:
+ folio_unlock(folio);
+ folio_put(folio);
free_inode:
tree->inode->i_mapping->a_ops = &hfs_aops;
iput(tree->inode);
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
index 3f7e9bef98743..070245f8c2157 100644
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -71,7 +71,7 @@ int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2)
*
* Find a block within an extent record
*/
-static u16 hfs_ext_find_block(struct hfs_extent *ext, u16 off)
+u16 hfs_ext_find_block(struct hfs_extent *ext, u16 off)
{
int i;
u16 count;
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index 203757a273ac3..4e9fd2abc05af 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -193,6 +193,7 @@ extern const struct inode_operations hfs_dir_inode_operations;
/* extent.c */
extern int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2);
+extern u16 hfs_ext_find_block(struct hfs_extent *ext, u16 off);
extern int hfs_free_fork(struct super_block *sb,
struct hfs_cat_file *file, int type);
extern int hfs_ext_write_extent(struct inode *inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0827/1887] habanalabs: remove support to export dmabuf from handle
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (825 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0826/1887] hfs: fix general protection fault in hfs_find_init() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0828/1887] habanalabs: helper function to validate export params Greg Kroah-Hartman
` (171 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ohad Sharabi, Oded Gabbay,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ohad Sharabi <osharabi@habana.ai>
[ Upstream commit 303dad15ed8ccbb1702f3476642d8a43680f97b5 ]
The API to the user which allows exporting DMA buffer from handle is
deprecated here. It was never used as it is relevant only for Gaudi2,
and the user stack has yet to add support for dmabuf in Gaudi2.
Looking forward, a modified API to export DMA buffer for ASICs that
supports virtual memory will be added.
Until the new API will be ready- exporting DMA buffer will not be
supported for ASICs with virtual memory.
Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Stable-dep-of: 33927f3d0ecd ("habanalabs: fix UAF in export_dmabuf()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/habanalabs/common/habanalabs.h | 5 -
drivers/misc/habanalabs/common/memory.c | 143 ++------------------
2 files changed, 9 insertions(+), 139 deletions(-)
diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
index e6eabcdda1c5c..ca4b5ce5e6f8e 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -1732,8 +1732,6 @@ struct hl_cs_counters_atomic {
* struct hl_dmabuf_priv - a dma-buf private object.
* @dmabuf: pointer to dma-buf object.
* @ctx: pointer to the dma-buf owner's context.
- * @phys_pg_pack: pointer to physical page pack if the dma-buf was exported for
- * memory allocation handle.
* @device_address: physical address of the device's memory. Relevant only
* if phys_pg_pack is NULL (dma-buf was exported from address).
* The total size can be taken from the dmabuf object.
@@ -1741,7 +1739,6 @@ struct hl_cs_counters_atomic {
struct hl_dmabuf_priv {
struct dma_buf *dmabuf;
struct hl_ctx *ctx;
- struct hl_vm_phys_pg_pack *phys_pg_pack;
uint64_t device_address;
};
@@ -2105,7 +2102,6 @@ struct hl_vm_hw_block_list_node {
* @node: used to attach to deletion list that is used when all the allocations are cleared
* at the teardown of the context.
* @mapping_cnt: number of shared mappings.
- * @exporting_cnt: number of dma-buf exporting.
* @asid: the context related to this list.
* @page_size: size of each page in the pack.
* @flags: HL_MEM_* flags related to this list.
@@ -2121,7 +2117,6 @@ struct hl_vm_phys_pg_pack {
u64 total_size;
struct list_head node;
atomic_t mapping_cnt;
- u32 exporting_cnt;
u32 asid;
u32 page_size;
u32 flags;
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index a49038da3f6d0..7ae0779fbf072 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -371,12 +371,6 @@ static int free_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args)
return -EINVAL;
}
- if (phys_pg_pack->exporting_cnt) {
- spin_unlock(&vm->idr_lock);
- dev_dbg(hdev->dev, "handle %u is exported, cannot free\n", handle);
- return -EINVAL;
- }
-
/* must remove from idr before the freeing of the physical pages as the refcount of the pool
* is also the trigger of the idr destroy
*/
@@ -1700,29 +1694,19 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
enum dma_data_direction dir)
{
struct dma_buf *dma_buf = attachment->dmabuf;
- struct hl_vm_phys_pg_pack *phys_pg_pack;
struct hl_dmabuf_priv *hl_dmabuf;
struct hl_device *hdev;
struct sg_table *sgt;
hl_dmabuf = dma_buf->priv;
hdev = hl_dmabuf->ctx->hdev;
- phys_pg_pack = hl_dmabuf->phys_pg_pack;
if (!attachment->peer2peer) {
dev_dbg(hdev->dev, "Failed to map dmabuf because p2p is disabled\n");
return ERR_PTR(-EPERM);
}
- if (phys_pg_pack)
- sgt = alloc_sgt_from_device_pages(hdev,
- phys_pg_pack->pages,
- phys_pg_pack->npages,
- phys_pg_pack->page_size,
- attachment->dev,
- dir);
- else
- sgt = alloc_sgt_from_device_pages(hdev,
+ sgt = alloc_sgt_from_device_pages(hdev,
&hl_dmabuf->device_address,
1,
hl_dmabuf->dmabuf->size,
@@ -1763,18 +1747,8 @@ static void hl_unmap_dmabuf(struct dma_buf_attachment *attachment,
static void hl_release_dmabuf(struct dma_buf *dmabuf)
{
struct hl_dmabuf_priv *hl_dmabuf = dmabuf->priv;
- struct hl_ctx *ctx = hl_dmabuf->ctx;
- struct hl_device *hdev = ctx->hdev;
- struct hl_vm *vm = &hdev->vm;
-
- if (hl_dmabuf->phys_pg_pack) {
- spin_lock(&vm->idr_lock);
- hl_dmabuf->phys_pg_pack->exporting_cnt--;
- spin_unlock(&vm->idr_lock);
- }
hl_ctx_put(hl_dmabuf->ctx);
-
kfree(hl_dmabuf);
}
@@ -1785,7 +1759,7 @@ static const struct dma_buf_ops habanalabs_dmabuf_ops = {
.release = hl_release_dmabuf,
};
-static int export_dmabuf_common(struct hl_ctx *ctx,
+static int export_dmabuf(struct hl_ctx *ctx,
struct hl_dmabuf_priv *hl_dmabuf,
u64 total_size, int flags, int *dmabuf_fd)
{
@@ -1849,6 +1823,11 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 device_addr,
prop = &hdev->asic_prop;
+ if (prop->dram_supports_virtual_memory) {
+ dev_dbg(hdev->dev, "Export not supported for devices with virtual memory\n");
+ return -EOPNOTSUPP;
+ }
+
if (!IS_ALIGNED(device_addr, PAGE_SIZE)) {
dev_dbg(hdev->dev,
"exported device memory address 0x%llx should be aligned to 0x%lx\n",
@@ -1890,99 +1869,7 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 device_addr,
hl_dmabuf->device_address = device_addr;
- rc = export_dmabuf_common(ctx, hl_dmabuf, size, flags, dmabuf_fd);
- if (rc)
- goto err_free_dmabuf_wrapper;
-
- return 0;
-
-err_free_dmabuf_wrapper:
- kfree(hl_dmabuf);
- return rc;
-}
-
-/**
- * export_dmabuf_from_handle() - export a dma-buf object for the given memory
- * handle.
- * @ctx: pointer to the context structure.
- * @handle: device memory allocation handle.
- * @flags: DMA-BUF file/FD flags.
- * @dmabuf_fd: pointer to result FD that represents the dma-buf object.
- *
- * Create and export a dma-buf object for an existing memory allocation inside
- * the device memory, and return a FD which is associated with the dma-buf
- * object.
- *
- * Return: 0 on success, non-zero for failure.
- */
-static int export_dmabuf_from_handle(struct hl_ctx *ctx, u64 handle, int flags,
- int *dmabuf_fd)
-{
- struct hl_vm_phys_pg_pack *phys_pg_pack;
- struct hl_dmabuf_priv *hl_dmabuf;
- struct hl_device *hdev = ctx->hdev;
- struct asic_fixed_properties *prop;
- struct hl_vm *vm = &hdev->vm;
- u64 bar_address;
- int rc, i;
-
- prop = &hdev->asic_prop;
-
- if (upper_32_bits(handle)) {
- dev_dbg(hdev->dev, "no match for handle 0x%llx\n", handle);
- return -EINVAL;
- }
-
- spin_lock(&vm->idr_lock);
-
- phys_pg_pack = idr_find(&vm->phys_pg_pack_handles, (u32) handle);
- if (!phys_pg_pack) {
- spin_unlock(&vm->idr_lock);
- dev_dbg(hdev->dev, "no match for handle 0x%x\n", (u32) handle);
- return -EINVAL;
- }
-
- /* increment now to avoid freeing device memory while exporting */
- phys_pg_pack->exporting_cnt++;
-
- spin_unlock(&vm->idr_lock);
-
- if (phys_pg_pack->vm_type != VM_TYPE_PHYS_PACK) {
- dev_dbg(hdev->dev, "handle 0x%llx does not represent DRAM memory\n", handle);
- rc = -EINVAL;
- goto err_dec_exporting_cnt;
- }
-
- for (i = 0 ; i < phys_pg_pack->npages ; i++) {
-
- bar_address = hdev->dram_pci_bar_start +
- (phys_pg_pack->pages[i] -
- prop->dram_base_address);
-
- if (bar_address + phys_pg_pack->page_size >
- hdev->dram_pci_bar_start + prop->dram_pci_bar_size ||
- bar_address + phys_pg_pack->page_size < bar_address) {
-
- dev_dbg(hdev->dev,
- "DRAM memory range 0x%llx (+0x%x) is outside of PCI BAR boundaries\n",
- phys_pg_pack->pages[i],
- phys_pg_pack->page_size);
-
- rc = -EINVAL;
- goto err_dec_exporting_cnt;
- }
- }
-
- hl_dmabuf = kzalloc(sizeof(*hl_dmabuf), GFP_KERNEL);
- if (!hl_dmabuf) {
- rc = -ENOMEM;
- goto err_dec_exporting_cnt;
- }
-
- hl_dmabuf->phys_pg_pack = phys_pg_pack;
-
- rc = export_dmabuf_common(ctx, hl_dmabuf, phys_pg_pack->total_size,
- flags, dmabuf_fd);
+ rc = export_dmabuf(ctx, hl_dmabuf, size, flags, dmabuf_fd);
if (rc)
goto err_free_dmabuf_wrapper;
@@ -1990,12 +1877,6 @@ static int export_dmabuf_from_handle(struct hl_ctx *ctx, u64 handle, int flags,
err_free_dmabuf_wrapper:
kfree(hl_dmabuf);
-
-err_dec_exporting_cnt:
- spin_lock(&vm->idr_lock);
- phys_pg_pack->exporting_cnt--;
- spin_unlock(&vm->idr_lock);
-
return rc;
}
@@ -2270,13 +2151,7 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data)
break;
case HL_MEM_OP_EXPORT_DMABUF_FD:
- if (hdev->asic_prop.dram_supports_virtual_memory)
- rc = export_dmabuf_from_handle(ctx,
- args->in.export_dmabuf_fd.handle,
- args->in.flags,
- &dmabuf_fd);
- else
- rc = export_dmabuf_from_addr(ctx,
+ rc = export_dmabuf_from_addr(ctx,
args->in.export_dmabuf_fd.handle,
args->in.export_dmabuf_fd.mem_size,
args->in.flags,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0828/1887] habanalabs: helper function to validate export params
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (826 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0827/1887] habanalabs: remove support to export dmabuf from handle Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0829/1887] habanalabs: fix dma-buf release handling if dma_buf_fd() fails Greg Kroah-Hartman
` (170 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ohad Sharabi, Oded Gabbay,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ohad Sharabi <osharabi@habana.ai>
[ Upstream commit 54fde5505c1311d45a96d7ad8fb8809581d38f22 ]
Validate export parameters in a dedicated function instead of in the
main export flow.
This will be useful later when support to export dmabuf for devices
with virtual memory will be added.
Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Stable-dep-of: 33927f3d0ecd ("habanalabs: fix UAF in export_dmabuf()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/habanalabs/common/memory.c | 79 ++++++++++++++-----------
1 file changed, 44 insertions(+), 35 deletions(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index 7ae0779fbf072..dcc496083f1c6 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1797,36 +1797,10 @@ static int export_dmabuf(struct hl_ctx *ctx,
return rc;
}
-/**
- * export_dmabuf_from_addr() - export a dma-buf object for the given memory
- * address and size.
- * @ctx: pointer to the context structure.
- * @device_addr: device memory physical address.
- * @size: size of device memory.
- * @flags: DMA-BUF file/FD flags.
- * @dmabuf_fd: pointer to result FD that represents the dma-buf object.
- *
- * Create and export a dma-buf object for an existing memory allocation inside
- * the device memory, and return a FD which is associated with the dma-buf
- * object.
- *
- * Return: 0 on success, non-zero for failure.
- */
-static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 device_addr,
- u64 size, int flags, int *dmabuf_fd)
+static int validate_export_params(struct hl_device *hdev, u64 device_addr, u64 size)
{
- struct hl_dmabuf_priv *hl_dmabuf;
- struct hl_device *hdev = ctx->hdev;
- struct asic_fixed_properties *prop;
+ struct asic_fixed_properties *prop = &hdev->asic_prop;
u64 bar_address;
- int rc;
-
- prop = &hdev->asic_prop;
-
- if (prop->dram_supports_virtual_memory) {
- dev_dbg(hdev->dev, "Export not supported for devices with virtual memory\n");
- return -EOPNOTSUPP;
- }
if (!IS_ALIGNED(device_addr, PAGE_SIZE)) {
dev_dbg(hdev->dev,
@@ -1843,26 +1817,61 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 device_addr,
}
if (device_addr < prop->dram_user_base_address ||
- device_addr + size > prop->dram_end_address ||
- device_addr + size < device_addr) {
+ (device_addr + size) > prop->dram_end_address ||
+ (device_addr + size) < device_addr) {
dev_dbg(hdev->dev,
"DRAM memory range 0x%llx (+0x%llx) is outside of DRAM boundaries\n",
device_addr, size);
return -EINVAL;
}
- bar_address = hdev->dram_pci_bar_start +
- (device_addr - prop->dram_base_address);
+ bar_address = hdev->dram_pci_bar_start + (device_addr - prop->dram_base_address);
- if (bar_address + size >
- hdev->dram_pci_bar_start + prop->dram_pci_bar_size ||
- bar_address + size < bar_address) {
+ if ((bar_address + size) > (hdev->dram_pci_bar_start + prop->dram_pci_bar_size) ||
+ (bar_address + size) < bar_address) {
dev_dbg(hdev->dev,
"DRAM memory range 0x%llx (+0x%llx) is outside of PCI BAR boundaries\n",
device_addr, size);
return -EINVAL;
}
+ return 0;
+}
+
+/**
+ * export_dmabuf_from_addr() - export a dma-buf object for the given memory
+ * address and size.
+ * @ctx: pointer to the context structure.
+ * @device_addr: device memory physical address.
+ * @size: size of device memory.
+ * @flags: DMA-BUF file/FD flags.
+ * @dmabuf_fd: pointer to result FD that represents the dma-buf object.
+ *
+ * Create and export a dma-buf object for an existing memory allocation inside
+ * the device memory, and return a FD which is associated with the dma-buf
+ * object.
+ *
+ * Return: 0 on success, non-zero for failure.
+ */
+static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 device_addr,
+ u64 size, int flags, int *dmabuf_fd)
+{
+ struct hl_dmabuf_priv *hl_dmabuf;
+ struct hl_device *hdev = ctx->hdev;
+ struct asic_fixed_properties *prop;
+ int rc;
+
+ prop = &hdev->asic_prop;
+
+ if (prop->dram_supports_virtual_memory) {
+ dev_dbg(hdev->dev, "Export not supported for devices with virtual memory\n");
+ return -EOPNOTSUPP;
+ }
+
+ rc = validate_export_params(hdev, device_addr, size);
+ if (rc)
+ return rc;
+
hl_dmabuf = kzalloc(sizeof(*hl_dmabuf), GFP_KERNEL);
if (!hl_dmabuf)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0829/1887] habanalabs: fix dma-buf release handling if dma_buf_fd() fails
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (827 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0828/1887] habanalabs: helper function to validate export params Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0830/1887] habanalabs: fix UAF in export_dmabuf() Greg Kroah-Hartman
` (169 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tomer Tayar, Oded Gabbay,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomer Tayar <ttayar@habana.ai>
[ Upstream commit 9b3d9f917f81aed559d19377c11d6fac3db89fd7 ]
The dma-buf private object is freed if a call to dma_buf_fd() fails,
and because a file was already associated with the dma-buf in
dma_buf_export(), the release op will be called and will use this
object.
Mark the 'priv' field as NULL in this case, and avoid accessing it from
the release op.
Signed-off-by: Tomer Tayar <ttayar@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Stable-dep-of: 33927f3d0ecd ("habanalabs: fix UAF in export_dmabuf()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/habanalabs/common/memory.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index dcc496083f1c6..d18e111001844 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1748,6 +1748,9 @@ static void hl_release_dmabuf(struct dma_buf *dmabuf)
{
struct hl_dmabuf_priv *hl_dmabuf = dmabuf->priv;
+ if (!hl_dmabuf)
+ return;
+
hl_ctx_put(hl_dmabuf->ctx);
kfree(hl_dmabuf);
}
@@ -1780,7 +1783,7 @@ static int export_dmabuf(struct hl_ctx *ctx,
fd = dma_buf_fd(hl_dmabuf->dmabuf, flags);
if (fd < 0) {
- dev_err(hdev->dev, "failed to get a file descriptor for a dma-buf\n");
+ dev_err(hdev->dev, "failed to get a file descriptor for a dma-buf, %d\n", fd);
rc = fd;
goto err_dma_buf_put;
}
@@ -1793,6 +1796,7 @@ static int export_dmabuf(struct hl_ctx *ctx,
return 0;
err_dma_buf_put:
+ hl_dmabuf->dmabuf->priv = NULL;
dma_buf_put(hl_dmabuf->dmabuf);
return rc;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0830/1887] habanalabs: fix UAF in export_dmabuf()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (828 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0829/1887] habanalabs: fix dma-buf release handling if dma_buf_fd() fails Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0831/1887] net/smc: fix UAF on smcsk after smc_listen_out() Greg Kroah-Hartman
` (168 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Al Viro, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
[ Upstream commit 33927f3d0ecdcff06326d6e4edb6166aed42811c ]
As soon as we'd inserted a file reference into descriptor table, another
thread could close it. That's fine for the case when all we are doing is
returning that descriptor to userland (it's a race, but it's a userland
race and there's nothing the kernel can do about it). However, if we
follow fd_install() with any kind of access to objects that would be
destroyed on close (be it the struct file itself or anything destroyed
by its ->release()), we have a UAF.
dma_buf_fd() is a combination of reserving a descriptor and fd_install().
habanalabs export_dmabuf() calls it and then proceeds to access the
objects destroyed on close. In particular, it grabs an extra reference to
another struct file that will be dropped as part of ->release() for ours;
that "will be" is actually "might have already been".
Fix that by reserving descriptor before anything else and do fd_install()
only when everything had been set up. As a side benefit, we no longer
have the failure exit with file already created, but reference to
underlying file (as well as ->dmabuf_export_cnt, etc.) not grabbed yet;
unlike dma_buf_fd(), fd_install() can't fail.
Fixes: db1a8dd916aa ("habanalabs: add support for dma-buf exporter")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/habanalabs/common/memory.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index d18e111001844..c4334492543f1 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1748,9 +1748,6 @@ static void hl_release_dmabuf(struct dma_buf *dmabuf)
{
struct hl_dmabuf_priv *hl_dmabuf = dmabuf->priv;
- if (!hl_dmabuf)
- return;
-
hl_ctx_put(hl_dmabuf->ctx);
kfree(hl_dmabuf);
}
@@ -1768,7 +1765,12 @@ static int export_dmabuf(struct hl_ctx *ctx,
{
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct hl_device *hdev = ctx->hdev;
- int rc, fd;
+ CLASS(get_unused_fd, fd)(flags);
+
+ if (fd < 0) {
+ dev_err(hdev->dev, "failed to get a file descriptor for a dma-buf, %d\n", fd);
+ return fd;
+ }
exp_info.ops = &habanalabs_dmabuf_ops;
exp_info.size = total_size;
@@ -1781,24 +1783,14 @@ static int export_dmabuf(struct hl_ctx *ctx,
return PTR_ERR(hl_dmabuf->dmabuf);
}
- fd = dma_buf_fd(hl_dmabuf->dmabuf, flags);
- if (fd < 0) {
- dev_err(hdev->dev, "failed to get a file descriptor for a dma-buf, %d\n", fd);
- rc = fd;
- goto err_dma_buf_put;
- }
-
hl_dmabuf->ctx = ctx;
hl_ctx_get(hl_dmabuf->ctx);
*dmabuf_fd = fd;
+ fd_install(fd, hl_dmabuf->dmabuf->file);
+ fd = -EBADF;
return 0;
-
-err_dma_buf_put:
- hl_dmabuf->dmabuf->priv = NULL;
- dma_buf_put(hl_dmabuf->dmabuf);
- return rc;
}
static int validate_export_params(struct hl_device *hdev, u64 device_addr, u64 size)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0831/1887] net/smc: fix UAF on smcsk after smc_listen_out()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (829 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0830/1887] habanalabs: fix UAF in export_dmabuf() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0832/1887] net/sched: Fix backlog accounting in qdisc_dequeue_internal Greg Kroah-Hartman
` (167 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, D. Wythe, Guangguan Wang,
Alexandra Winter, Dust Li, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: D. Wythe <alibuda@linux.alibaba.com>
[ Upstream commit d9cef55ed49117bd63695446fb84b4b91815c0b4 ]
BPF CI testing report a UAF issue:
[ 16.446633] BUG: kernel NULL pointer dereference, address: 000000000000003 0
[ 16.447134] #PF: supervisor read access in kernel mod e
[ 16.447516] #PF: error_code(0x0000) - not-present pag e
[ 16.447878] PGD 0 P4D 0
[ 16.448063] Oops: Oops: 0000 [#1] PREEMPT SMP NOPT I
[ 16.448409] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Tainted: G OE 6.13.0-rc3-g89e8a75fda73-dirty #4 2
[ 16.449124] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODUL E
[ 16.449502] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/201 4
[ 16.450201] Workqueue: smc_hs_wq smc_listen_wor k
[ 16.450531] RIP: 0010:smc_listen_work+0xc02/0x159 0
[ 16.452158] RSP: 0018:ffffb5ab40053d98 EFLAGS: 0001024 6
[ 16.452526] RAX: 0000000000000001 RBX: 0000000000000002 RCX: 000000000000030 0
[ 16.452994] RDX: 0000000000000280 RSI: 00003513840053f0 RDI: 000000000000000 0
[ 16.453492] RBP: ffffa097808e3800 R08: ffffa09782dba1e0 R09: 000000000000000 5
[ 16.453987] R10: 0000000000000000 R11: 0000000000000000 R12: ffffa0978274640 0
[ 16.454497] R13: 0000000000000000 R14: 0000000000000000 R15: ffffa09782d4092 0
[ 16.454996] FS: 0000000000000000(0000) GS:ffffa097bbc00000(0000) knlGS:000000000000000 0
[ 16.455557] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003 3
[ 16.455961] CR2: 0000000000000030 CR3: 0000000102788004 CR4: 0000000000770ef 0
[ 16.456459] PKRU: 5555555 4
[ 16.456654] Call Trace :
[ 16.456832] <TASK >
[ 16.456989] ? __die+0x23/0x7 0
[ 16.457215] ? page_fault_oops+0x180/0x4c 0
[ 16.457508] ? __lock_acquire+0x3e6/0x249 0
[ 16.457801] ? exc_page_fault+0x68/0x20 0
[ 16.458080] ? asm_exc_page_fault+0x26/0x3 0
[ 16.458389] ? smc_listen_work+0xc02/0x159 0
[ 16.458689] ? smc_listen_work+0xc02/0x159 0
[ 16.458987] ? lock_is_held_type+0x8f/0x10 0
[ 16.459284] process_one_work+0x1ea/0x6d 0
[ 16.459570] worker_thread+0x1c3/0x38 0
[ 16.459839] ? __pfx_worker_thread+0x10/0x1 0
[ 16.460144] kthread+0xe0/0x11 0
[ 16.460372] ? __pfx_kthread+0x10/0x1 0
[ 16.460640] ret_from_fork+0x31/0x5 0
[ 16.460896] ? __pfx_kthread+0x10/0x1 0
[ 16.461166] ret_from_fork_asm+0x1a/0x3 0
[ 16.461453] </TASK >
[ 16.461616] Modules linked in: bpf_testmod(OE) [last unloaded: bpf_testmod(OE) ]
[ 16.462134] CR2: 000000000000003 0
[ 16.462380] ---[ end trace 0000000000000000 ]---
[ 16.462710] RIP: 0010:smc_listen_work+0xc02/0x1590
The direct cause of this issue is that after smc_listen_out_connected(),
newclcsock->sk may be NULL since it will releases the smcsk. Therefore,
if the application closes the socket immediately after accept,
newclcsock->sk can be NULL. A possible execution order could be as
follows:
smc_listen_work | userspace
-----------------------------------------------------------------
lock_sock(sk) |
smc_listen_out_connected() |
| \- smc_listen_out |
| | \- release_sock |
| |- sk->sk_data_ready() |
| fd = accept();
| close(fd);
| \- socket->sk = NULL;
/* newclcsock->sk is NULL now */
SMC_STAT_SERV_SUCC_INC(sock_net(newclcsock->sk))
Since smc_listen_out_connected() will not fail, simply swapping the order
of the code can easily fix this issue.
Fixes: 3b2dec2603d5 ("net/smc: restructure client and server code in af_smc")
Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20250818054618.41615-1-alibuda@linux.alibaba.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/af_smc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 71ceaab9b6dd3..75d9036282298 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -2468,8 +2468,9 @@ static void smc_listen_work(struct work_struct *work)
mutex_unlock(&smc_server_lgr_pending);
}
smc_conn_save_peer_info(new_smc, cclc);
- smc_listen_out_connected(new_smc);
SMC_STAT_SERV_SUCC_INC(sock_net(newclcsock->sk), ini);
+ /* smc_listen_out() will release smcsk */
+ smc_listen_out_connected(new_smc);
goto out_free;
out_unlock:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0832/1887] net/sched: Fix backlog accounting in qdisc_dequeue_internal
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (830 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0831/1887] net/smc: fix UAF on smcsk after smc_listen_out() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0833/1887] drm/amd/display: fix a Null pointer dereference vulnerability Greg Kroah-Hartman
` (166 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, William Liu, Savino Dicanosa,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Liu <will@willsroot.io>
[ Upstream commit 52bf272636bda69587952b35ae97690b8dc89941 ]
This issue applies for the following qdiscs: hhf, fq, fq_codel, and
fq_pie, and occurs in their change handlers when adjusting to the new
limit. The problem is the following in the values passed to the
subsequent qdisc_tree_reduce_backlog call given a tbf parent:
When the tbf parent runs out of tokens, skbs of these qdiscs will
be placed in gso_skb. Their peek handlers are qdisc_peek_dequeued,
which accounts for both qlen and backlog. However, in the case of
qdisc_dequeue_internal, ONLY qlen is accounted for when pulling
from gso_skb. This means that these qdiscs are missing a
qdisc_qstats_backlog_dec when dropping packets to satisfy the
new limit in their change handlers.
One can observe this issue with the following (with tc patched to
support a limit of 0):
export TARGET=fq
tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: tbf rate 8bit burst 100b latency 1ms
tc qdisc replace dev lo handle 3: parent 1:1 $TARGET limit 1000
echo ''; echo 'add child'; tc -s -d qdisc show dev lo
ping -I lo -f -c2 -s32 -W0.001 127.0.0.1 2>&1 >/dev/null
echo ''; echo 'after ping'; tc -s -d qdisc show dev lo
tc qdisc change dev lo handle 3: parent 1:1 $TARGET limit 0
echo ''; echo 'after limit drop'; tc -s -d qdisc show dev lo
tc qdisc replace dev lo handle 2: parent 1:1 sfq
echo ''; echo 'post graft'; tc -s -d qdisc show dev lo
The second to last show command shows 0 packets but a positive
number (74) of backlog bytes. The problem becomes clearer in the
last show command, where qdisc_purge_queue triggers
qdisc_tree_reduce_backlog with the positive backlog and causes an
underflow in the tbf parent's backlog (4096 Mb instead of 0).
To fix this issue, the codepath for all clients of qdisc_dequeue_internal
has been simplified: codel, pie, hhf, fq, fq_pie, and fq_codel.
qdisc_dequeue_internal handles the backlog adjustments for all cases that
do not directly use the dequeue handler.
The old fq_codel_change limit adjustment loop accumulated the arguments to
the subsequent qdisc_tree_reduce_backlog call through the cstats field.
However, this is confusing and error prone as fq_codel_dequeue could also
potentially mutate this field (which qdisc_dequeue_internal calls in the
non gso_skb case), so we have unified the code here with other qdiscs.
Fixes: 2d3cbfd6d54a ("net_sched: Flush gso_skb list too during ->change()")
Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM")
Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc")
Signed-off-by: William Liu <will@willsroot.io>
Reviewed-by: Savino Dicanosa <savy@syst3mfailure.io>
Link: https://patch.msgid.link/20250812235725.45243-1-will@willsroot.io
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sch_generic.h | 11 ++++++++---
net/sched/sch_codel.c | 12 +++++++-----
net/sched/sch_fq.c | 12 +++++++-----
net/sched/sch_fq_codel.c | 12 +++++++-----
net/sched/sch_fq_pie.c | 12 +++++++-----
net/sched/sch_hhf.c | 12 +++++++-----
net/sched/sch_pie.c | 12 +++++++-----
7 files changed, 50 insertions(+), 33 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d932af97fa579..ae7b5535eeb13 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -1048,12 +1048,17 @@ static inline struct sk_buff *qdisc_dequeue_internal(struct Qdisc *sch, bool dir
skb = __skb_dequeue(&sch->gso_skb);
if (skb) {
sch->q.qlen--;
+ qdisc_qstats_backlog_dec(sch, skb);
return skb;
}
- if (direct)
- return __qdisc_dequeue_head(&sch->q);
- else
+ if (direct) {
+ skb = __qdisc_dequeue_head(&sch->q);
+ if (skb)
+ qdisc_qstats_backlog_dec(sch, skb);
+ return skb;
+ } else {
return sch->dequeue(sch);
+ }
}
static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
index 1f30dc76d20c7..655eee9e629be 100644
--- a/net/sched/sch_codel.c
+++ b/net/sched/sch_codel.c
@@ -168,9 +168,9 @@ static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = {
static int codel_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct codel_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_CODEL_MAX + 1];
- unsigned int qlen, dropped = 0;
int err;
err = nla_parse_nested_deprecated(tb, TCA_CODEL_MAX, opt,
@@ -204,15 +204,17 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt,
if (tb[TCA_CODEL_ECN])
q->params.ecn = !!nla_get_u32(tb[TCA_CODEL_ECN]);
- qlen = sch->q.qlen;
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
- dropped += qdisc_pkt_len(skb);
- qdisc_qstats_backlog_dec(sch, skb);
+ if (!skb)
+ break;
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_qdisc_drop(skb, sch);
}
- qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return 0;
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 91f5ef6be0f23..2223edfd7aa77 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -806,11 +806,11 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
static int fq_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct fq_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_FQ_MAX + 1];
- int err, drop_count = 0;
- unsigned drop_len = 0;
u32 fq_log;
+ int err;
err = nla_parse_nested_deprecated(tb, TCA_FQ_MAX, opt, fq_policy,
NULL);
@@ -900,16 +900,18 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt,
err = fq_resize(sch, fq_log);
sch_tree_lock(sch);
}
+
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
if (!skb)
break;
- drop_len += qdisc_pkt_len(skb);
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_kfree_skbs(skb, skb);
- drop_count++;
}
- qdisc_tree_reduce_backlog(sch, drop_count, drop_len);
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return err;
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 08cb94bf5950b..f618ec382081b 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -402,6 +402,7 @@ static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = {
static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct fq_codel_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_FQ_CODEL_MAX + 1];
u32 quantum = 0;
@@ -470,13 +471,14 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
q->memory_usage > q->memory_limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
- q->cstats.drop_len += qdisc_pkt_len(skb);
+ if (!skb)
+ break;
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_kfree_skbs(skb, skb);
- q->cstats.drop_count++;
}
- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, q->cstats.drop_len);
- q->cstats.drop_count = 0;
- q->cstats.drop_len = 0;
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return 0;
diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
index 75d6e7716ae8e..d7c144af98916 100644
--- a/net/sched/sch_fq_pie.c
+++ b/net/sched/sch_fq_pie.c
@@ -284,10 +284,9 @@ static struct sk_buff *fq_pie_qdisc_dequeue(struct Qdisc *sch)
static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct fq_pie_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_FQ_PIE_MAX + 1];
- unsigned int len_dropped = 0;
- unsigned int num_dropped = 0;
int err;
err = nla_parse_nested(tb, TCA_FQ_PIE_MAX, opt, fq_pie_policy, extack);
@@ -366,11 +365,14 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
- len_dropped += qdisc_pkt_len(skb);
- num_dropped += 1;
+ if (!skb)
+ break;
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_kfree_skbs(skb, skb);
}
- qdisc_tree_reduce_backlog(sch, num_dropped, len_dropped);
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return 0;
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index e1e8527e45192..17027d1f4d11a 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -536,9 +536,9 @@ static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {
static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct hhf_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_HHF_MAX + 1];
- unsigned int qlen, prev_backlog;
int err;
u64 non_hh_quantum;
u32 new_quantum = q->quantum;
@@ -585,15 +585,17 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
q->hhf_evict_timeout = usecs_to_jiffies(us);
}
- qlen = sch->q.qlen;
- prev_backlog = sch->qstats.backlog;
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
+ if (!skb)
+ break;
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_kfree_skbs(skb, skb);
}
- qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen,
- prev_backlog - sch->qstats.backlog);
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return 0;
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index 1ed6f43c93c4d..5dffe25457b87 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -138,9 +138,9 @@ static const struct nla_policy pie_policy[TCA_PIE_MAX + 1] = {
static int pie_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
+ unsigned int dropped_pkts = 0, dropped_bytes = 0;
struct pie_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_PIE_MAX + 1];
- unsigned int qlen, dropped = 0;
int err;
err = nla_parse_nested_deprecated(tb, TCA_PIE_MAX, opt, pie_policy,
@@ -188,15 +188,17 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt,
nla_get_u32(tb[TCA_PIE_DQ_RATE_ESTIMATOR]);
/* Drop excess packets if new limit is lower */
- qlen = sch->q.qlen;
while (sch->q.qlen > sch->limit) {
struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
- dropped += qdisc_pkt_len(skb);
- qdisc_qstats_backlog_dec(sch, skb);
+ if (!skb)
+ break;
+
+ dropped_pkts++;
+ dropped_bytes += qdisc_pkt_len(skb);
rtnl_qdisc_drop(skb, sch);
}
- qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
+ qdisc_tree_reduce_backlog(sch, dropped_pkts, dropped_bytes);
sch_tree_unlock(sch);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0833/1887] drm/amd/display: fix a Null pointer dereference vulnerability
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (831 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0832/1887] net/sched: Fix backlog accounting in qdisc_dequeue_internal Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0834/1887] ksmbd: fix refcount leak causing resource not released Greg Kroah-Hartman
` (165 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Siyang Liu,
Roman Li, Alex Hung, Daniel Wheeler, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siyang Liu <Security@tencent.com>
[ Upstream commit 1bcf63a44381691d6192872801f830ce3250e367 ]
[Why]
A null pointer dereference vulnerability exists in the AMD display driver's
(DC module) cleanup function dc_destruct().
When display control context (dc->ctx) construction fails
(due to memory allocation failure), this pointer remains NULL.
During subsequent error handling when dc_destruct() is called,
there's no NULL check before dereferencing the perf_trace member
(dc->ctx->perf_trace), causing a kernel null pointer dereference crash.
[How]
Check if dc->ctx is non-NULL before dereferencing.
Link: https://lore.kernel.org/r/tencent_54FF4252EDFB6533090A491A25EEF3EDBF06@qq.com
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
(Updated commit text and removed unnecessary error message)
Signed-off-by: Siyang Liu <Security@tencent.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 9dd8e2ba268c636c240a918e0a31e6feaee19404)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 7594aaf79a101..cfcd4ed1666d0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -831,16 +831,18 @@ static void dc_destruct(struct dc *dc)
dc_destroy_resource_pool(dc);
- if (dc->ctx->gpio_service)
- dal_gpio_service_destroy(&dc->ctx->gpio_service);
+ if (dc->ctx) {
+ if (dc->ctx->gpio_service)
+ dal_gpio_service_destroy(&dc->ctx->gpio_service);
- if (dc->ctx->created_bios)
- dal_bios_parser_destroy(&dc->ctx->dc_bios);
+ if (dc->ctx->created_bios)
+ dal_bios_parser_destroy(&dc->ctx->dc_bios);
- dc_perf_trace_destroy(&dc->ctx->perf_trace);
+ dc_perf_trace_destroy(&dc->ctx->perf_trace);
- kfree(dc->ctx);
- dc->ctx = NULL;
+ kfree(dc->ctx);
+ dc->ctx = NULL;
+ }
kfree(dc->bw_vbios);
dc->bw_vbios = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0834/1887] ksmbd: fix refcount leak causing resource not released
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (832 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0833/1887] drm/amd/display: fix a Null pointer dereference vulnerability Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0835/1887] s390/ism: Introduce struct ism_dmb Greg Kroah-Hartman
` (164 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ziyan Xu, Namjae Jeon, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziyan Xu <ziyan@securitygossip.com>
[ Upstream commit 89bb430f621124af39bb31763c4a8b504c9651e2 ]
When ksmbd_conn_releasing(opinfo->conn) returns true,the refcount was not
decremented properly, causing a refcount leak that prevents the count from
reaching zero and the memory from being released.
Cc: stable@vger.kernel.org
Signed-off-by: Ziyan Xu <ziyan@securitygossip.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/oplock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 58f351be5d905..a81c56b3fe965 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -1142,6 +1142,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
atomic_inc(&opinfo->conn->r_count);
if (ksmbd_conn_releasing(opinfo->conn)) {
atomic_dec(&opinfo->conn->r_count);
+ opinfo_put(opinfo);
continue;
}
@@ -1184,6 +1185,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
atomic_inc(&opinfo->conn->r_count);
if (ksmbd_conn_releasing(opinfo->conn)) {
atomic_dec(&opinfo->conn->r_count);
+ opinfo_put(opinfo);
continue;
}
read_unlock(&p_ci->m_lock);
@@ -1390,6 +1392,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
atomic_inc(&brk_op->conn->r_count);
if (ksmbd_conn_releasing(brk_op->conn)) {
atomic_dec(&brk_op->conn->r_count);
+ opinfo_put(brk_op);
continue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0835/1887] s390/ism: Introduce struct ism_dmb
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (833 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0834/1887] ksmbd: fix refcount leak causing resource not released Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0836/1887] s390/ism: fix concurrency management in ism_cmd() Greg Kroah-Hartman
` (163 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Raspl, Jan Karcher,
Wenjia Zhang, David S. Miller, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Raspl <raspl@linux.ibm.com>
[ Upstream commit 1baedb13f1d50ae8c7852134fdf934b4463e9baa ]
Conceptually, a DMB is a structure that belongs to ISM devices. However,
SMC currently 'owns' this structure. So future exploiters of ISM devices
would be forced to include SMC headers to work - which is just weird.
Therefore, we switch ISM to struct ism_dmb, introduce a new public header
with the definition (will be populated with further API calls later on),
and, add a thin wrapper to please SMC. Since structs smcd_dmb and ism_dmb
are identical, we can simply convert between the two for now.
Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Signed-off-by: Jan Karcher <jaka@linux.ibm.com>
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: 897e8601b9cf ("s390/ism: fix concurrency management in ism_cmd()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/net/ism.h | 1 +
drivers/s390/net/ism_drv.c | 22 ++++++++++++++++------
include/linux/ism.h | 23 +++++++++++++++++++++++
3 files changed, 40 insertions(+), 6 deletions(-)
create mode 100644 include/linux/ism.h
diff --git a/drivers/s390/net/ism.h b/drivers/s390/net/ism.h
index 38fe90c2597d1..90af513701836 100644
--- a/drivers/s390/net/ism.h
+++ b/drivers/s390/net/ism.h
@@ -5,6 +5,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/pci.h>
+#include <linux/ism.h>
#include <net/smc.h>
#include <asm/pci_insn.h>
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index d34bb6ec1490f..cae64eccead9b 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -215,14 +215,14 @@ static int ism_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
return ism_cmd(ism, &cmd);
}
-static void ism_free_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
+static void ism_free_dmb(struct ism_dev *ism, struct ism_dmb *dmb)
{
clear_bit(dmb->sba_idx, ism->sba_bitmap);
dma_free_coherent(&ism->pdev->dev, dmb->dmb_len,
dmb->cpu_addr, dmb->dma_addr);
}
-static int ism_alloc_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
+static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb)
{
unsigned long bit;
@@ -250,7 +250,7 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
return dmb->cpu_addr ? 0 : -ENOMEM;
}
-static int ism_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
+static int ism_register_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
{
struct ism_dev *ism = smcd->priv;
union ism_reg_dmb cmd;
@@ -281,7 +281,12 @@ static int ism_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
return ret;
}
-static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
+static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
+{
+ return ism_register_dmb(smcd, (struct ism_dmb *)dmb);
+}
+
+static int ism_unregister_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
{
struct ism_dev *ism = smcd->priv;
union ism_unreg_dmb cmd;
@@ -302,6 +307,11 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
return ret;
}
+static int smcd_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
+{
+ return ism_unregister_dmb(smcd, (struct ism_dmb *)dmb);
+}
+
static int ism_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
{
struct ism_dev *ism = smcd->priv;
@@ -474,8 +484,8 @@ static irqreturn_t ism_handle_irq(int irq, void *data)
static const struct smcd_ops ism_ops = {
.query_remote_gid = ism_query_rgid,
- .register_dmb = ism_register_dmb,
- .unregister_dmb = ism_unregister_dmb,
+ .register_dmb = smcd_register_dmb,
+ .unregister_dmb = smcd_unregister_dmb,
.add_vlan_id = ism_add_vlan_id,
.del_vlan_id = ism_del_vlan_id,
.set_vlan_required = ism_set_vlan_required,
diff --git a/include/linux/ism.h b/include/linux/ism.h
new file mode 100644
index 0000000000000..69bfbf0faaa10
--- /dev/null
+++ b/include/linux/ism.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Internal Shared Memory
+ *
+ * Definitions for the ISM module
+ *
+ * Copyright IBM Corp. 2022
+ */
+#ifndef _ISM_H
+#define _ISM_H
+
+struct ism_dmb {
+ u64 dmb_tok;
+ u64 rgid;
+ u32 dmb_len;
+ u32 sba_idx;
+ u32 vlan_valid;
+ u32 vlan_id;
+ void *cpu_addr;
+ dma_addr_t dma_addr;
+};
+
+#endif /* _ISM_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0836/1887] s390/ism: fix concurrency management in ism_cmd()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (834 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0835/1887] s390/ism: Introduce struct ism_dmb Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0837/1887] rcu: Fix rcu_read_unlock() deadloop due to IRQ work Greg Kroah-Hartman
` (162 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aliaksei Makarau, Mahanta Jambigi,
Halil Pasic, Alexandra Winter, Simon Horman, Paolo Abeni,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Halil Pasic <pasic@linux.ibm.com>
[ Upstream commit 897e8601b9cff1d054cdd53047f568b0e1995726 ]
The s390x ISM device data sheet clearly states that only one
request-response sequence is allowable per ISM function at any point in
time. Unfortunately as of today the s390/ism driver in Linux does not
honor that requirement. This patch aims to rectify that.
This problem was discovered based on Aliaksei's bug report which states
that for certain workloads the ISM functions end up entering error state
(with PEC 2 as seen from the logs) after a while and as a consequence
connections handled by the respective function break, and for future
connection requests the ISM device is not considered -- given it is in a
dysfunctional state. During further debugging PEC 3A was observed as
well.
A kernel message like
[ 1211.244319] zpci: 061a:00:00.0: Event 0x2 reports an error for PCI function 0x61a
is a reliable indicator of the stated function entering error state
with PEC 2. Let me also point out that a kernel message like
[ 1211.244325] zpci: 061a:00:00.0: The ism driver bound to the device does not support error recovery
is a reliable indicator that the ISM function won't be auto-recovered
because the ISM driver currently lacks support for it.
On a technical level, without this synchronization, commands (inputs to
the FW) may be partially or fully overwritten (corrupted) by another CPU
trying to issue commands on the same function. There is hard evidence that
this can lead to DMB token values being used as DMB IOVAs, leading to
PEC 2 PCI events indicating invalid DMA. But this is only one of the
failure modes imaginable. In theory even completely losing one command
and executing another one twice and then trying to interpret the outputs
as if the command we intended to execute was actually executed and not
the other one is also possible. Frankly, I don't feel confident about
providing an exhaustive list of possible consequences.
Fixes: 684b89bc39ce ("s390/ism: add device driver for internal shared memory")
Reported-by: Aliaksei Makarau <Aliaksei.Makarau@ibm.com>
Tested-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Tested-by: Aliaksei Makarau <Aliaksei.Makarau@ibm.com>
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250722161817.1298473-1-wintera@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/net/ism.h | 1 +
drivers/s390/net/ism_drv.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/drivers/s390/net/ism.h b/drivers/s390/net/ism.h
index 90af513701836..6f21e05b9c6c9 100644
--- a/drivers/s390/net/ism.h
+++ b/drivers/s390/net/ism.h
@@ -192,6 +192,7 @@ struct ism_sba {
struct ism_dev {
spinlock_t lock;
+ spinlock_t cmd_lock; /* serializes cmds */
struct pci_dev *pdev;
struct smcd_dev *smcd;
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index cae64eccead9b..9576e3975c721 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -40,6 +40,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd)
struct ism_req_hdr *req = cmd;
struct ism_resp_hdr *resp = cmd;
+ spin_lock(&ism->cmd_lock);
__ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req));
__ism_write_cmd(ism, req, 0, sizeof(*req));
@@ -53,6 +54,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd)
}
__ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp));
out:
+ spin_unlock(&ism->cmd_lock);
return resp->ret;
}
@@ -555,6 +557,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENOMEM;
spin_lock_init(&ism->lock);
+ spin_lock_init(&ism->cmd_lock);
dev_set_drvdata(&pdev->dev, ism);
ism->pdev = pdev;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0837/1887] rcu: Fix rcu_read_unlock() deadloop due to IRQ work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (835 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0836/1887] s390/ism: fix concurrency management in ism_cmd() Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0838/1887] mm/smaps: fix race between smaps_hugetlb_range and migration Greg Kroah-Hartman
` (161 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiongfeng Wang, Qi Xi,
Joel Fernandes, Paul E. McKenney, Linux Kernel Functional Testing,
Neeraj Upadhyay (AMD), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Fernandes <joelagnelf@nvidia.com>
[ Upstream commit b41642c87716bbd09797b1e4ea7d904f06c39b7b ]
During rcu_read_unlock_special(), if this happens during irq_exit(), we
can lockup if an IPI is issued. This is because the IPI itself triggers
the irq_exit() path causing a recursive lock up.
This is precisely what Xiongfeng found when invoking a BPF program on
the trace_tick_stop() tracepoint As shown in the trace below. Fix by
managing the irq_work state correctly.
irq_exit()
__irq_exit_rcu()
/* in_hardirq() returns false after this */
preempt_count_sub(HARDIRQ_OFFSET)
tick_irq_exit()
tick_nohz_irq_exit()
tick_nohz_stop_sched_tick()
trace_tick_stop() /* a bpf prog is hooked on this trace point */
__bpf_trace_tick_stop()
bpf_trace_run2()
rcu_read_unlock_special()
/* will send a IPI to itself */
irq_work_queue_on(&rdp->defer_qs_iw, rdp->cpu);
A simple reproducer can also be obtained by doing the following in
tick_irq_exit(). It will hang on boot without the patch:
static inline void tick_irq_exit(void)
{
+ rcu_read_lock();
+ WRITE_ONCE(current->rcu_read_unlock_special.b.need_qs, true);
+ rcu_read_unlock();
+
Reported-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Closes: https://lore.kernel.org/all/9acd5f9f-6732-7701-6880-4b51190aa070@huawei.com/
Tested-by: Qi Xi <xiqi2@huawei.com>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
Reviewed-by: "Paul E. McKenney" <paulmck@kernel.org>
Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
[neeraj: Apply Frederic's suggested fix for PREEMPT_RT]
Signed-off-by: Neeraj Upadhyay (AMD) <neeraj.upadhyay@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/rcu/tree.h | 13 ++++++++++++-
kernel/rcu/tree_plugin.h | 37 ++++++++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index aa16d3cd62ba5..4770ff998f27d 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -158,6 +158,17 @@ union rcu_noqs {
u16 s; /* Set of bits, aggregate OR here. */
};
+/*
+ * An IRQ work (deferred_qs_iw) is used by RCU to get the scheduler's attention.
+ * to report quiescent states at the soonest possible time.
+ * The request can be in one of the following states:
+ * - DEFER_QS_IDLE: An IRQ work is yet to be scheduled.
+ * - DEFER_QS_PENDING: An IRQ work was scheduled but either not yet run, or it
+ * ran and we still haven't reported a quiescent state.
+ */
+#define DEFER_QS_IDLE 0
+#define DEFER_QS_PENDING 1
+
/* Per-CPU data for read-copy update. */
struct rcu_data {
/* 1) quiescent-state and grace-period handling : */
@@ -175,7 +186,7 @@ struct rcu_data {
/* during and after the last grace */
/* period it is aware of. */
struct irq_work defer_qs_iw; /* Obtain later scheduler attention. */
- bool defer_qs_iw_pending; /* Scheduler attention pending? */
+ int defer_qs_iw_pending; /* Scheduler attention pending? */
struct work_struct strict_work; /* Schedule readers for strict GPs. */
/* 2) batch handling */
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 4cb5c901a2049..7dd83a4d86810 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -474,13 +474,16 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
struct rcu_node *rnp;
union rcu_special special;
+ rdp = this_cpu_ptr(&rcu_data);
+ if (rdp->defer_qs_iw_pending == DEFER_QS_PENDING)
+ rdp->defer_qs_iw_pending = DEFER_QS_IDLE;
+
/*
* If RCU core is waiting for this CPU to exit its critical section,
* report the fact that it has exited. Because irqs are disabled,
* t->rcu_read_unlock_special cannot change.
*/
special = t->rcu_read_unlock_special;
- rdp = this_cpu_ptr(&rcu_data);
if (!special.s && !rdp->cpu_no_qs.b.exp) {
local_irq_restore(flags);
return;
@@ -617,7 +620,23 @@ static void rcu_preempt_deferred_qs_handler(struct irq_work *iwp)
rdp = container_of(iwp, struct rcu_data, defer_qs_iw);
local_irq_save(flags);
- rdp->defer_qs_iw_pending = false;
+
+ /*
+ * If the IRQ work handler happens to run in the middle of RCU read-side
+ * critical section, it could be ineffective in getting the scheduler's
+ * attention to report a deferred quiescent state (the whole point of the
+ * IRQ work). For this reason, requeue the IRQ work.
+ *
+ * Basically, we want to avoid following situation:
+ * 1. rcu_read_unlock() queues IRQ work (state -> DEFER_QS_PENDING)
+ * 2. CPU enters new rcu_read_lock()
+ * 3. IRQ work runs but cannot report QS due to rcu_preempt_depth() > 0
+ * 4. rcu_read_unlock() does not re-queue work (state still PENDING)
+ * 5. Deferred QS reporting does not happen.
+ */
+ if (rcu_preempt_depth() > 0)
+ WRITE_ONCE(rdp->defer_qs_iw_pending, DEFER_QS_IDLE);
+
local_irq_restore(flags);
}
@@ -664,17 +683,13 @@ static void rcu_read_unlock_special(struct task_struct *t)
set_tsk_need_resched(current);
set_preempt_need_resched();
if (IS_ENABLED(CONFIG_IRQ_WORK) && irqs_were_disabled &&
- expboost && !rdp->defer_qs_iw_pending && cpu_online(rdp->cpu)) {
+ expboost && rdp->defer_qs_iw_pending != DEFER_QS_PENDING &&
+ cpu_online(rdp->cpu)) {
// Get scheduler to re-evaluate and call hooks.
// If !IRQ_WORK, FQS scan will eventually IPI.
- if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) &&
- IS_ENABLED(CONFIG_PREEMPT_RT))
- rdp->defer_qs_iw = IRQ_WORK_INIT_HARD(
- rcu_preempt_deferred_qs_handler);
- else
- init_irq_work(&rdp->defer_qs_iw,
- rcu_preempt_deferred_qs_handler);
- rdp->defer_qs_iw_pending = true;
+ rdp->defer_qs_iw =
+ IRQ_WORK_INIT_HARD(rcu_preempt_deferred_qs_handler);
+ rdp->defer_qs_iw_pending = DEFER_QS_PENDING;
irq_work_queue_on(&rdp->defer_qs_iw, rdp->cpu);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0838/1887] mm/smaps: fix race between smaps_hugetlb_range and migration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (836 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0837/1887] rcu: Fix rcu_read_unlock() deadloop due to IRQ work Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0839/1887] LoongArch: Optimize module load time by optimizing PLT/GOT counting Greg Kroah-Hartman
` (160 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jinjiang Tu, David Hildenbrand,
Andrei Vagin, Andrii Nakryiko, Baolin Wang, Brahmajit Das,
Catalin Marinas, Christophe Leroy, David Rientjes, Dev Jain,
Hugh Dickins, Joern Engel, Kefeng Wang, Lorenzo Stoakes,
Michal Hocko, Ryan Roberts, Thiago Jung Bauermann, Andrew Morton,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu <tujinjiang@huawei.com>
[ Upstream commit 45d19b4b6c2d422771c29b83462d84afcbb33f01 ]
smaps_hugetlb_range() handles the pte without holdling ptl, and may be
concurrenct with migration, leaing to BUG_ON in pfn_swap_entry_to_page().
The race is as follows.
smaps_hugetlb_range migrate_pages
huge_ptep_get
remove_migration_ptes
folio_unlock
pfn_swap_entry_folio
BUG_ON
To fix it, hold ptl lock in smaps_hugetlb_range().
Link: https://lkml.kernel.org/r/20250724090958.455887-1-tujinjiang@huawei.com
Link: https://lkml.kernel.org/r/20250724090958.455887-2-tujinjiang@huawei.com
Fixes: 25ee01a2fca0 ("mm: hugetlb: proc: add hugetlb-related fields to /proc/PID/smaps")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Andrei Vagin <avagin@gmail.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Brahmajit Das <brahmajit.xyz@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: David Rientjes <rientjes@google.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Joern Engel <joern@logfs.org>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/proc/task_mmu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 484886cdd272c..eb002adf9f59f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -727,7 +727,9 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
struct mem_size_stats *mss = walk->private;
struct vm_area_struct *vma = walk->vma;
struct page *page = NULL;
+ spinlock_t *ptl;
+ ptl = huge_pte_lock(hstate_vma(vma), walk->mm, pte);
if (pte_present(*pte)) {
page = vm_normal_page(vma, addr, *pte);
} else if (is_swap_pte(*pte)) {
@@ -742,6 +744,7 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
else
mss->private_hugetlb += huge_page_size(hstate_vma(vma));
}
+ spin_unlock(ptl);
return 0;
}
#else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0839/1887] LoongArch: Optimize module load time by optimizing PLT/GOT counting
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (837 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0838/1887] mm/smaps: fix race between smaps_hugetlb_range and migration Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0840/1887] xfrm: Duplicate SPI Handling Greg Kroah-Hartman
` (159 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kanglong Wang, Huacai Chen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kanglong Wang <wangkanglong@loongson.cn>
[ Upstream commit 63dbd8fb2af3a89466538599a9acb2d11ef65c06 ]
When enabling CONFIG_KASAN, CONFIG_PREEMPT_VOLUNTARY_BUILD and
CONFIG_PREEMPT_VOLUNTARY at the same time, there will be soft deadlock,
the relevant logs are as follows:
rcu: INFO: rcu_sched self-detected stall on CPU
...
Call Trace:
[<900000000024f9e4>] show_stack+0x5c/0x180
[<90000000002482f4>] dump_stack_lvl+0x94/0xbc
[<9000000000224544>] rcu_dump_cpu_stacks+0x1fc/0x280
[<900000000037ac80>] rcu_sched_clock_irq+0x720/0xf88
[<9000000000396c34>] update_process_times+0xb4/0x150
[<90000000003b2474>] tick_nohz_handler+0xf4/0x250
[<9000000000397e28>] __hrtimer_run_queues+0x1d0/0x428
[<9000000000399b2c>] hrtimer_interrupt+0x214/0x538
[<9000000000253634>] constant_timer_interrupt+0x64/0x80
[<9000000000349938>] __handle_irq_event_percpu+0x78/0x1a0
[<9000000000349a78>] handle_irq_event_percpu+0x18/0x88
[<9000000000354c00>] handle_percpu_irq+0x90/0xf0
[<9000000000348c74>] handle_irq_desc+0x94/0xb8
[<9000000001012b28>] handle_cpu_irq+0x68/0xa0
[<9000000001def8c0>] handle_loongarch_irq+0x30/0x48
[<9000000001def958>] do_vint+0x80/0xd0
[<9000000000268a0c>] kasan_mem_to_shadow.part.0+0x2c/0x2a0
[<90000000006344f4>] __asan_load8+0x4c/0x120
[<900000000025c0d0>] module_frob_arch_sections+0x5c8/0x6b8
[<90000000003895f0>] load_module+0x9e0/0x2958
[<900000000038b770>] __do_sys_init_module+0x208/0x2d0
[<9000000001df0c34>] do_syscall+0x94/0x190
[<900000000024d6fc>] handle_syscall+0xbc/0x158
After analysis, this is because the slow speed of loading the amdgpu
module leads to the long time occupation of the cpu and then the soft
deadlock.
When loading a module, module_frob_arch_sections() tries to figure out
the number of PLTs/GOTs that will be needed to handle all the RELAs. It
will call the count_max_entries() to find in an out-of-order date which
counting algorithm has O(n^2) complexity.
To make it faster, we sort the relocation list by info and addend. That
way, to check for a duplicate relocation, it just needs to compare with
the previous entry. This reduces the complexity of the algorithm to O(n
log n), as done in commit d4e0340919fb ("arm64/module: Optimize module
load time by optimizing PLT counting"). This gives sinificant reduction
in module load time for modules with large number of relocations.
After applying this patch, the soft deadlock problem has been solved,
and the kernel starts normally without "Call Trace".
Using the default configuration to test some modules, the results are as
follows:
Module Size
ip_tables 36K
fat 143K
radeon 2.5MB
amdgpu 16MB
Without this patch:
Module Module load time (ms) Count(PLTs/GOTs)
ip_tables 18 59/6
fat 0 162/14
radeon 54 1221/84
amdgpu 1411 4525/1098
With this patch:
Module Module load time (ms) Count(PLTs/GOTs)
ip_tables 18 59/6
fat 0 162/14
radeon 22 1221/84
amdgpu 45 4525/1098
Fixes: fcdfe9d22bed ("LoongArch: Add ELF and module support")
Signed-off-by: Kanglong Wang <wangkanglong@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/kernel/module-sections.c | 36 ++++++++++++-------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
index d296a70b758fd..10969d242f44d 100644
--- a/arch/loongarch/kernel/module-sections.c
+++ b/arch/loongarch/kernel/module-sections.c
@@ -6,6 +6,7 @@
#include <linux/elf.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/sort.h>
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val)
{
@@ -59,39 +60,38 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Addr val)
return (Elf_Addr)&plt[nr];
}
-static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y)
-{
- return x->r_info == y->r_info && x->r_addend == y->r_addend;
-}
+#define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b))
-static bool duplicate_rela(const Elf_Rela *rela, int idx)
+static int compare_rela(const void *x, const void *y)
{
- int i;
+ int ret;
+ const Elf_Rela *rela_x = x, *rela_y = y;
- for (i = 0; i < idx; i++) {
- if (is_rela_equal(&rela[i], &rela[idx]))
- return true;
- }
+ ret = cmp_3way(rela_x->r_info, rela_y->r_info);
+ if (ret == 0)
+ ret = cmp_3way(rela_x->r_addend, rela_y->r_addend);
- return false;
+ return ret;
}
static void count_max_entries(Elf_Rela *relas, int num,
unsigned int *plts, unsigned int *gots)
{
- unsigned int i, type;
+ unsigned int i;
+
+ sort(relas, num, sizeof(Elf_Rela), compare_rela, NULL);
for (i = 0; i < num; i++) {
- type = ELF_R_TYPE(relas[i].r_info);
- switch (type) {
+ if (i && !compare_rela(&relas[i-1], &relas[i]))
+ continue;
+
+ switch (ELF_R_TYPE(relas[i].r_info)) {
case R_LARCH_SOP_PUSH_PLT_PCREL:
case R_LARCH_B26:
- if (!duplicate_rela(relas, i))
- (*plts)++;
+ (*plts)++;
break;
case R_LARCH_GOT_PC_HI20:
- if (!duplicate_rela(relas, i))
- (*gots)++;
+ (*gots)++;
break;
default:
break; /* Do nothing. */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0840/1887] xfrm: Duplicate SPI Handling
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (838 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0839/1887] LoongArch: Optimize module load time by optimizing PLT/GOT counting Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0841/1887] bnxt_en: Fix memory corruption when FW resources change during ifdown Greg Kroah-Hartman
` (158 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aakash Kumar S, Herbert Xu,
Steffen Klassert, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aakash Kumar S <saakashkumar@marvell.com>
[ Upstream commit 94f39804d891cffe4ce17737d295f3b195bc7299 ]
The issue originates when Strongswan initiates an XFRM_MSG_ALLOCSPI
Netlink message, which triggers the kernel function xfrm_alloc_spi().
This function is expected to ensure uniqueness of the Security Parameter
Index (SPI) for inbound Security Associations (SAs). However, it can
return success even when the requested SPI is already in use, leading
to duplicate SPIs assigned to multiple inbound SAs, differentiated
only by their destination addresses.
This behavior causes inconsistencies during SPI lookups for inbound packets.
Since the lookup may return an arbitrary SA among those with the same SPI,
packet processing can fail, resulting in packet drops.
According to RFC 4301 section 4.4.2 , for inbound processing a unicast SA
is uniquely identified by the SPI and optionally protocol.
Reproducing the Issue Reliably:
To consistently reproduce the problem, restrict the available SPI range in
charon.conf : spi_min = 0x10000000 spi_max = 0x10000002
This limits the system to only 2 usable SPI values.
Next, create more than 2 Child SA. each using unique pair of src/dst address.
As soon as the 3rd Child SA is initiated, it will be assigned a duplicate
SPI, since the SPI pool is already exhausted.
With a narrow SPI range, the issue is consistently reproducible.
With a broader/default range, it becomes rare and unpredictable.
Current implementation:
xfrm_spi_hash() lookup function computes hash using daddr, proto, and family.
So if two SAs have the same SPI but different destination addresses, then
they will:
a. Hash into different buckets
b. Be stored in different linked lists (byspi + h)
c. Not be seen in the same hlist_for_each_entry_rcu() iteration.
As a result, the lookup will result in NULL and kernel allows that Duplicate SPI
Proposed Change:
xfrm_state_lookup_spi_proto() does a truly global search - across all states,
regardless of hash bucket and matches SPI and proto.
Signed-off-by: Aakash Kumar S <saakashkumar@marvell.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_state.c | 67 ++++++++++++++++++++++++++-----------------
1 file changed, 41 insertions(+), 26 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ecafa6950139f..6b4fa60de6d89 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1304,6 +1304,26 @@ struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
}
EXPORT_SYMBOL(xfrm_state_lookup_byspi);
+static struct xfrm_state *xfrm_state_lookup_spi_proto(struct net *net, __be32 spi, u8 proto)
+{
+ struct xfrm_state *x;
+ unsigned int i;
+
+ rcu_read_lock();
+ for (i = 0; i <= net->xfrm.state_hmask; i++) {
+ hlist_for_each_entry_rcu(x, &net->xfrm.state_byspi[i], byspi) {
+ if (x->id.spi == spi && x->id.proto == proto) {
+ if (!xfrm_state_hold_rcu(x))
+ continue;
+ rcu_read_unlock();
+ return x;
+ }
+ }
+ }
+ rcu_read_unlock();
+ return NULL;
+}
+
static void __xfrm_state_insert(struct xfrm_state *x)
{
struct net *net = xs_net(x);
@@ -2091,10 +2111,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
unsigned int h;
struct xfrm_state *x0;
int err = -ENOENT;
- __be32 minspi = htonl(low);
- __be32 maxspi = htonl(high);
+ u32 range = high - low + 1;
__be32 newspi = 0;
- u32 mark = x->mark.v & x->mark.m;
spin_lock_bh(&x->lock);
if (x->km.state == XFRM_STATE_DEAD)
@@ -2106,33 +2124,30 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
err = -ENOENT;
- if (minspi == maxspi) {
- x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
- if (x0) {
- xfrm_state_put(x0);
+ for (h = 0; h < range; h++) {
+ u32 spi = (low == high) ? low : low + prandom_u32_max(high - low + 1);
+ newspi = htonl(spi);
+
+ spin_lock_bh(&net->xfrm.xfrm_state_lock);
+ x0 = xfrm_state_lookup_spi_proto(net, newspi, x->id.proto);
+ if (!x0) {
+ x->id.spi = newspi;
+ h = xfrm_spi_hash(net, &x->id.daddr, newspi, x->id.proto, x->props.family);
+ hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
+ spin_unlock_bh(&net->xfrm.xfrm_state_lock);
+ err = 0;
goto unlock;
}
- newspi = minspi;
- } else {
- u32 spi = 0;
- for (h = 0; h < high-low+1; h++) {
- spi = low + prandom_u32_max(high - low + 1);
- x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
- if (x0 == NULL) {
- newspi = htonl(spi);
- break;
- }
- xfrm_state_put(x0);
- }
- }
- if (newspi) {
- spin_lock_bh(&net->xfrm.xfrm_state_lock);
- x->id.spi = newspi;
- h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
- hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
+ xfrm_state_put(x0);
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
- err = 0;
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ goto unlock;
+ }
+
+ if (low == high)
+ break;
}
unlock:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0841/1887] bnxt_en: Fix memory corruption when FW resources change during ifdown
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (839 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0840/1887] xfrm: Duplicate SPI Handling Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0842/1887] trace/fgraph: Fix the warning caused by missing unregister notifier Greg Kroah-Hartman
` (157 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kalesh AP, Andy Gospodarek,
Sreekanth Reddy, Michael Chan, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
[ Upstream commit 2747328ba2714f1a7454208dbbc1dc0631990b4a ]
bnxt_set_dflt_rings() assumes that it is always called before any TC has
been created. So it doesn't take bp->num_tc into account and assumes
that it is always 0 or 1.
In the FW resource or capability change scenario, the FW will return
flags in bnxt_hwrm_if_change() that will cause the driver to
reinitialize and call bnxt_cancel_reservations(). This will lead to
bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc
may be greater than 1. This will cause bp->tx_ring[] to be sized too
small and cause memory corruption in bnxt_alloc_cp_rings().
Fix it by properly scaling the TX rings by bp->num_tc in the code
paths mentioned above. Add 2 helper functions to determine
bp->tx_nr_rings and bp->tx_nr_rings_per_tc.
Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20250825175927.459987-2-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 24 ++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index de7bef33641a8..7da32225cc165 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -10520,6 +10520,20 @@ static int bnxt_reinit_after_abort(struct bnxt *bp)
return rc;
}
+static int bnxt_tx_nr_rings(struct bnxt *bp)
+{
+ int tcs = netdev_get_num_tc(bp->dev);
+
+ return tcs ? bp->tx_nr_rings_per_tc * tcs : bp->tx_nr_rings_per_tc;
+}
+
+static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
+{
+ int tcs = netdev_get_num_tc(bp->dev);
+
+ return tcs ? bp->tx_nr_rings / tcs : bp->tx_nr_rings;
+}
+
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
int rc = 0;
@@ -13471,7 +13485,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
bp->rx_nr_rings = bp->cp_nr_rings;
bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
+ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
@@ -13502,12 +13516,12 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
bnxt_trim_dflt_sh_rings(bp);
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
+ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "Unable to reserve tx rings\n");
- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
if (sh)
bnxt_trim_dflt_sh_rings(bp);
@@ -13516,7 +13530,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "2nd rings reservation failed.\n");
- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
}
if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
bp->rx_nr_rings++;
@@ -13550,7 +13564,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
if (rc)
goto init_dflt_ring_err;
- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_set_dflt_rfs(bp);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0842/1887] trace/fgraph: Fix the warning caused by missing unregister notifier
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (840 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0841/1887] bnxt_en: Fix memory corruption when FW resources change during ifdown Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:48 ` [PATCH 6.1 0843/1887] vxlan: Fix NPD in {arp,neigh}_reduce() when using nexthop objects Greg Kroah-Hartman
` (156 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google), Ye Weihua,
Steven Rostedt (Google), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Weihua <yeweihua4@huawei.com>
[ Upstream commit edede7a6dcd7435395cf757d053974aaab6ab1c2 ]
This warning was triggered during testing on v6.16:
notifier callback ftrace_suspend_notifier_call already registered
WARNING: CPU: 2 PID: 86 at kernel/notifier.c:23 notifier_chain_register+0x44/0xb0
...
Call Trace:
<TASK>
blocking_notifier_chain_register+0x34/0x60
register_ftrace_graph+0x330/0x410
ftrace_profile_write+0x1e9/0x340
vfs_write+0xf8/0x420
? filp_flush+0x8a/0xa0
? filp_close+0x1f/0x30
? do_dup2+0xaf/0x160
ksys_write+0x65/0xe0
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x77/0x7f
When writing to the function_profile_enabled interface, the notifier was
not unregistered after start_graph_tracing failed, causing a warning the
next time function_profile_enabled was written.
Fixed by adding unregister_pm_notifier in the exception path.
Link: https://lore.kernel.org/20250818073332.3890629-1-yeweihua4@huawei.com
Fixes: 4a2b8dda3f870 ("tracing/function-graph-tracer: fix a regression while suspend to disk")
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Ye Weihua <yeweihua4@huawei.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/fgraph.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 218cd95bf8e48..383c8c7f11311 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -623,6 +623,7 @@ int register_ftrace_graph(struct fgraph_ops *gops)
ret = start_graph_tracing();
if (ret) {
ftrace_graph_active--;
+ unregister_pm_notifier(&ftrace_suspend_notifier);
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0843/1887] vxlan: Fix NPD in {arp,neigh}_reduce() when using nexthop objects
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (841 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0842/1887] trace/fgraph: Fix the warning caused by missing unregister notifier Greg Kroah-Hartman
@ 2026-10-28 16:48 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0844/1887] vxlan: Fix NPD when refreshing an FDB entry with a nexthop object Greg Kroah-Hartman
` (155 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Petr Machata, Ido Schimmel,
Nikolay Aleksandrov, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 1f5d2fd1ca04a23c18b1bde9a43ce2fa2ffa1bce ]
When the "proxy" option is enabled on a VXLAN device, the device will
suppress ARP requests and IPv6 Neighbor Solicitation messages if it is
able to reply on behalf of the remote host. That is, if a matching and
valid neighbor entry is configured on the VXLAN device whose MAC address
is not behind the "any" remote (0.0.0.0 / ::).
The code currently assumes that the FDB entry for the neighbor's MAC
address points to a valid remote destination, but this is incorrect if
the entry is associated with an FDB nexthop group. This can result in a
NPD [1][3] which can be reproduced using [2][4].
Fix by checking that the remote destination exists before dereferencing
it.
[1]
BUG: kernel NULL pointer dereference, address: 0000000000000000
[...]
CPU: 4 UID: 0 PID: 365 Comm: arping Not tainted 6.17.0-rc2-virtme-g2a89cb21162c #2 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014
RIP: 0010:vxlan_xmit+0xb58/0x15f0
[...]
Call Trace:
<TASK>
dev_hard_start_xmit+0x5d/0x1c0
__dev_queue_xmit+0x246/0xfd0
packet_sendmsg+0x113a/0x1850
__sock_sendmsg+0x38/0x70
__sys_sendto+0x126/0x180
__x64_sys_sendto+0x24/0x30
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2]
#!/bin/bash
ip address add 192.0.2.1/32 dev lo
ip nexthop add id 1 via 192.0.2.2 fdb
ip nexthop add id 10 group 1 fdb
ip link add name vx0 up type vxlan id 10010 local 192.0.2.1 dstport 4789 proxy
ip neigh add 192.0.2.3 lladdr 00:11:22:33:44:55 nud perm dev vx0
bridge fdb add 00:11:22:33:44:55 dev vx0 self static nhid 10
arping -b -c 1 -s 192.0.2.1 -I vx0 192.0.2.3
[3]
BUG: kernel NULL pointer dereference, address: 0000000000000000
[...]
CPU: 13 UID: 0 PID: 372 Comm: ndisc6 Not tainted 6.17.0-rc2-virtmne-g6ee90cb26014 #3 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1v996), BIOS 1.17.0-4.fc41 04/01/2x014
RIP: 0010:vxlan_xmit+0x803/0x1600
[...]
Call Trace:
<TASK>
dev_hard_start_xmit+0x5d/0x1c0
__dev_queue_xmit+0x246/0xfd0
ip6_finish_output2+0x210/0x6c0
ip6_finish_output+0x1af/0x2b0
ip6_mr_output+0x92/0x3e0
ip6_send_skb+0x30/0x90
rawv6_sendmsg+0xe6e/0x12e0
__sock_sendmsg+0x38/0x70
__sys_sendto+0x126/0x180
__x64_sys_sendto+0x24/0x30
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x4b/0x53
RIP: 0033:0x7f383422ec77
[4]
#!/bin/bash
ip address add 2001:db8:1::1/128 dev lo
ip nexthop add id 1 via 2001:db8:1::1 fdb
ip nexthop add id 10 group 1 fdb
ip link add name vx0 up type vxlan id 10010 local 2001:db8:1::1 dstport 4789 proxy
ip neigh add 2001:db8:1::3 lladdr 00:11:22:33:44:55 nud perm dev vx0
bridge fdb add 00:11:22:33:44:55 dev vx0 self static nhid 10
ndisc6 -r 1 -s 2001:db8:1::1 -w 1 2001:db8:1::3 vx0
Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20250901065035.159644-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index c9f02da4c8af8..216f67d011f08 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -1943,6 +1943,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
n = neigh_lookup(&arp_tbl, &tip, dev);
if (n) {
+ struct vxlan_rdst *rdst = NULL;
struct vxlan_fdb *f;
struct sk_buff *reply;
@@ -1952,7 +1953,9 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
}
f = vxlan_find_mac(vxlan, n->ha, vni);
- if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
+ if (f)
+ rdst = first_remote_rcu(f);
+ if (rdst && vxlan_addr_any(&rdst->remote_ip)) {
/* bridge-local neighbor */
neigh_release(n);
goto out;
@@ -2111,6 +2114,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, dev);
if (n) {
+ struct vxlan_rdst *rdst = NULL;
struct vxlan_fdb *f;
struct sk_buff *reply;
@@ -2120,7 +2124,9 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
}
f = vxlan_find_mac(vxlan, n->ha, vni);
- if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
+ if (f)
+ rdst = first_remote_rcu(f);
+ if (rdst && vxlan_addr_any(&rdst->remote_ip)) {
/* bridge-local neighbor */
neigh_release(n);
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0844/1887] vxlan: Fix NPD when refreshing an FDB entry with a nexthop object
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (842 preceding siblings ...)
2026-10-28 16:48 ` [PATCH 6.1 0843/1887] vxlan: Fix NPD in {arp,neigh}_reduce() when using nexthop objects Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0845/1887] ptp: ocp: fix use-after-free bugs causing by ptp_ocp_watchdog Greg Kroah-Hartman
` (154 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marlin Cremers, Petr Machata,
Ido Schimmel, Nikolay Aleksandrov, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 6ead38147ebb813f08be6ea8ef547a0e4c09559a ]
VXLAN FDB entries can point to either a remote destination or an FDB
nexthop group. The latter is usually used in EVPN deployments where
learning is disabled.
However, when learning is enabled, an incoming packet might try to
refresh an FDB entry that points to an FDB nexthop group and therefore
does not have a remote. Such packets should be dropped, but they are
only dropped after dereferencing the non-existent remote, resulting in a
NPD [1] which can be reproduced using [2].
Fix by dropping such packets earlier. Remove the misleading comment from
first_remote_rcu().
[1]
BUG: kernel NULL pointer dereference, address: 0000000000000000
[...]
CPU: 13 UID: 0 PID: 361 Comm: mausezahn Not tainted 6.17.0-rc1-virtme-g9f6b606b6b37 #1 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014
RIP: 0010:vxlan_snoop+0x98/0x1e0
[...]
Call Trace:
<TASK>
vxlan_encap_bypass+0x209/0x240
encap_bypass_if_local+0xb1/0x100
vxlan_xmit_one+0x1375/0x17e0
vxlan_xmit+0x6b4/0x15f0
dev_hard_start_xmit+0x5d/0x1c0
__dev_queue_xmit+0x246/0xfd0
packet_sendmsg+0x113a/0x1850
__sock_sendmsg+0x38/0x70
__sys_sendto+0x126/0x180
__x64_sys_sendto+0x24/0x30
do_syscall_64+0xa4/0x260
entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2]
#!/bin/bash
ip address add 192.0.2.1/32 dev lo
ip address add 192.0.2.2/32 dev lo
ip nexthop add id 1 via 192.0.2.3 fdb
ip nexthop add id 10 group 1 fdb
ip link add name vx0 up type vxlan id 10010 local 192.0.2.1 dstport 12345 localbypass
ip link add name vx1 up type vxlan id 10020 local 192.0.2.2 dstport 54321 learning
bridge fdb add 00:11:22:33:44:55 dev vx0 self static dst 192.0.2.2 port 54321 vni 10020
bridge fdb add 00:aa:bb:cc:dd:ee dev vx1 self static nhid 10
mausezahn vx0 -a 00:aa:bb:cc:dd:ee -b 00:11:22:33:44:55 -c 1 -q
Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Reported-by: Marlin Cremers <mcremers@cloudbear.nl>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20250901065035.159644-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 8 ++++----
drivers/net/vxlan/vxlan_private.h | 4 +---
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 216f67d011f08..536c8384d635a 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -1522,6 +1522,10 @@ static bool vxlan_snoop(struct net_device *dev,
if (likely(f)) {
struct vxlan_rdst *rdst = first_remote_rcu(f);
+ /* Don't override an fdb with nexthop with a learnt entry */
+ if (rcu_access_pointer(f->nh))
+ return true;
+
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
rdst->remote_ifindex == ifindex))
return false;
@@ -1530,10 +1534,6 @@ static bool vxlan_snoop(struct net_device *dev,
if (f->state & (NUD_PERMANENT | NUD_NOARP))
return true;
- /* Don't override an fdb with nexthop with a learnt entry */
- if (rcu_access_pointer(f->nh))
- return true;
-
if (net_ratelimit())
netdev_info(dev,
"%pM migrated from %pIS to %pIS\n",
diff --git a/drivers/net/vxlan/vxlan_private.h b/drivers/net/vxlan/vxlan_private.h
index b0e8c6d290579..9e1cc18ca81ab 100644
--- a/drivers/net/vxlan/vxlan_private.h
+++ b/drivers/net/vxlan/vxlan_private.h
@@ -56,9 +56,7 @@ static inline struct hlist_head *vs_head(struct net *net, __be16 port)
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
}
-/* First remote destination for a forwarding entry.
- * Guaranteed to be non-NULL because remotes are never deleted.
- */
+/* First remote destination for a forwarding entry. */
static inline struct vxlan_rdst *first_remote_rcu(struct vxlan_fdb *fdb)
{
if (rcu_access_pointer(fdb->nh))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0845/1887] ptp: ocp: fix use-after-free bugs causing by ptp_ocp_watchdog
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (843 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0844/1887] vxlan: Fix NPD when refreshing an FDB entry with a nexthop object Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0846/1887] mm/vmalloc, mm/kasan: respect gfp mask in kasan_populate_vmalloc() Greg Kroah-Hartman
` (153 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Duoming Zhou, Vadim Fedorenko,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <duoming@zju.edu.cn>
[ Upstream commit 8bf935cf789872350b04c1a6468b0a509f67afb2 ]
The ptp_ocp_detach() only shuts down the watchdog timer if it is
pending. However, if the timer handler is already running, the
timer_delete_sync() is not called. This leads to race conditions
where the devlink that contains the ptp_ocp is deallocated while
the timer handler is still accessing it, resulting in use-after-free
bugs. The following details one of the race scenarios.
(thread 1) | (thread 2)
ptp_ocp_remove() |
ptp_ocp_detach() | ptp_ocp_watchdog()
if (timer_pending(&bp->watchdog))| bp = timer_container_of()
timer_delete_sync() |
|
devlink_free(devlink) //free |
| bp-> //use
Resolve this by unconditionally calling timer_delete_sync() to ensure
the timer is reliably deactivated, preventing any access after free.
Fixes: 773bda964921 ("ptp: ocp: Expose various resources on the timecard.")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20250828082949.28189-1-duoming@zju.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ptp/ptp_ocp.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index f2332b954bcf0..0661e1e2dca1f 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -3673,8 +3673,7 @@ ptp_ocp_detach(struct ptp_ocp *bp)
ptp_ocp_debugfs_remove_device(bp);
ptp_ocp_detach_sysfs(bp);
ptp_ocp_attr_group_del(bp);
- if (timer_pending(&bp->watchdog))
- del_timer_sync(&bp->watchdog);
+ del_timer_sync(&bp->watchdog);
if (bp->ts0)
ptp_ocp_unregister_ext(bp->ts0);
if (bp->ts1)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0846/1887] mm/vmalloc, mm/kasan: respect gfp mask in kasan_populate_vmalloc()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (844 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0845/1887] ptp: ocp: fix use-after-free bugs causing by ptp_ocp_watchdog Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0847/1887] smb: client: let smbd_destroy() call disable_work_sync(&info->post_send_credits_work) Greg Kroah-Hartman
` (152 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Uladzislau Rezki (Sony),
syzbot+3470c9ffee63e4abafeb, Andrey Ryabinin, Baoquan He,
Michal Hocko, Alexander Potapenko, Andrey Konovalov,
Dmitry Vyukov, Vincenzo Frascino, Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uladzislau Rezki (Sony) <urezki@gmail.com>
[ Upstream commit 79357cd06d41d0f5a11b17d7c86176e395d10ef2 ]
kasan_populate_vmalloc() and its helpers ignore the caller's gfp_mask and
always allocate memory using the hardcoded GFP_KERNEL flag. This makes
them inconsistent with vmalloc(), which was recently extended to support
GFP_NOFS and GFP_NOIO allocations.
Page table allocations performed during shadow population also ignore the
external gfp_mask. To preserve the intended semantics of GFP_NOFS and
GFP_NOIO, wrap the apply_to_page_range() calls into the appropriate
memalloc scope.
xfs calls vmalloc with GFP_NOFS, so this bug could lead to deadlock.
There was a report here
https://lkml.kernel.org/r/686ea951.050a0220.385921.0016.GAE@google.com
This patch:
- Extends kasan_populate_vmalloc() and helpers to take gfp_mask;
- Passes gfp_mask down to alloc_pages_bulk() and __get_free_page();
- Enforces GFP_NOFS/NOIO semantics with memalloc_*_save()/restore()
around apply_to_page_range();
- Updates vmalloc.c and percpu allocator call sites accordingly.
Link: https://lkml.kernel.org/r/20250831121058.92971-1-urezki@gmail.com
Fixes: 451769ebb7e7 ("mm/vmalloc: alloc GFP_NO{FS,IO} for vmalloc")
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Reported-by: syzbot+3470c9ffee63e4abafeb@syzkaller.appspotmail.com
Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/kasan.h | 6 +++---
mm/kasan/shadow.c | 31 ++++++++++++++++++++++++-------
mm/vmalloc.c | 4 ++--
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 5614d9da7a9e8..b290621c4ee34 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -387,7 +387,7 @@ static inline void kasan_init_hw_tags(void) { }
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
-int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
+int kasan_populate_vmalloc(unsigned long addr, unsigned long size, gfp_t gfp_mask);
void kasan_release_vmalloc(unsigned long start, unsigned long end,
unsigned long free_region_start,
unsigned long free_region_end);
@@ -398,7 +398,7 @@ static inline void kasan_populate_early_vm_area_shadow(void *start,
unsigned long size)
{ }
static inline int kasan_populate_vmalloc(unsigned long start,
- unsigned long size)
+ unsigned long size, gfp_t gfp_mask)
{
return 0;
}
@@ -443,7 +443,7 @@ kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms,
static inline void kasan_populate_early_vm_area_shadow(void *start,
unsigned long size) { }
static inline int kasan_populate_vmalloc(unsigned long start,
- unsigned long size)
+ unsigned long size, gfp_t gfp_mask)
{
return 0;
}
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 9dc041fd4f0f7..c651f3266e064 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -302,13 +302,13 @@ static void ___free_pages_bulk(struct page **pages, int nr_pages)
}
}
-static int ___alloc_pages_bulk(struct page **pages, int nr_pages)
+static int ___alloc_pages_bulk(struct page **pages, int nr_pages, gfp_t gfp_mask)
{
unsigned long nr_populated, nr_total = nr_pages;
struct page **page_array = pages;
while (nr_pages) {
- nr_populated = alloc_pages_bulk_array(GFP_KERNEL, nr_pages, pages);
+ nr_populated = alloc_pages_bulk_array(gfp_mask, nr_pages, pages);
if (!nr_populated) {
___free_pages_bulk(page_array, nr_total - nr_pages);
return -ENOMEM;
@@ -320,25 +320,42 @@ static int ___alloc_pages_bulk(struct page **pages, int nr_pages)
return 0;
}
-static int __kasan_populate_vmalloc(unsigned long start, unsigned long end)
+static int __kasan_populate_vmalloc(unsigned long start, unsigned long end, gfp_t gfp_mask)
{
unsigned long nr_pages, nr_total = PFN_UP(end - start);
struct vmalloc_populate_data data;
+ unsigned int flags;
int ret = 0;
- data.pages = (struct page **)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+ data.pages = (struct page **)__get_free_page(gfp_mask | __GFP_ZERO);
if (!data.pages)
return -ENOMEM;
while (nr_total) {
nr_pages = min(nr_total, PAGE_SIZE / sizeof(data.pages[0]));
- ret = ___alloc_pages_bulk(data.pages, nr_pages);
+ ret = ___alloc_pages_bulk(data.pages, nr_pages, gfp_mask);
if (ret)
break;
data.start = start;
+
+ /*
+ * page tables allocations ignore external gfp mask, enforce it
+ * by the scope API
+ */
+ if ((gfp_mask & (__GFP_FS | __GFP_IO)) == __GFP_IO)
+ flags = memalloc_nofs_save();
+ else if ((gfp_mask & (__GFP_FS | __GFP_IO)) == 0)
+ flags = memalloc_noio_save();
+
ret = apply_to_page_range(&init_mm, start, nr_pages * PAGE_SIZE,
kasan_populate_vmalloc_pte, &data);
+
+ if ((gfp_mask & (__GFP_FS | __GFP_IO)) == __GFP_IO)
+ memalloc_nofs_restore(flags);
+ else if ((gfp_mask & (__GFP_FS | __GFP_IO)) == 0)
+ memalloc_noio_restore(flags);
+
___free_pages_bulk(data.pages, nr_pages);
if (ret)
break;
@@ -352,7 +369,7 @@ static int __kasan_populate_vmalloc(unsigned long start, unsigned long end)
return ret;
}
-int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
+int kasan_populate_vmalloc(unsigned long addr, unsigned long size, gfp_t gfp_mask)
{
unsigned long shadow_start, shadow_end;
int ret;
@@ -381,7 +398,7 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
shadow_start = PAGE_ALIGN_DOWN(shadow_start);
shadow_end = PAGE_ALIGN(shadow_end);
- ret = __kasan_populate_vmalloc(shadow_start, shadow_end);
+ ret = __kasan_populate_vmalloc(shadow_start, shadow_end, gfp_mask);
if (ret)
return ret;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 6c8a9b748db17..32d172fa3e6cf 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1708,7 +1708,7 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
BUG_ON(va->va_start < vstart);
BUG_ON(va->va_end > vend);
- ret = kasan_populate_vmalloc(addr, size);
+ ret = kasan_populate_vmalloc(addr, size, gfp_mask);
if (ret) {
free_vmap_area(va);
return ERR_PTR(ret);
@@ -3997,7 +3997,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
/* populate the kasan shadow space */
for (area = 0; area < nr_vms; area++) {
- if (kasan_populate_vmalloc(vas[area]->va_start, sizes[area]))
+ if (kasan_populate_vmalloc(vas[area]->va_start, sizes[area], GFP_KERNEL))
goto err_free_shadow;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0847/1887] smb: client: let smbd_destroy() call disable_work_sync(&info->post_send_credits_work)
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (845 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0846/1887] mm/vmalloc, mm/kasan: respect gfp mask in kasan_populate_vmalloc() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0848/1887] smb: client: let recv_done verify data_offset, data_length and remaining_data_length Greg Kroah-Hartman
` (151 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Steve French, Tom Talpey, Long Li,
Namjae Jeon, linux-cifs, samba-technical, Stefan Metzmacher,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <metze@samba.org>
[ Upstream commit d9dcbbcf9145b68aa85c40947311a6907277e097 ]
In smbd_destroy() we may destroy the memory so we better
wait until post_send_credits_work is no longer pending
and will never be started again.
I actually just hit the case using rxe:
WARNING: CPU: 0 PID: 138 at drivers/infiniband/sw/rxe/rxe_verbs.c:1032 rxe_post_recv+0x1ee/0x480 [rdma_rxe]
...
[ 5305.686979] [ T138] smbd_post_recv+0x445/0xc10 [cifs]
[ 5305.687135] [ T138] ? srso_alias_return_thunk+0x5/0xfbef5
[ 5305.687149] [ T138] ? __kasan_check_write+0x14/0x30
[ 5305.687185] [ T138] ? __pfx_smbd_post_recv+0x10/0x10 [cifs]
[ 5305.687329] [ T138] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 5305.687356] [ T138] ? srso_alias_return_thunk+0x5/0xfbef5
[ 5305.687368] [ T138] ? srso_alias_return_thunk+0x5/0xfbef5
[ 5305.687378] [ T138] ? _raw_spin_unlock_irqrestore+0x11/0x60
[ 5305.687389] [ T138] ? srso_alias_return_thunk+0x5/0xfbef5
[ 5305.687399] [ T138] ? get_receive_buffer+0x168/0x210 [cifs]
[ 5305.687555] [ T138] smbd_post_send_credits+0x382/0x4b0 [cifs]
[ 5305.687701] [ T138] ? __pfx_smbd_post_send_credits+0x10/0x10 [cifs]
[ 5305.687855] [ T138] ? __pfx___schedule+0x10/0x10
[ 5305.687865] [ T138] ? __pfx__raw_spin_lock_irq+0x10/0x10
[ 5305.687875] [ T138] ? queue_delayed_work_on+0x8e/0xa0
[ 5305.687889] [ T138] process_one_work+0x629/0xf80
[ 5305.687908] [ T138] ? srso_alias_return_thunk+0x5/0xfbef5
[ 5305.687917] [ T138] ? __kasan_check_write+0x14/0x30
[ 5305.687933] [ T138] worker_thread+0x87f/0x1570
...
It means rxe_post_recv was called after rdma_destroy_qp().
This happened because put_receive_buffer() was triggered
by ib_drain_qp() and called:
queue_work(info->workqueue, &info->post_send_credits_work);
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Fixes: f198186aa9bb ("CIFS: SMBD: Establish SMB Direct connection")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smbdirect.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index 9b16840952c09..d2878973c1476 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -1358,6 +1358,9 @@ void smbd_destroy(struct TCP_Server_Info *server)
info->transport_status == SMBD_DISCONNECTED);
}
+ log_rdma_event(INFO, "cancelling post_send_credits_work\n");
+ cancel_work_sync(&info->post_send_credits_work);
+
log_rdma_event(INFO, "destroying qp\n");
ib_drain_qp(info->id->qp);
rdma_destroy_qp(info->id);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0848/1887] smb: client: let recv_done verify data_offset, data_length and remaining_data_length
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (846 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0847/1887] smb: client: let smbd_destroy() call disable_work_sync(&info->post_send_credits_work) Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0849/1887] wifi: wilc1000: avoid buffer overflow in WID string configuration Greg Kroah-Hartman
` (150 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Talpey, Long Li, linux-cifs,
samba-technical, Namjae Jeon, Stefan Metzmacher, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <metze@samba.org>
[ Upstream commit f57e53ea252363234f86674db475839e5b87102e ]
This is inspired by the related server fixes.
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Fixes: f198186aa9bb ("CIFS: SMBD: Establish SMB Direct connection")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smbdirect.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index d2878973c1476..894f5ffca909f 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -461,7 +461,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
struct smbd_response *response =
container_of(wc->wr_cqe, struct smbd_response, cqe);
struct smbd_connection *info = response->info;
- int data_length = 0;
+ u32 data_offset = 0;
+ u32 data_length = 0;
+ u32 remaining_data_length = 0;
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
response, response->type, wc->status, wc->opcode,
@@ -493,7 +495,22 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
/* SMBD data transfer packet */
case SMBD_TRANSFER_DATA:
data_transfer = smbd_response_payload(response);
+
+ if (wc->byte_len <
+ offsetof(struct smbd_data_transfer, padding))
+ goto error;
+
+ remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length);
+ data_offset = le32_to_cpu(data_transfer->data_offset);
data_length = le32_to_cpu(data_transfer->data_length);
+ if (wc->byte_len < data_offset ||
+ (u64)wc->byte_len < (u64)data_offset + data_length)
+ goto error;
+
+ if (remaining_data_length > info->max_fragmented_recv_size ||
+ data_length > info->max_fragmented_recv_size ||
+ (u64)remaining_data_length + (u64)data_length > (u64)info->max_fragmented_recv_size)
+ goto error;
/*
* If this is a packet with data playload place the data in
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0849/1887] wifi: wilc1000: avoid buffer overflow in WID string configuration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (847 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0848/1887] smb: client: let recv_done verify data_offset, data_length and remaining_data_length Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0850/1887] Bluetooth: MGMT: Fix possible UAFs Greg Kroah-Hartman
` (149 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Ajay Singh,
Johannes Berg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ajay.Kathat@microchip.com <Ajay.Kathat@microchip.com>
[ Upstream commit fe9e4d0c39311d0f97b024147a0d155333f388b5 ]
Fix the following copy overflow warning identified by Smatch checker.
drivers/net/wireless/microchip/wilc1000/wlan_cfg.c:184 wilc_wlan_parse_response_frame()
error: '__memcpy()' 'cfg->s[i]->str' copy overflow (512 vs 65537)
This patch introduces size check before accessing the memory buffer.
The checks are base on the WID type of received data from the firmware.
For WID string configuration, the size limit is determined by individual
element size in 'struct wilc_cfg_str_vals' that is maintained in 'len' field
of 'struct wilc_cfg_str'.
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/linux-wireless/aLFbr9Yu9j_TQTey@stanley.mountain
Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Link: https://patch.msgid.link/20250829225829.5423-1-ajay.kathat@microchip.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../wireless/microchip/wilc1000/wlan_cfg.c | 37 ++++++++++++++-----
.../wireless/microchip/wilc1000/wlan_cfg.h | 5 ++-
2 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
index 131388886acbf..cfabd5aebb540 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
@@ -41,10 +41,10 @@ static const struct wilc_cfg_word g_cfg_word[] = {
};
static const struct wilc_cfg_str g_cfg_str[] = {
- {WID_FIRMWARE_VERSION, NULL},
- {WID_MAC_ADDR, NULL},
- {WID_ASSOC_RES_INFO, NULL},
- {WID_NIL, NULL}
+ {WID_FIRMWARE_VERSION, 0, NULL},
+ {WID_MAC_ADDR, 0, NULL},
+ {WID_ASSOC_RES_INFO, 0, NULL},
+ {WID_NIL, 0, NULL}
};
#define WILC_RESP_MSG_TYPE_CONFIG_REPLY 'R'
@@ -147,44 +147,58 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
switch (FIELD_GET(WILC_WID_TYPE, wid)) {
case WID_CHAR:
+ len = 3;
+ if (len + 2 > size)
+ return;
+
while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
i++;
if (cfg->b[i].id == wid)
cfg->b[i].val = info[4];
- len = 3;
break;
case WID_SHORT:
+ len = 4;
+ if (len + 2 > size)
+ return;
+
while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
i++;
if (cfg->hw[i].id == wid)
cfg->hw[i].val = get_unaligned_le16(&info[4]);
- len = 4;
break;
case WID_INT:
+ len = 6;
+ if (len + 2 > size)
+ return;
+
while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
i++;
if (cfg->w[i].id == wid)
cfg->w[i].val = get_unaligned_le32(&info[4]);
- len = 6;
break;
case WID_STR:
+ len = 2 + get_unaligned_le16(&info[2]);
+
while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
i++;
- if (cfg->s[i].id == wid)
+ if (cfg->s[i].id == wid) {
+ if (len > cfg->s[i].len || (len + 2 > size))
+ return;
+
memcpy(cfg->s[i].str, &info[2],
- get_unaligned_le16(&info[2]) + 2);
+ len);
+ }
- len = 2 + get_unaligned_le16(&info[2]);
break;
default:
@@ -384,12 +398,15 @@ int wilc_wlan_cfg_init(struct wilc *wl)
/* store the string cfg parameters */
wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
wl->cfg.s[i].str = str_vals->firmware_version;
+ wl->cfg.s[i].len = sizeof(str_vals->firmware_version);
i++;
wl->cfg.s[i].id = WID_MAC_ADDR;
wl->cfg.s[i].str = str_vals->mac_address;
+ wl->cfg.s[i].len = sizeof(str_vals->mac_address);
i++;
wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
wl->cfg.s[i].str = str_vals->assoc_rsp;
+ wl->cfg.s[i].len = sizeof(str_vals->assoc_rsp);
i++;
wl->cfg.s[i].id = WID_NIL;
wl->cfg.s[i].str = NULL;
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
index 614c5673f2328..b0987682892aa 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
@@ -24,12 +24,13 @@ struct wilc_cfg_word {
struct wilc_cfg_str {
u16 id;
+ u16 len;
u8 *str;
};
struct wilc_cfg_str_vals {
- u8 mac_address[7];
- u8 firmware_version[129];
+ u8 mac_address[8];
+ u8 firmware_version[130];
u8 assoc_rsp[256];
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0850/1887] Bluetooth: MGMT: Fix possible UAFs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (848 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0849/1887] wifi: wilc1000: avoid buffer overflow in WID string configuration Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0851/1887] x86/mce: use is_copy_from_user() to determine copy-from-user context Greg Kroah-Hartman
` (148 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, cen zhang, Luiz Augusto von Dentz,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit 302a1f674c00dd5581ab8e493ef44767c5101aab ]
This attemps to fix possible UAFs caused by struct mgmt_pending being
freed while still being processed like in the following trace, in order
to fix mgmt_pending_valid is introduce and use to check if the
mgmt_pending hasn't been removed from the pending list, on the complete
callbacks it is used to check and in addtion remove the cmd from the list
while holding mgmt_pending_lock to avoid TOCTOU problems since if the cmd
is left on the list it can still be accessed and freed.
BUG: KASAN: slab-use-after-free in mgmt_add_adv_patterns_monitor_sync+0x35/0x50 net/bluetooth/mgmt.c:5223
Read of size 8 at addr ffff8880709d4dc0 by task kworker/u11:0/55
CPU: 0 UID: 0 PID: 55 Comm: kworker/u11:0 Not tainted 6.16.4 #2 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xca/0x240 mm/kasan/report.c:482
kasan_report+0x118/0x150 mm/kasan/report.c:595
mgmt_add_adv_patterns_monitor_sync+0x35/0x50 net/bluetooth/mgmt.c:5223
hci_cmd_sync_work+0x210/0x3a0 net/bluetooth/hci_sync.c:332
process_one_work kernel/workqueue.c:3238 [inline]
process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3321
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3402
kthread+0x711/0x8a0 kernel/kthread.c:464
ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148
ret_from_fork_asm+0x1a/0x30 home/kwqcheii/source/fuzzing/kernel/kasan/linux-6.16.4/arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 12210:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:260 [inline]
__kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4364
kmalloc_noprof include/linux/slab.h:905 [inline]
kzalloc_noprof include/linux/slab.h:1039 [inline]
mgmt_pending_new+0x65/0x1e0 net/bluetooth/mgmt_util.c:269
mgmt_pending_add+0x35/0x140 net/bluetooth/mgmt_util.c:296
__add_adv_patterns_monitor+0x130/0x200 net/bluetooth/mgmt.c:5247
add_adv_patterns_monitor+0x214/0x360 net/bluetooth/mgmt.c:5364
hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719
hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839
sock_sendmsg_nosec net/socket.c:714 [inline]
__sock_sendmsg+0x219/0x270 net/socket.c:729
sock_write_iter+0x258/0x330 net/socket.c:1133
new_sync_write fs/read_write.c:593 [inline]
vfs_write+0x5c9/0xb30 fs/read_write.c:686
ksys_write+0x145/0x250 fs/read_write.c:738
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 12221:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x62/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:233 [inline]
slab_free_hook mm/slub.c:2381 [inline]
slab_free mm/slub.c:4648 [inline]
kfree+0x18e/0x440 mm/slub.c:4847
mgmt_pending_free net/bluetooth/mgmt_util.c:311 [inline]
mgmt_pending_foreach+0x30d/0x380 net/bluetooth/mgmt_util.c:257
__mgmt_power_off+0x169/0x350 net/bluetooth/mgmt.c:9444
hci_dev_close_sync+0x754/0x1330 net/bluetooth/hci_sync.c:5290
hci_dev_do_close net/bluetooth/hci_core.c:501 [inline]
hci_dev_close+0x108/0x200 net/bluetooth/hci_core.c:526
sock_do_ioctl+0xd9/0x300 net/socket.c:1192
sock_ioctl+0x576/0x790 net/socket.c:1313
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fixes: cf75ad8b41d2 ("Bluetooth: hci_sync: Convert MGMT_SET_POWERED")
Fixes: 2bd1b237616b ("Bluetooth: hci_sync: Convert MGMT_OP_SET_DISCOVERABLE to use cmd_sync")
Fixes: f056a65783cc ("Bluetooth: hci_sync: Convert MGMT_OP_SET_CONNECTABLE to use cmd_sync")
Fixes: 3244845c6307 ("Bluetooth: hci_sync: Convert MGMT_OP_SSP")
Fixes: d81a494c43df ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LE")
Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
Fixes: 71efbb08b538 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_PHY_CONFIGURATION")
Fixes: b747a83690c8 ("Bluetooth: hci_sync: Refactor add Adv Monitor")
Fixes: abfeea476c68 ("Bluetooth: hci_sync: Convert MGMT_OP_START_DISCOVERY")
Fixes: 26ac4c56f03f ("Bluetooth: hci_sync: Convert MGMT_OP_SET_ADVERTISING")
Reported-by: cen zhang <zzzccc427@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/mgmt.c | 260 ++++++++++++++++++++++++++------------
net/bluetooth/mgmt_util.c | 46 +++++++
net/bluetooth/mgmt_util.h | 3 +
3 files changed, 231 insertions(+), 78 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b09a8aaf03623..e1c045d1c7887 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1311,8 +1311,7 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
struct mgmt_mode *cp;
/* Make sure cmd still outstanding. */
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
cp = cmd->param;
@@ -1339,23 +1338,29 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
mgmt_status(err));
}
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
}
static int set_powered_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_mode *cp;
+ struct mgmt_mode cp;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
/* Make sure cmd still outstanding. */
- if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
return -ECANCELED;
+ }
- cp = cmd->param;
+ memcpy(&cp, cmd->param, sizeof(cp));
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
BT_DBG("%s", hdev->name);
- return hci_set_powered_sync(hdev, cp->val);
+ return hci_set_powered_sync(hdev, cp.val);
}
static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -1496,8 +1501,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "err %d", err);
/* Make sure cmd still outstanding. */
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
hci_dev_lock(hdev);
@@ -1519,12 +1523,15 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
new_settings(hdev, cmd->sk);
done:
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
hci_dev_unlock(hdev);
}
static int set_discoverable_sync(struct hci_dev *hdev, void *data)
{
+ if (!mgmt_pending_listed(hdev, data))
+ return -ECANCELED;
+
BT_DBG("%s", hdev->name);
return hci_update_discoverable_sync(hdev);
@@ -1671,8 +1678,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "err %d", err);
/* Make sure cmd still outstanding. */
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
hci_dev_lock(hdev);
@@ -1687,8 +1693,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
new_settings(hdev, cmd->sk);
done:
- if (cmd)
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
hci_dev_unlock(hdev);
}
@@ -1724,6 +1729,9 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
static int set_connectable_sync(struct hci_dev *hdev, void *data)
{
+ if (!mgmt_pending_listed(hdev, data))
+ return -ECANCELED;
+
BT_DBG("%s", hdev->name);
return hci_update_connectable_sync(hdev);
@@ -1900,14 +1908,17 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
{
struct cmd_lookup match = { NULL, hdev };
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_mode *cp = cmd->param;
- u8 enable = cp->val;
+ struct mgmt_mode *cp;
+ u8 enable;
bool changed;
/* Make sure cmd still outstanding. */
- if (err == -ECANCELED || cmd != pending_find(MGMT_OP_SET_SSP, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
+ cp = cmd->param;
+ enable = cp->val;
+
if (err) {
u8 mgmt_err = mgmt_status(err);
@@ -1916,8 +1927,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
new_settings(hdev, NULL);
}
- mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true,
- cmd_status_rsp, &mgmt_err);
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
return;
}
@@ -1927,7 +1937,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
}
- mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match);
+ settings_rsp(cmd, &match);
if (changed)
new_settings(hdev, match.sk);
@@ -1941,14 +1951,25 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
static int set_ssp_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_mode *cp = cmd->param;
+ struct mgmt_mode cp;
bool changed = false;
int err;
- if (cp->val)
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ memcpy(&cp, cmd->param, sizeof(cp));
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ if (cp.val)
changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);
- err = hci_write_ssp_mode_sync(hdev, cp->val);
+ err = hci_write_ssp_mode_sync(hdev, cp.val);
if (!err && changed)
hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
@@ -2041,32 +2062,50 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
static void set_le_complete(struct hci_dev *hdev, void *data, int err)
{
+ struct mgmt_pending_cmd *cmd = data;
struct cmd_lookup match = { NULL, hdev };
u8 status = mgmt_status(err);
bt_dev_dbg(hdev, "err %d", err);
- if (status) {
- mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp,
- &status);
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
return;
+
+ if (status) {
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, status);
+ goto done;
}
- mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match);
+ settings_rsp(cmd, &match);
new_settings(hdev, match.sk);
if (match.sk)
sock_put(match.sk);
+
+done:
+ mgmt_pending_free(cmd);
}
static int set_le_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_mode *cp = cmd->param;
- u8 val = !!cp->val;
+ struct mgmt_mode cp;
+ u8 val;
int err;
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ memcpy(&cp, cmd->param, sizeof(cp));
+ val = !!cp.val;
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
if (!val) {
hci_clear_adv_instance_sync(hdev, NULL, 0x00, true);
@@ -2108,7 +2147,12 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
{
struct mgmt_pending_cmd *cmd = data;
u8 status = mgmt_status(err);
- struct sock *sk = cmd->sk;
+ struct sock *sk;
+
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
+ return;
+
+ sk = cmd->sk;
if (status) {
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
@@ -2123,24 +2167,37 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
static int set_mesh_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_cp_set_mesh *cp = cmd->param;
- size_t len = cmd->param_len;
+ struct mgmt_cp_set_mesh cp;
+ size_t len;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ memcpy(&cp, cmd->param, sizeof(cp));
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ len = cmd->param_len;
memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types));
- if (cp->enable)
+ if (cp.enable)
hci_dev_set_flag(hdev, HCI_MESH);
else
hci_dev_clear_flag(hdev, HCI_MESH);
- hdev->le_scan_interval = __le16_to_cpu(cp->period);
- hdev->le_scan_window = __le16_to_cpu(cp->window);
+ hdev->le_scan_interval = __le16_to_cpu(cp.period);
+ hdev->le_scan_window = __le16_to_cpu(cp.window);
- len -= sizeof(*cp);
+ len -= sizeof(cp);
/* If filters don't fit, forward all adv pkts */
if (len <= sizeof(hdev->mesh_ad_types))
- memcpy(hdev->mesh_ad_types, cp->ad_types, len);
+ memcpy(hdev->mesh_ad_types, cp.ad_types, len);
hci_update_passive_scan_sync(hdev);
return 0;
@@ -3876,15 +3933,16 @@ static int name_changed_sync(struct hci_dev *hdev, void *data)
static void set_name_complete(struct hci_dev *hdev, void *data, int err)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_cp_set_local_name *cp = cmd->param;
+ struct mgmt_cp_set_local_name *cp;
u8 status = mgmt_status(err);
bt_dev_dbg(hdev, "err %d", err);
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
+ cp = cmd->param;
+
if (status) {
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
status);
@@ -3896,16 +3954,27 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
hci_cmd_sync_queue(hdev, name_changed_sync, NULL, NULL);
}
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
}
static int set_name_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_cp_set_local_name *cp = cmd->param;
+ struct mgmt_cp_set_local_name cp;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ memcpy(&cp, cmd->param, sizeof(cp));
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
if (lmp_bredr_capable(hdev)) {
- hci_update_name_sync(hdev, cp->name);
+ hci_update_name_sync(hdev, cp.name);
hci_update_eir_sync(hdev);
}
@@ -4063,12 +4132,10 @@ int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip)
static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
{
struct mgmt_pending_cmd *cmd = data;
- struct sk_buff *skb = cmd->skb;
+ struct sk_buff *skb;
u8 status = mgmt_status(err);
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
- return;
+ skb = cmd->skb;
if (!status) {
if (!skb)
@@ -4095,7 +4162,7 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
if (skb && !IS_ERR(skb))
kfree_skb(skb);
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
}
static int set_default_phy_sync(struct hci_dev *hdev, void *data)
@@ -4103,7 +4170,9 @@ static int set_default_phy_sync(struct hci_dev *hdev, void *data)
struct mgmt_pending_cmd *cmd = data;
struct mgmt_cp_set_phy_configuration *cp = cmd->param;
struct hci_cp_le_set_default_phy cp_phy;
- u32 selected_phys = __le32_to_cpu(cp->selected_phys);
+ u32 selected_phys;
+
+ selected_phys = __le32_to_cpu(cp->selected_phys);
memset(&cp_phy, 0, sizeof(cp_phy));
@@ -4243,7 +4312,7 @@ static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_PHY_CONFIGURATION, hdev, data,
+ cmd = mgmt_pending_new(sk, MGMT_OP_SET_PHY_CONFIGURATION, hdev, data,
len);
if (!cmd)
err = -ENOMEM;
@@ -5333,7 +5402,17 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
{
struct mgmt_rp_add_adv_patterns_monitor rp;
struct mgmt_pending_cmd *cmd = data;
- struct adv_monitor *monitor = cmd->user_data;
+ struct adv_monitor *monitor;
+
+ /* This is likely the result of hdev being closed and mgmt_index_removed
+ * is attempting to clean up any pending command so
+ * hci_adv_monitors_clear is about to be called which will take care of
+ * freeing the adv_monitor instances.
+ */
+ if (status == -ECANCELED && !mgmt_pending_valid(hdev, cmd))
+ return;
+
+ monitor = cmd->user_data;
hci_dev_lock(hdev);
@@ -5361,9 +5440,20 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
static int mgmt_add_adv_patterns_monitor_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct adv_monitor *monitor = cmd->user_data;
+ struct adv_monitor *mon;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
- return hci_add_adv_monitor(hdev, monitor);
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ mon = cmd->user_data;
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ return hci_add_adv_monitor(hdev, mon);
}
static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
@@ -5630,7 +5720,8 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
status);
}
-static void read_local_oob_data_complete(struct hci_dev *hdev, void *data, int err)
+static void read_local_oob_data_complete(struct hci_dev *hdev, void *data,
+ int err)
{
struct mgmt_rp_read_local_oob_data mgmt_rp;
size_t rp_size = sizeof(mgmt_rp);
@@ -5650,7 +5741,8 @@ static void read_local_oob_data_complete(struct hci_dev *hdev, void *data, int e
bt_dev_dbg(hdev, "status %d", status);
if (status) {
- mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, status);
+ mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
+ status);
goto remove;
}
@@ -5955,17 +6047,12 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
- if (err == -ECANCELED)
- return;
-
- if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
- cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
- cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
cmd->param, 1);
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
DISCOVERY_FINDING);
@@ -5973,6 +6060,9 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
static int start_discovery_sync(struct hci_dev *hdev, void *data)
{
+ if (!mgmt_pending_listed(hdev, data))
+ return -ECANCELED;
+
return hci_start_discovery_sync(hdev);
}
@@ -6199,15 +6289,14 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
{
struct mgmt_pending_cmd *cmd = data;
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
return;
bt_dev_dbg(hdev, "err %d", err);
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
cmd->param, 1);
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
if (!err)
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
@@ -6215,6 +6304,9 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
static int stop_discovery_sync(struct hci_dev *hdev, void *data)
{
+ if (!mgmt_pending_listed(hdev, data))
+ return -ECANCELED;
+
return hci_stop_discovery_sync(hdev);
}
@@ -6424,14 +6516,18 @@ static void enable_advertising_instance(struct hci_dev *hdev, int err)
static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
{
+ struct mgmt_pending_cmd *cmd = data;
struct cmd_lookup match = { NULL, hdev };
u8 instance;
struct adv_info *adv_instance;
u8 status = mgmt_status(err);
+ if (err == -ECANCELED || !mgmt_pending_valid(hdev, data))
+ return;
+
if (status) {
- mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true,
- cmd_status_rsp, &status);
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, status);
+ mgmt_pending_free(cmd);
return;
}
@@ -6440,8 +6536,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
else
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
- mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp,
- &match);
+ settings_rsp(cmd, &match);
new_settings(hdev, match.sk);
@@ -6473,10 +6568,23 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
static int set_adv_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
- struct mgmt_mode *cp = cmd->param;
- u8 val = !!cp->val;
+ struct mgmt_mode cp;
+ u8 val;
- if (cp->val == 0x02)
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ if (!__mgmt_pending_listed(hdev, cmd)) {
+ mutex_unlock(&hdev->mgmt_pending_lock);
+ return -ECANCELED;
+ }
+
+ memcpy(&cp, cmd->param, sizeof(cp));
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ val = !!cp.val;
+
+ if (cp.val == 0x02)
hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
else
hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
@@ -8168,10 +8276,6 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
u8 status = mgmt_status(err);
u16 eir_len;
- if (err == -ECANCELED ||
- cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
- return;
-
if (!status) {
if (!skb)
status = MGMT_STATUS_FAILED;
@@ -8278,7 +8382,7 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
kfree_skb(skb);
kfree(mgmt_rp);
- mgmt_pending_remove(cmd);
+ mgmt_pending_free(cmd);
}
static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
@@ -8287,7 +8391,7 @@ static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
struct mgmt_pending_cmd *cmd;
int err;
- cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
+ cmd = mgmt_pending_new(sk, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev,
cp, sizeof(*cp));
if (!cmd)
return -ENOMEM;
diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c
index 4ba500c377a4c..e612121b96d0c 100644
--- a/net/bluetooth/mgmt_util.c
+++ b/net/bluetooth/mgmt_util.c
@@ -320,6 +320,52 @@ void mgmt_pending_remove(struct mgmt_pending_cmd *cmd)
mgmt_pending_free(cmd);
}
+bool __mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
+{
+ struct mgmt_pending_cmd *tmp;
+
+ lockdep_assert_held(&hdev->mgmt_pending_lock);
+
+ if (!cmd)
+ return false;
+
+ list_for_each_entry(tmp, &hdev->mgmt_pending, list) {
+ if (cmd == tmp)
+ return true;
+ }
+
+ return false;
+}
+
+bool mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
+{
+ bool listed;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
+ listed = __mgmt_pending_listed(hdev, cmd);
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ return listed;
+}
+
+bool mgmt_pending_valid(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd)
+{
+ bool listed;
+
+ if (!cmd)
+ return false;
+
+ mutex_lock(&hdev->mgmt_pending_lock);
+
+ listed = __mgmt_pending_listed(hdev, cmd);
+ if (listed)
+ list_del(&cmd->list);
+
+ mutex_unlock(&hdev->mgmt_pending_lock);
+
+ return listed;
+}
+
void mgmt_mesh_foreach(struct hci_dev *hdev,
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
void *data, struct sock *sk)
diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h
index 024e51dd69375..bcba8c9d89528 100644
--- a/net/bluetooth/mgmt_util.h
+++ b/net/bluetooth/mgmt_util.h
@@ -65,6 +65,9 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
void *data, u16 len);
void mgmt_pending_free(struct mgmt_pending_cmd *cmd);
void mgmt_pending_remove(struct mgmt_pending_cmd *cmd);
+bool __mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
+bool mgmt_pending_listed(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
+bool mgmt_pending_valid(struct hci_dev *hdev, struct mgmt_pending_cmd *cmd);
void mgmt_mesh_foreach(struct hci_dev *hdev,
void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data),
void *data, struct sock *sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0851/1887] x86/mce: use is_copy_from_user() to determine copy-from-user context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (849 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0850/1887] Bluetooth: MGMT: Fix possible UAFs Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0852/1887] net: mscc: ocelot: Fix use-after-free caused by cyclic delayed work Greg Kroah-Hartman
` (147 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shuai Xue, Peter Zijlstra,
Borislav Petkov (AMD), Tony Luck, Baolin Wang, Catalin Marinas,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Josh Poimboeuf,
Miaohe Lin, Naoya Horiguchi, Ruidong Tian, Thomas Gleinxer,
Yazen Ghannam, Jane Chu, Jarkko Sakkinen, Jonathan Cameron,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuai Xue <xueshuai@linux.alibaba.com>
[ Upstream commit 1a15bb8303b6b104e78028b6c68f76a0d4562134 ]
Patch series "mm/hwpoison: Fix regressions in memory failure handling",
v4.
## 1. What am I trying to do:
This patchset resolves two critical regressions related to memory failure
handling that have appeared in the upstream kernel since version 5.17, as
compared to 5.10 LTS.
- copyin case: poison found in user page while kernel copying from user space
- instr case: poison found while instruction fetching in user space
## 2. What is the expected outcome and why
- For copyin case:
Kernel can recover from poison found where kernel is doing get_user() or
copy_from_user() if those places get an error return and the kernel return
-EFAULT to the process instead of crashing. More specifily, MCE handler
checks the fixup handler type to decide whether an in kernel #MC can be
recovered. When EX_TYPE_UACCESS is found, the PC jumps to recovery code
specified in _ASM_EXTABLE_FAULT() and return a -EFAULT to user space.
- For instr case:
If a poison found while instruction fetching in user space, full recovery
is possible. User process takes #PF, Linux allocates a new page and fills
by reading from storage.
## 3. What actually happens and why
- For copyin case: kernel panic since v5.17
Commit 4c132d1d844a ("x86/futex: Remove .fixup usage") introduced a new
extable fixup type, EX_TYPE_EFAULT_REG, and later patches updated the
extable fixup type for copy-from-user operations, changing it from
EX_TYPE_UACCESS to EX_TYPE_EFAULT_REG. It breaks previous EX_TYPE_UACCESS
handling when posion found in get_user() or copy_from_user().
- For instr case: user process is killed by a SIGBUS signal due to #CMCI
and #MCE race
When an uncorrected memory error is consumed there is a race between the
CMCI from the memory controller reporting an uncorrected error with a UCNA
signature, and the core reporting and SRAR signature machine check when
the data is about to be consumed.
### Background: why *UN*corrected errors tied to *C*MCI in Intel platform [1]
Prior to Icelake memory controllers reported patrol scrub events that
detected a previously unseen uncorrected error in memory by signaling a
broadcast machine check with an SRAO (Software Recoverable Action
Optional) signature in the machine check bank. This was overkill because
it's not an urgent problem that no core is on the verge of consuming that
bad data. It's also found that multi SRAO UCE may cause nested MCE
interrupts and finally become an IERR.
Hence, Intel downgrades the machine check bank signature of patrol scrub
from SRAO to UCNA (Uncorrected, No Action required), and signal changed to
#CMCI. Just to add to the confusion, Linux does take an action (in
uc_decode_notifier()) to try to offline the page despite the UC*NA*
signature name.
### Background: why #CMCI and #MCE race when poison is consuming in
Intel platform [1]
Having decided that CMCI/UCNA is the best action for patrol scrub errors,
the memory controller uses it for reads too. But the memory controller is
executing asynchronously from the core, and can't tell the difference
between a "real" read and a speculative read. So it will do CMCI/UCNA if
an error is found in any read.
Thus:
1) Core is clever and thinks address A is needed soon, issues a
speculative read.
2) Core finds it is going to use address A soon after sending the read
request
3) The CMCI from the memory controller is in a race with MCE from the
core that will soon try to retire the load from address A.
Quite often (because speculation has got better) the CMCI from the memory
controller is delivered before the core is committed to the instruction
reading address A, so the interrupt is taken, and Linux offlines the page
(marking it as poison).
## Why user process is killed for instr case
Commit 046545a661af ("mm/hwpoison: fix error page recovered but reported
"not recovered"") tries to fix noise message "Memory error not recovered"
and skips duplicate SIGBUSs due to the race. But it also introduced a bug
that kill_accessing_process() return -EHWPOISON for instr case, as result,
kill_me_maybe() send a SIGBUS to user process.
# 4. The fix, in my opinion, should be:
- For copyin case:
The key point is whether the error context is in a read from user memory.
We do not care about the ex-type if we know its a MOV reading from
userspace.
is_copy_from_user() return true when both of the following two checks are
true:
- the current instruction is copy
- source address is user memory
If copy_user is true, we set
m->kflags |= MCE_IN_KERNEL_COPYIN | MCE_IN_KERNEL_RECOV;
Then do_machine_check() will try fixup_exception() first.
- For instr case: let kill_accessing_process() return 0 to prevent a SIGBUS.
- For patch 3:
The return value of memory_failure() is quite important while discussed
instr case regression with Tony and Miaohe for patch 2, so add comment
about the return value.
This patch (of 3):
Commit 4c132d1d844a ("x86/futex: Remove .fixup usage") introduced a new
extable fixup type, EX_TYPE_EFAULT_REG, and commit 4c132d1d844a
("x86/futex: Remove .fixup usage") updated the extable fixup type for
copy-from-user operations, changing it from EX_TYPE_UACCESS to
EX_TYPE_EFAULT_REG. The error context for copy-from-user operations no
longer functions as an in-kernel recovery context. Consequently, the
error context for copy-from-user operations no longer functions as an
in-kernel recovery context, resulting in kernel panics with the message:
"Machine check: Data load in unrecoverable area of kernel."
To address this, it is crucial to identify if an error context involves a
read operation from user memory. The function is_copy_from_user() can be
utilized to determine:
- the current operation is copy
- when reading user memory
When these conditions are met, is_copy_from_user() will return true,
confirming that it is indeed a direct copy from user memory. This check
is essential for correctly handling the context of errors in these
operations without relying on the extable fixup types that previously
allowed for in-kernel recovery.
So, use is_copy_from_user() to determine if a context is copy user directly.
Link: https://lkml.kernel.org/r/20250312112852.82415-1-xueshuai@linux.alibaba.com
Link: https://lkml.kernel.org/r/20250312112852.82415-2-xueshuai@linux.alibaba.com
Fixes: 4c132d1d844a ("x86/futex: Remove .fixup usage")
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
Tested-by: Tony Luck <tony.luck@intel.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Borislav Betkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Ruidong Tian <tianruidong@linux.alibaba.com>
Cc: Thomas Gleinxer <tglx@linutronix.de>
Cc: Yazen Ghannam <yazen.ghannam@amd.com>
Cc: Jane Chu <jane.chu@oracle.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/cpu/mce/severity.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
index 00483d1c27e4f..7793dfd300525 100644
--- a/arch/x86/kernel/cpu/mce/severity.c
+++ b/arch/x86/kernel/cpu/mce/severity.c
@@ -283,14 +283,12 @@ static noinstr int error_context(struct mce *m, struct pt_regs *regs)
copy_user = is_copy_from_user(regs);
instrumentation_end();
- switch (fixup_type) {
- case EX_TYPE_UACCESS:
- case EX_TYPE_COPY:
- if (!copy_user)
- return IN_KERNEL;
- m->kflags |= MCE_IN_KERNEL_COPYIN;
- fallthrough;
+ if (copy_user) {
+ m->kflags |= MCE_IN_KERNEL_COPYIN | MCE_IN_KERNEL_RECOV;
+ return IN_KERNEL_RECOV;
+ }
+ switch (fixup_type) {
case EX_TYPE_FAULT_MCE_SAFE:
case EX_TYPE_DEFAULT_MCE_SAFE:
m->kflags |= MCE_IN_KERNEL_RECOV;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0852/1887] net: mscc: ocelot: Fix use-after-free caused by cyclic delayed work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (850 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0851/1887] x86/mce: use is_copy_from_user() to determine copy-from-user context Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0853/1887] i915: Move list_count() to list.h as list_count_nodes() for broader use Greg Kroah-Hartman
` (146 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Duoming Zhou, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <duoming@zju.edu.cn>
[ Upstream commit bc9ea787079671cb19a8b25ff9f02be5ef6bfcf5 ]
The origin code calls cancel_delayed_work() in ocelot_stats_deinit()
to cancel the cyclic delayed work item ocelot->stats_work. However,
cancel_delayed_work() may fail to cancel the work item if it is already
executing. While destroy_workqueue() does wait for all pending work items
in the work queue to complete before destroying the work queue, it cannot
prevent the delayed work item from being rescheduled within the
ocelot_check_stats_work() function. This limitation exists because the
delayed work item is only enqueued into the work queue after its timer
expires. Before the timer expiration, destroy_workqueue() has no visibility
of this pending work item. Once the work queue appears empty,
destroy_workqueue() proceeds with destruction. When the timer eventually
expires, the delayed work item gets queued again, leading to the following
warning:
workqueue: cannot queue ocelot_check_stats_work on wq ocelot-switch-stats
WARNING: CPU: 2 PID: 0 at kernel/workqueue.c:2255 __queue_work+0x875/0xaf0
...
RIP: 0010:__queue_work+0x875/0xaf0
...
RSP: 0018:ffff88806d108b10 EFLAGS: 00010086
RAX: 0000000000000000 RBX: 0000000000000101 RCX: 0000000000000027
RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffff88806d123e88
RBP: ffffffff813c3170 R08: 0000000000000000 R09: ffffed100da247d2
R10: ffffed100da247d1 R11: ffff88806d123e8b R12: ffff88800c00f000
R13: ffff88800d7285c0 R14: ffff88806d0a5580 R15: ffff88800d7285a0
FS: 0000000000000000(0000) GS:ffff8880e5725000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fe18e45ea10 CR3: 0000000005e6c000 CR4: 00000000000006f0
Call Trace:
<IRQ>
? kasan_report+0xc6/0xf0
? __pfx_delayed_work_timer_fn+0x10/0x10
? __pfx_delayed_work_timer_fn+0x10/0x10
call_timer_fn+0x25/0x1c0
__run_timer_base.part.0+0x3be/0x8c0
? __pfx_delayed_work_timer_fn+0x10/0x10
? rcu_sched_clock_irq+0xb06/0x27d0
? __pfx___run_timer_base.part.0+0x10/0x10
? try_to_wake_up+0xb15/0x1960
? _raw_spin_lock_irq+0x80/0xe0
? __pfx__raw_spin_lock_irq+0x10/0x10
tmigr_handle_remote_up+0x603/0x7e0
? __pfx_tmigr_handle_remote_up+0x10/0x10
? sched_balance_trigger+0x1c0/0x9f0
? sched_tick+0x221/0x5a0
? _raw_spin_lock_irq+0x80/0xe0
? __pfx__raw_spin_lock_irq+0x10/0x10
? tick_nohz_handler+0x339/0x440
? __pfx_tmigr_handle_remote_up+0x10/0x10
__walk_groups.isra.0+0x42/0x150
tmigr_handle_remote+0x1f4/0x2e0
? __pfx_tmigr_handle_remote+0x10/0x10
? ktime_get+0x60/0x140
? lapic_next_event+0x11/0x20
? clockevents_program_event+0x1d4/0x2a0
? hrtimer_interrupt+0x322/0x780
handle_softirqs+0x16a/0x550
irq_exit_rcu+0xaf/0xe0
sysvec_apic_timer_interrupt+0x70/0x80
</IRQ>
...
The following diagram reveals the cause of the above warning:
CPU 0 (remove) | CPU 1 (delayed work callback)
mscc_ocelot_remove() |
ocelot_deinit() | ocelot_check_stats_work()
ocelot_stats_deinit() |
cancel_delayed_work()| ...
| queue_delayed_work()
destroy_workqueue() | (wait a time)
| __queue_work() //UAF
The above scenario actually constitutes a UAF vulnerability.
The ocelot_stats_deinit() is only invoked when initialization
failure or resource destruction, so we must ensure that any
delayed work items cannot be rescheduled.
Replace cancel_delayed_work() with disable_delayed_work_sync()
to guarantee proper cancellation of the delayed work item and
ensure completion of any currently executing work before the
workqueue is deallocated.
A deadlock concern was considered: ocelot_stats_deinit() is called
in a process context and is not holding any locks that the delayed
work item might also need. Therefore, the use of the _sync() variant
is safe here.
This bug was identified through static analysis. To reproduce the
issue and validate the fix, I simulated ocelot-switch device by
writing a kernel module and prepared the necessary resources for
the virtual ocelot-switch device's probe process. Then, removing
the virtual device will trigger the mscc_ocelot_remove() function,
which in turn destroys the workqueue.
Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/20251001011149.55073-1-duoming@zju.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mscc/ocelot_stats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mscc/ocelot_stats.c b/drivers/net/ethernet/mscc/ocelot_stats.c
index 6b95262dad904..30b978eaf4036 100644
--- a/drivers/net/ethernet/mscc/ocelot_stats.c
+++ b/drivers/net/ethernet/mscc/ocelot_stats.c
@@ -454,6 +454,6 @@ int ocelot_stats_init(struct ocelot *ocelot)
void ocelot_stats_deinit(struct ocelot *ocelot)
{
- cancel_delayed_work(&ocelot->stats_work);
+ cancel_delayed_work_sync(&ocelot->stats_work);
destroy_workqueue(ocelot->stats_queue);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0853/1887] i915: Move list_count() to list.h as list_count_nodes() for broader use
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (851 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0852/1887] net: mscc: ocelot: Fix use-after-free caused by cyclic delayed work Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0854/1887] ptp: Add a upper bound on max_vclocks Greg Kroah-Hartman
` (145 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas De Marchi, Jani Nikula,
Andy Shevchenko, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 4d70c74659d9746502b23d055dba03d1d28ec388 ]
Some of the existing users, and definitely will be new ones, want to
count existing nodes in the list. Provide a generic API for that by
moving code from i915 to list.h.
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20221130134838.23805-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
In this tree the i915 list_count() helper and its only user live in
intel_execlists_submission.c rather than intel_engine_cs.c, so the
i915 conversion is applied there instead.
Stable-dep-of: e9f35294e18d ("ptp: Add a upper bound on max_vclocks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/i915/gt/intel_execlists_submission.c | 15 ++-------------
include/linux/list.h | 15 +++++++++++++++
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 321dbecba0f3c..1a396eb13c2e4 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -4153,17 +4153,6 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine,
spin_unlock_irqrestore(&sched_engine->lock, flags);
}
-static unsigned long list_count(struct list_head *list)
-{
- struct list_head *pos;
- unsigned long count = 0;
-
- list_for_each(pos, list)
- count++;
-
- return count;
-}
-
void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
struct i915_request *hung_rq,
struct drm_printer *m)
@@ -4174,8 +4163,8 @@ void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m);
- drm_printf(m, "\tOn hold?: %lu\n",
- list_count(&engine->sched_engine->hold));
+ drm_printf(m, "\tOn hold?: %zu\n",
+ list_count_nodes(&engine->sched_engine->hold));
spin_unlock_irqrestore(&engine->sched_engine->lock, flags);
}
diff --git a/include/linux/list.h b/include/linux/list.h
index a2f9a62c577a4..38e8ed08d598c 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -662,6 +662,21 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_is_head(pos, (head)); \
pos = n, n = pos->prev)
+/**
+ * list_count_nodes - count nodes in the list
+ * @head: the head for your list.
+ */
+static inline size_t list_count_nodes(struct list_head *head)
+{
+ struct list_head *pos;
+ size_t count = 0;
+
+ list_for_each(pos, head)
+ count++;
+
+ return count;
+}
+
/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0854/1887] ptp: Add a upper bound on max_vclocks
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (852 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0853/1887] i915: Move list_count() to list.h as list_count_nodes() for broader use Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0855/1887] RISC-V: KVM: Write hgatp register with valid mode bits Greg Kroah-Hartman
` (144 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+94d20db923b9f51be0df,
I Viswanath, Richard Cochran, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: I Viswanath <viswanathiyyappan@gmail.com>
[ Upstream commit e9f35294e18da82162004a2f35976e7031aaf7f9 ]
syzbot reported WARNING in max_vclocks_store.
This occurs when the argument max is too large for kcalloc to handle.
Extend the guard to guard against values that are too large for
kcalloc
Reported-by: syzbot+94d20db923b9f51be0df@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=94d20db923b9f51be0df
Tested-by: syzbot+94d20db923b9f51be0df@syzkaller.appspotmail.com
Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion")
Signed-off-by: I Viswanath <viswanathiyyappan@gmail.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Link: https://patch.msgid.link/20250925155908.5034-1-viswanathiyyappan@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ptp/ptp_private.h | 1 +
drivers/ptp/ptp_sysfs.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/ptp/ptp_private.h
+++ b/drivers/ptp/ptp_private.h
@@ -19,6 +19,7 @@
#define PTP_MAX_TIMESTAMPS 128
#define PTP_BUF_TIMESTAMPS 30
#define PTP_DEFAULT_MAX_VCLOCKS 20
+#define PTP_MAX_VCLOCKS_LIMIT (KMALLOC_MAX_SIZE/(sizeof(int)))
struct timestamp_event_queue {
struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS];
--- a/drivers/ptp/ptp_sysfs.c
+++ b/drivers/ptp/ptp_sysfs.c
@@ -271,7 +271,7 @@ static ssize_t max_vclocks_store(struct
size_t size;
u32 max;
- if (kstrtou32(buf, 0, &max) || max == 0)
+ if (kstrtou32(buf, 0, &max) || max == 0 || max > PTP_MAX_VCLOCKS_LIMIT)
return -EINVAL;
if (max == ptp->max_vclocks)
^ permalink raw reply [flat|nested] 1899+ messages in thread* [PATCH 6.1 0855/1887] RISC-V: KVM: Write hgatp register with valid mode bits
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (853 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0854/1887] ptp: Add a upper bound on max_vclocks Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0856/1887] tty: n_gsm: introduce macro for minimal unit size Greg Kroah-Hartman
` (143 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nutty Liu, Troy Mitchell,
Guo Ren (Alibaba DAMO Academy), Fangyu Yu, Anup Patel,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
[ Upstream commit 2b351e3d04be9e1533f26c3464f1e44a5beace30 ]
According to the RISC-V Privileged Architecture Spec, when MODE=Bare
is selected,software must write zero to the remaining fields of hgatp.
We have detected the valid mode supported by the HW before, So using a
valid mode to detect how many vmid bits are supported.
Fixes: fd7bb4a251df ("RISC-V: KVM: Implement VMID allocator")
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
Reviewed-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
Link: https://lore.kernel.org/r/20250821142542.2472079-2-guoren@kernel.org
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/kvm/vmid.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/kvm/vmid.c b/arch/riscv/kvm/vmid.c
index 6cd93995fb65e..dc5d318fe91cd 100644
--- a/arch/riscv/kvm/vmid.c
+++ b/arch/riscv/kvm/vmid.c
@@ -26,7 +26,7 @@ void kvm_riscv_gstage_vmid_detect(void)
/* Figure-out number of VMID bits in HW */
old = csr_read(CSR_HGATP);
- csr_write(CSR_HGATP, old | HGATP_VMID_MASK);
+ csr_write(CSR_HGATP, (kvm_riscv_gstage_mode() << HGATP_MODE_SHIFT) | HGATP_VMID_MASK);
vmid_bits = csr_read(CSR_HGATP);
vmid_bits = (vmid_bits & HGATP_VMID_MASK) >> HGATP_VMID_SHIFT;
vmid_bits = fls_long(vmid_bits);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0856/1887] tty: n_gsm: introduce macro for minimal unit size
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (854 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0855/1887] RISC-V: KVM: Write hgatp register with valid mode bits Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0857/1887] tty: n_gsm: add parameters used with parameter negotiation Greg Kroah-Hartman
` (142 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Daniel Starke, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Starke <daniel.starke@siemens.com>
[ Upstream commit 7a1212475f5e313c11300272f34ffa32462bbeef ]
n_gsm has a minimal protocol overhead of 7 bytes. The current code already
checks whether the configured MRU/MTU size is at least one byte more than
this.
Introduce the macro MIN_MTU to make this value more obvious.
Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
Link: https://lore.kernel.org/r/20221103091743.2119-1-daniel.starke@siemens.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 3cf0b3c243e5 ("tty: n_gsm: Don't block input queue by waiting MSC")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/n_gsm.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index fc52a7a38df32..165a70ab1f004 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -89,6 +89,7 @@ module_param(debug, int, 0600);
*/
#define MAX_MRU 1500
#define MAX_MTU 1500
+#define MIN_MTU (PROT_OVERHEAD + 1)
/* SOF, ADDR, CTRL, LEN1, LEN2, ..., FCS, EOF */
#define PROT_OVERHEAD 7
#define GSM_NET_TX_TIMEOUT (HZ*10)
@@ -2771,7 +2772,9 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
if ((c->adaption != 1 && c->adaption != 2) || c->k)
return -EOPNOTSUPP;
/* Check the MRU/MTU range looks sane */
- if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
+ if (c->mru < MIN_MTU || c->mtu < MIN_MTU)
+ return -EINVAL;
+ if (c->mru > MAX_MRU || c->mtu > MAX_MTU)
return -EINVAL;
if (c->n2 > 255)
return -EINVAL;
@@ -3360,7 +3363,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
return -ENOMEM;
}
net->mtu = dlci->gsm->mtu;
- net->min_mtu = 8;
+ net->min_mtu = MIN_MTU;
net->max_mtu = dlci->gsm->mtu;
mux_net = netdev_priv(net);
mux_net->dlci = dlci;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0857/1887] tty: n_gsm: add parameters used with parameter negotiation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (855 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0856/1887] tty: n_gsm: introduce macro for minimal unit size Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0858/1887] tty: n_gsm: Dont block input queue by waiting MSC Greg Kroah-Hartman
` (141 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Daniel Starke, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Starke <daniel.starke@siemens.com>
[ Upstream commit 2ec7a802a04c545ceea96bf67ee818d8bb0349e2 ]
n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
the newer 27.010 here. Chapter 5.4.6.3.1 describes the encoding of the
parameter negotiation messages.
Add the parameters used there to 'gsm_mux' and 'gsm_dlci' and initialize both
according to the value ranges and recommended defaults defined in chapter 5.7.
Replace the use of the DLC default values from the 'gsm_mux' fields with the DLC
specific values from the 'gsm_dlci' fields where applicable.
Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
Link: https://lore.kernel.org/r/20221103091743.2119-2-daniel.starke@siemens.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 3cf0b3c243e5 ("tty: n_gsm: Don't block input queue by waiting MSC")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/n_gsm.c | 58 +++++++++++++++++++++++++++++++++++----------
1 file changed, 45 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 165a70ab1f004..374d013eada6e 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -40,6 +40,7 @@
#include <linux/tty.h>
#include <linux/ctype.h>
#include <linux/mm.h>
+#include <linux/math.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/poll.h>
@@ -75,7 +76,12 @@ module_param(debug, int, 0600);
#define T1 10 /* 100mS */
#define T2 34 /* 333mS */
+#define T3 10 /* 10s */
#define N2 3 /* Retry 3 times */
+#define K 2 /* outstanding I frames */
+
+#define MAX_T3 255 /* In seconds. */
+#define MAX_WINDOW_SIZE 7 /* Limit of K in error recovery mode. */
/* Use long timers for testing at low speed with debug on */
#ifdef DEBUG_TIMING
@@ -160,7 +166,12 @@ struct gsm_dlci {
int prev_adaption;
u32 modem_rx; /* Our incoming virtual modem lines */
u32 modem_tx; /* Our outgoing modem lines */
+ unsigned int mtu;
bool dead; /* Refuse re-open */
+ /* Configuration */
+ u8 prio; /* Priority */
+ u8 ftype; /* Frame type */
+ u8 k; /* Window size */
/* Flow control */
bool throttled; /* Private copy of throttle state */
bool constipated; /* Throttle status for outgoing */
@@ -285,7 +296,9 @@ struct gsm_mux {
int adaption; /* 1 or 2 supported */
u8 ftype; /* UI or UIH */
int t1, t2; /* Timers in 1/100th of a sec */
+ unsigned int t3; /* Power wake-up timer in seconds. */
int n2; /* Retry count */
+ u8 k; /* Window size */
/* Statistics (not currently exposed) */
unsigned long bad_fcs;
@@ -1079,12 +1092,12 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
return 0;
/* MTU/MRU count only the data bits but watch adaption mode */
- if ((len + h) > gsm->mtu)
- len = gsm->mtu - h;
+ if ((len + h) > dlci->mtu)
+ len = dlci->mtu - h;
size = len + h;
- msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+ msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype);
if (!msg)
return -ENOMEM;
dp = msg->data;
@@ -1148,19 +1161,19 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
len = dlci->skb->len + overhead;
/* MTU/MRU count only the data bits */
- if (len > gsm->mtu) {
+ if (len > dlci->mtu) {
if (dlci->adaption == 3) {
/* Over long frame, bin it */
dev_kfree_skb_any(dlci->skb);
dlci->skb = NULL;
return 0;
}
- len = gsm->mtu;
+ len = dlci->mtu;
} else
last = 1;
size = len + overhead;
- msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+ msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype);
if (msg == NULL) {
skb_queue_tail(&dlci->skb_list, dlci->skb);
dlci->skb = NULL;
@@ -1217,7 +1230,7 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
return -EINVAL;
}
- msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+ msg = gsm_data_alloc(gsm, dlci->addr, size, dlci->ftype);
if (!msg) {
pr_err("%s: gsm_data_alloc error", __func__);
return -ENOMEM;
@@ -1343,8 +1356,9 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
static int gsm_control_command(struct gsm_mux *gsm, int cmd, const u8 *data,
int dlen)
{
- struct gsm_msg *msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
+ struct gsm_msg *msg;
+ msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype);
if (msg == NULL)
return -ENOMEM;
@@ -1370,7 +1384,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data,
int dlen)
{
struct gsm_msg *msg;
- msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
+
+ msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype);
if (msg == NULL)
return;
msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */
@@ -2081,6 +2096,13 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
dlci->gsm = gsm;
dlci->addr = addr;
dlci->adaption = gsm->adaption;
+ dlci->mtu = gsm->mtu;
+ if (addr == 0)
+ dlci->prio = 0;
+ else
+ dlci->prio = roundup(addr + 1, 8) - 1;
+ dlci->ftype = gsm->ftype;
+ dlci->k = gsm->k;
dlci->state = DLCI_CLOSED;
if (addr) {
dlci->data = gsm_dlci_data;
@@ -2710,7 +2732,9 @@ static struct gsm_mux *gsm_alloc_mux(void)
gsm->t1 = T1;
gsm->t2 = T2;
+ gsm->t3 = T3;
gsm->n2 = N2;
+ gsm->k = K;
gsm->ftype = UIH;
gsm->adaption = 1;
gsm->encoding = GSM_ADV_OPT;
@@ -2750,7 +2774,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,
c->initiator = gsm->initiator;
c->t1 = gsm->t1;
c->t2 = gsm->t2;
- c->t3 = 0; /* Not supported */
+ c->t3 = gsm->t3;
c->n2 = gsm->n2;
if (gsm->ftype == UIH)
c->i = 1;
@@ -2759,7 +2783,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,
pr_debug("Ftype %d i %d\n", gsm->ftype, c->i);
c->mru = gsm->mru;
c->mtu = gsm->mtu;
- c->k = 0;
+ c->k = gsm->k;
}
static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
@@ -2776,12 +2800,16 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
return -EINVAL;
if (c->mru > MAX_MRU || c->mtu > MAX_MTU)
return -EINVAL;
+ if (c->t3 > MAX_T3)
+ return -EINVAL;
if (c->n2 > 255)
return -EINVAL;
if (c->encapsulation > 1) /* Basic, advanced, no I */
return -EINVAL;
if (c->initiator > 1)
return -EINVAL;
+ if (c->k > MAX_WINDOW_SIZE)
+ return -EINVAL;
if (c->i == 0 || c->i > 2) /* UIH and UI only */
return -EINVAL;
/*
@@ -2829,6 +2857,10 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
gsm->t1 = c->t1;
if (c->t2)
gsm->t2 = c->t2;
+ if (c->t3)
+ gsm->t3 = c->t3;
+ if (c->k)
+ gsm->k = c->k;
/*
* FIXME: We need to separate activation/deactivation from adding
@@ -3362,9 +3394,9 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
pr_err("alloc_netdev failed\n");
return -ENOMEM;
}
- net->mtu = dlci->gsm->mtu;
+ net->mtu = dlci->mtu;
net->min_mtu = MIN_MTU;
- net->max_mtu = dlci->gsm->mtu;
+ net->max_mtu = dlci->mtu;
mux_net = netdev_priv(net);
mux_net->dlci = dlci;
kref_init(&mux_net->ref);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0858/1887] tty: n_gsm: Dont block input queue by waiting MSC
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (856 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0857/1887] tty: n_gsm: add parameters used with parameter negotiation Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0859/1887] tcp_metrics: use dst_dev_net_rcu() Greg Kroah-Hartman
` (140 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Seppo Takalo, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seppo Takalo <seppo.takalo@nordicsemi.no>
[ Upstream commit 3cf0b3c243e56bc43be560617416c1d9f301f44c ]
Currently gsm_queue() processes incoming frames and when opening
a DLC channel it calls gsm_dlci_open() which calls gsm_modem_update().
If basic mode is used it calls gsm_modem_upd_via_msc() and it
cannot block the input queue by waiting the response to come
into the same input queue.
Instead allow sending Modem Status Command without waiting for remote
end to respond. Define a new function gsm_modem_send_initial_msc()
for this purpose. As MSC is only valid for basic encoding, it does
not do anything for advanced or when convergence layer type 2 is used.
Fixes: 48473802506d ("tty: n_gsm: fix missing update of modem controls after DLCI open")
Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
Link: https://lore.kernel.org/r/20250827123221.1148666-1-seppo.takalo@nordicsemi.no
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/n_gsm.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 374d013eada6e..db9382b573000 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -420,6 +420,7 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
static void gsmld_write_trigger(struct gsm_mux *gsm);
static void gsmld_write_task(struct work_struct *work);
+static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci);
/**
* gsm_fcs_add - update FCS
@@ -1834,7 +1835,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
pr_debug("DLCI %d goes open.\n", dlci->addr);
/* Send current modem state */
if (dlci->addr)
- gsm_modem_update(dlci, 0);
+ gsm_modem_send_initial_msc(dlci);
gsm_dlci_data_kick(dlci);
wake_up(&dlci->gsm->event);
}
@@ -3490,6 +3491,28 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
return gsm_control_wait(dlci->gsm, ctrl);
}
+/**
+ * gsm_modem_send_initial_msc - Send initial modem status message
+ *
+ * @dlci channel
+ *
+ * Send an initial MSC message after DLCI open to set the initial
+ * modem status lines. This is only done for basic mode.
+ * Does not wait for a response as we cannot block the input queue
+ * processing.
+ */
+static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci)
+{
+ u8 modembits[2];
+
+ if (dlci->adaption != 1 || dlci->gsm->encoding != GSM_BASIC_OPT)
+ return 0;
+
+ modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */
+ modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
+ return gsm_control_command(dlci->gsm, CMD_MSC, (const u8 *)&modembits, 2);
+}
+
/**
* gsm_modem_update - send modem status line state
* @dlci: channel
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0859/1887] tcp_metrics: use dst_dev_net_rcu()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (857 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0858/1887] tty: n_gsm: Dont block input queue by waiting MSC Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0860/1887] f2fs: Use a folio in f2fs_truncate_partial_cluster() Greg Kroah-Hartman
` (139 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, David Ahern,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 50c127a69cd6285300931853b352a1918cfa180f ]
Replace three dst_dev() with a lockdep enabled helper.
Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-7-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/tcp_metrics.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 8bf1118e04c66..d3559a9cb2330 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -170,7 +170,7 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
struct net *net;
spin_lock_bh(&tcp_metrics_lock);
- net = dev_net(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
/* While waiting for the spin-lock the cache might have been populated
* with this entry and so we have to check again.
@@ -273,7 +273,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
return NULL;
}
- net = dev_net(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
hash ^= net_hash_mix(net);
hash = hash_32(hash, tcp_metrics_hash_log);
@@ -318,7 +318,7 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk,
else
return NULL;
- net = dev_net(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
hash ^= net_hash_mix(net);
hash = hash_32(hash, tcp_metrics_hash_log);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0860/1887] f2fs: Use a folio in f2fs_truncate_partial_cluster()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (858 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0859/1887] tcp_metrics: use dst_dev_net_rcu() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0861/1887] f2fs: fix to avoid overflow while left shift operation Greg Kroah-Hartman
` (138 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Wilcox (Oracle), Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit 1cda5bc0b2fe93cdcb5f05a02f814a282d32742c ]
Convert the incoming page to a folio and use it throughout.
Removes an access to page->index.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: 0fe1c6bec54e ("f2fs: fix to avoid overflow while left shift operation")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/compress.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index de64a621c729b..b882891fbf28d 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1215,13 +1215,14 @@ int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock)
int i;
for (i = cluster_size - 1; i >= 0; i--) {
- loff_t start = rpages[i]->index << PAGE_SHIFT;
+ struct folio *folio = page_folio(rpages[i]);
+ loff_t start = folio->index << PAGE_SHIFT;
if (from <= start) {
- zero_user_segment(rpages[i], 0, PAGE_SIZE);
+ folio_zero_segment(folio, 0, folio_size(folio));
} else {
- zero_user_segment(rpages[i], from - start,
- PAGE_SIZE);
+ folio_zero_segment(folio, from - start,
+ folio_size(folio));
break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0861/1887] f2fs: fix to avoid overflow while left shift operation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (859 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0860/1887] f2fs: Use a folio in f2fs_truncate_partial_cluster() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0862/1887] crypto: hisilicon/qm - request reserved interrupt for virtual function Greg Kroah-Hartman
` (137 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 0fe1c6bec54ea68ed8c987b3890f2296364e77bb ]
Should cast type of folio->index from pgoff_t to loff_t to avoid overflow
while left shift operation.
Fixes: 3265d3db1f16 ("f2fs: support partial truncation on compressed inode")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/compress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index b882891fbf28d..37a684c682c7b 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1216,7 +1216,7 @@ int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock)
for (i = cluster_size - 1; i >= 0; i--) {
struct folio *folio = page_folio(rpages[i]);
- loff_t start = folio->index << PAGE_SHIFT;
+ loff_t start = (loff_t)folio->index << PAGE_SHIFT;
if (from <= start) {
folio_zero_segment(folio, 0, folio_size(folio));
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0862/1887] crypto: hisilicon/qm - request reserved interrupt for virtual function
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (860 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0861/1887] f2fs: fix to avoid overflow while left shift operation Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0863/1887] f2fs: fix to truncate first page in error path of f2fs_truncate() Greg Kroah-Hartman
` (136 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Weili Qian, Chenghai Huang,
Herbert Xu, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weili Qian <qianweili@huawei.com>
[ Upstream commit 9228facb308157ac0bdd264b873187896f7a9c7a ]
The device interrupt vector 3 is an error interrupt for
physical function and a reserved interrupt for virtual function.
However, the driver has not registered the reserved interrupt for
virtual function. When allocating interrupts, the number of interrupts
is allocated based on powers of two, which includes this interrupt.
When the system enables GICv4 and the virtual function passthrough
to the virtual machine, releasing the interrupt in the driver
triggers a warning.
The WARNING report is:
WARNING: CPU: 62 PID: 14889 at arch/arm64/kvm/vgic/vgic-its.c:852 its_free_ite+0x94/0xb4
Therefore, register a reserved interrupt for VF and set the
IRQF_NO_AUTOEN flag to avoid that warning.
Fixes: 3536cc55cada ("crypto: hisilicon/qm - support get device irq information from hardware registers")
Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/crypto/hisilicon/qm.c | 38 +++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 9ebd7b3d97be7..216d8ea775e9d 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -4557,6 +4557,15 @@ void hisi_qm_reset_done(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(hisi_qm_reset_done);
+static irqreturn_t qm_rsvd_irq(int irq, void *data)
+{
+ struct hisi_qm *qm = data;
+
+ dev_info(&qm->pdev->dev, "Reserved interrupt, ignore!\n");
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t qm_abnormal_irq(int irq, void *data)
{
struct hisi_qm *qm = data;
@@ -4856,7 +4865,7 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm)
struct pci_dev *pdev = qm->pdev;
u32 irq_vector, val;
- if (qm->fun_type == QM_HW_VF)
+ if (qm->fun_type == QM_HW_VF && qm->ver < QM_HW_V3)
return;
val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val;
@@ -4873,17 +4882,28 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm)
u32 irq_vector, val;
int ret;
- if (qm->fun_type == QM_HW_VF)
- return 0;
-
val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val;
if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK))
return 0;
-
irq_vector = val & QM_IRQ_VECTOR_MASK;
+
+ /* For VF, this is a reserved interrupt in V3 version. */
+ if (qm->fun_type == QM_HW_VF) {
+ if (qm->ver < QM_HW_V3)
+ return 0;
+
+ ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_rsvd_irq,
+ IRQF_NO_AUTOEN, qm->dev_name, qm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request reserved irq, ret = %d!\n", ret);
+ return ret;
+ }
+ return 0;
+ }
+
ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_abnormal_irq, 0, qm->dev_name, qm);
if (ret)
- dev_err(&qm->pdev->dev, "failed to request abnormal irq, ret = %d", ret);
+ dev_err(&qm->pdev->dev, "failed to request abnormal irq, ret = %d!\n", ret);
return ret;
}
@@ -5222,6 +5242,12 @@ static int hisi_qm_pci_init(struct hisi_qm *qm)
pci_set_master(pdev);
num_vec = qm_get_irq_num(qm);
+ if (!num_vec) {
+ dev_err(dev, "Device irq num is zero!\n");
+ ret = -EINVAL;
+ goto err_get_pci_res;
+ }
+ num_vec = roundup_pow_of_two(num_vec);
ret = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSI);
if (ret < 0) {
dev_err(dev, "Failed to enable MSI vectors!\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0863/1887] f2fs: fix to truncate first page in error path of f2fs_truncate()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (861 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0862/1887] crypto: hisilicon/qm - request reserved interrupt for virtual function Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0864/1887] ipv6: use RCU in ip6_output() Greg Kroah-Hartman
` (135 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+90266696fe5daacebd35, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 9251a9e6e871cb03c4714a18efa8f5d4a8818450 ]
syzbot reports a bug as below:
loop0: detected capacity change from 0 to 40427
F2FS-fs (loop0): Wrong SSA boundary, start(3584) end(4096) blocks(3072)
F2FS-fs (loop0): Can't find valid F2FS filesystem in 1th superblock
F2FS-fs (loop0): invalid crc value
F2FS-fs (loop0): f2fs_convert_inline_folio: corrupted inline inode ino=3, i_addr[0]:0x1601, run fsck to fix.
------------[ cut here ]------------
kernel BUG at fs/inode.c:753!
RIP: 0010:clear_inode+0x169/0x190 fs/inode.c:753
Call Trace:
<TASK>
evict+0x504/0x9c0 fs/inode.c:810
f2fs_fill_super+0x5612/0x6fa0 fs/f2fs/super.c:5047
get_tree_bdev_flags+0x40e/0x4d0 fs/super.c:1692
vfs_get_tree+0x8f/0x2b0 fs/super.c:1815
do_new_mount+0x2a2/0x9e0 fs/namespace.c:3808
do_mount fs/namespace.c:4136 [inline]
__do_sys_mount fs/namespace.c:4347 [inline]
__se_sys_mount+0x317/0x410 fs/namespace.c:4324
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
During f2fs_evict_inode(), clear_inode() detects that we missed to truncate
all page cache before destorying inode, that is because in below path, we
will create page #0 in cache, but missed to drop it in error path, let's fix
it.
- evict
- f2fs_evict_inode
- f2fs_truncate
- f2fs_convert_inline_inode
- f2fs_grab_cache_folio
: create page #0 in cache
- f2fs_convert_inline_folio
: sanity check failed, return -EFSCORRUPTED
- clear_inode detects that inode->i_data.nrpages is not zero
Fixes: 92dffd01790a ("f2fs: convert inline_data when i_size becomes large")
Reported-by: syzbot+90266696fe5daacebd35@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-f2fs-devel/68c09802.050a0220.3c6139.000e.GAE@google.com
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/file.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 6755d23a90512..c35b2a25a66d6 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -828,8 +828,16 @@ int f2fs_truncate(struct inode *inode)
/* we should check inline_data size */
if (!f2fs_may_inline_data(inode)) {
err = f2fs_convert_inline_inode(inode);
- if (err)
+ if (err) {
+ /*
+ * Always truncate page #0 to avoid page cache
+ * leak in evict() path.
+ */
+ truncate_inode_pages_range(inode->i_mapping,
+ F2FS_BLK_TO_BYTES(0),
+ F2FS_BLK_END_BYTES(0));
return err;
+ }
}
err = f2fs_truncate_blocks(inode, i_size_read(inode), true);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0864/1887] ipv6: use RCU in ip6_output()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (862 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0863/1887] f2fs: fix to truncate first page in error path of f2fs_truncate() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0865/1887] xen/events: avoid using info_for_irq() in xen_send_IPI_one() Greg Kroah-Hartman
` (134 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, David Ahern,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 11709573cc4e48dc34c80fc7ab9ce5b159e29695 ]
Use RCU in ip6_output() in order to use dst_dev_rcu() to prevent
possible UAF.
We can remove rcu_read_lock()/rcu_read_unlock() pairs
from ip6_finish_output2().
Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ip6_output.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 7ad60793c853c..3ff6f43bd40ae 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -59,7 +59,7 @@
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst->dev;
+ struct net_device *dev = dst_dev_rcu(dst);
struct inet6_dev *idev = ip6_dst_idev(dst);
unsigned int hh_len = LL_RESERVED_SPACE(dev);
const struct in6_addr *daddr, *nexthop;
@@ -69,15 +69,12 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
/* Be paranoid, rather than too clever. */
if (unlikely(hh_len > skb_headroom(skb)) && dev->header_ops) {
- /* Make sure idev stays alive */
- rcu_read_lock();
+ /* idev stays alive because we hold rcu_read_lock(). */
skb = skb_expand_head(skb, hh_len);
if (!skb) {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
- rcu_read_unlock();
return -ENOMEM;
}
- rcu_read_unlock();
}
hdr = ipv6_hdr(skb);
@@ -122,7 +119,6 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
daddr = &hdr->daddr;
}
- rcu_read_lock();
nexthop = rt6_nexthop(dst_rt6_info(dst), daddr);
neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
@@ -130,7 +126,6 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
if (unlikely(!neigh))
neigh = __neigh_create(&nd_tbl, nexthop, dev, false);
if (IS_ERR(neigh)) {
- rcu_read_unlock();
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
return -EINVAL;
@@ -138,7 +133,6 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
}
sock_confirm_neigh(skb, neigh);
ret = neigh_output(neigh, skb, false);
- rcu_read_unlock();
return ret;
}
@@ -224,22 +218,30 @@ static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
- struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+ struct dst_entry *dst = skb_dst(skb);
+ struct net_device *dev, *indev = skb->dev;
+ struct inet6_dev *idev;
+ int ret;
skb->protocol = htons(ETH_P_IPV6);
+ rcu_read_lock();
+ dev = dst_dev_rcu(dst);
+ idev = ip6_dst_idev(dst);
skb->dev = dev;
if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
+ rcu_read_unlock();
kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
return 0;
}
- return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
- net, sk, skb, indev, dev,
- ip6_finish_output,
- !(IP6CB(skb)->flags & IP6SKB_REROUTED));
+ ret = NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
+ net, sk, skb, indev, dev,
+ ip6_finish_output,
+ !(IP6CB(skb)->flags & IP6SKB_REROUTED));
+ rcu_read_unlock();
+ return ret;
}
EXPORT_SYMBOL(ip6_output);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0865/1887] xen/events: avoid using info_for_irq() in xen_send_IPI_one()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (863 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0864/1887] ipv6: use RCU in ip6_output() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0866/1887] xen/events: reduce externally visible helper functions Greg Kroah-Hartman
` (133 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Woodhouse, Juergen Gross,
Stefano Stabellini, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
[ Upstream commit e64e7c74b99ec9e439abca75f522f4b98f220bd1 ]
xen_send_IPI_one() is being used by cpuhp_report_idle_dead() after
it calls rcu_report_dead(), meaning that any RCU usage by
xen_send_IPI_one() is a bad idea.
Unfortunately xen_send_IPI_one() is using notify_remote_via_irq()
today, which is using irq_get_chip_data() via info_for_irq(). And
irq_get_chip_data() in turn is using a maple-tree lookup requiring
RCU.
Avoid this problem by caching the ipi event channels in another
percpu variable, allowing the use notify_remote_via_evtchn() in
xen_send_IPI_one().
Fixes: 721255b9826b ("genirq: Use a maple tree for interrupt descriptor management")
Reported-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: David Woodhouse <dwmw@amazon.co.uk>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Juergen Gross <jgross@suse.com>
Stable-dep-of: 07ce121d93a5 ("xen/events: Return -EEXIST for bound VIRQs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_base.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 9052a4873bca8..b8dd604f82b41 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -163,6 +163,8 @@ static DEFINE_PER_CPU(int [NR_VIRQS], virq_to_irq) = {[0 ... NR_VIRQS-1] = -1};
/* IRQ <-> IPI mapping */
static DEFINE_PER_CPU(int [XEN_NR_IPIS], ipi_to_irq) = {[0 ... XEN_NR_IPIS-1] = -1};
+/* Cache for IPI event channels - needed for hot cpu unplug (avoid RCU usage). */
+static DEFINE_PER_CPU(evtchn_port_t [XEN_NR_IPIS], ipi_to_evtchn) = {[0 ... XEN_NR_IPIS-1] = 0};
/* Event channel distribution data */
static atomic_t channels_on_cpu[NR_CPUS];
@@ -365,6 +367,7 @@ static int xen_irq_info_ipi_setup(unsigned cpu,
info->u.ipi = ipi;
per_cpu(ipi_to_irq, cpu)[ipi] = irq;
+ per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
return xen_irq_info_common_setup(info, irq, IRQT_IPI, evtchn, 0);
}
@@ -988,6 +991,7 @@ static void __unbind_from_irq(unsigned int irq)
break;
case IRQT_IPI:
per_cpu(ipi_to_irq, cpu)[ipi_from_irq(irq)] = -1;
+ per_cpu(ipi_to_evtchn, cpu)[ipi_from_irq(irq)] = 0;
break;
case IRQT_EVTCHN:
dev = info->u.interdomain;
@@ -1639,7 +1643,7 @@ EXPORT_SYMBOL_GPL(evtchn_put);
void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
{
- int irq;
+ evtchn_port_t evtchn;
#ifdef CONFIG_X86
if (unlikely(vector == XEN_NMI_VECTOR)) {
@@ -1650,9 +1654,9 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
return;
}
#endif
- irq = per_cpu(ipi_to_irq, cpu)[vector];
- BUG_ON(irq < 0);
- notify_remote_via_irq(irq);
+ evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+ BUG_ON(evtchn == 0);
+ notify_remote_via_evtchn(evtchn);
}
struct evtchn_loop_ctrl {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0866/1887] xen/events: reduce externally visible helper functions
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (864 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0865/1887] xen/events: avoid using info_for_irq() in xen_send_IPI_one() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0867/1887] xen/events: remove some simple helpers from events_base.c Greg Kroah-Hartman
` (132 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Juergen Gross, Oleksandr Tyshchenko,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
[ Upstream commit 686464514fbebb6c8de4415238319e414c3500a4 ]
get_evtchn_to_irq() has only one external user while irq_from_evtchn()
provides the same functionality and is exported for a wider user base.
Modify the only external user of get_evtchn_to_irq() to use
irq_from_evtchn() instead and make get_evtchn_to_irq() static.
evtchn_from_irq() and irq_from_virq() have a single external user and
can easily be combined to a new helper irq_evtchn_from_virq() allowing
to drop irq_from_virq() and to make evtchn_from_irq() static.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Stable-dep-of: 07ce121d93a5 ("xen/events: Return -EEXIST for bound VIRQs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_2l.c | 8 ++++----
drivers/xen/events/events_base.c | 13 +++++++++----
drivers/xen/events/events_internal.h | 1 -
include/xen/events.h | 4 ++--
4 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c
index b8f2f971c2f0f..e3585330cf98b 100644
--- a/drivers/xen/events/events_2l.c
+++ b/drivers/xen/events/events_2l.c
@@ -171,11 +171,11 @@ static void evtchn_2l_handle_events(unsigned cpu, struct evtchn_loop_ctrl *ctrl)
int i;
struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
+ evtchn_port_t evtchn;
/* Timer interrupt has highest priority. */
- irq = irq_from_virq(cpu, VIRQ_TIMER);
+ irq = irq_evtchn_from_virq(cpu, VIRQ_TIMER, &evtchn);
if (irq != -1) {
- evtchn_port_t evtchn = evtchn_from_irq(irq);
word_idx = evtchn / BITS_PER_LONG;
bit_idx = evtchn % BITS_PER_LONG;
if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx))
@@ -328,9 +328,9 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
for (i = 0; i < EVTCHN_2L_NR_CHANNELS; i++) {
if (sync_test_bit(i, BM(sh->evtchn_pending))) {
int word_idx = i / BITS_PER_EVTCHN_WORD;
- printk(" %d: event %d -> irq %d%s%s%s\n",
+ printk(" %d: event %d -> irq %u%s%s%s\n",
cpu_from_evtchn(i), i,
- get_evtchn_to_irq(i),
+ irq_from_evtchn(i),
sync_test_bit(word_idx, BM(&v->evtchn_pending_sel))
? "" : " l2-clear",
!sync_test_bit(i, BM(sh->evtchn_mask))
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index b8dd604f82b41..a92b96b575757 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -247,7 +247,7 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq)
return 0;
}
-int get_evtchn_to_irq(evtchn_port_t evtchn)
+static int get_evtchn_to_irq(evtchn_port_t evtchn)
{
if (evtchn >= xen_evtchn_max_channels())
return -1;
@@ -414,7 +414,7 @@ static void xen_irq_info_cleanup(struct irq_info *info)
/*
* Accessors for packed IRQ information.
*/
-evtchn_port_t evtchn_from_irq(unsigned irq)
+static evtchn_port_t evtchn_from_irq(unsigned int irq)
{
const struct irq_info *info = NULL;
@@ -432,9 +432,14 @@ unsigned int irq_from_evtchn(evtchn_port_t evtchn)
}
EXPORT_SYMBOL_GPL(irq_from_evtchn);
-int irq_from_virq(unsigned int cpu, unsigned int virq)
+int irq_evtchn_from_virq(unsigned int cpu, unsigned int virq,
+ evtchn_port_t *evtchn)
{
- return per_cpu(virq_to_irq, cpu)[virq];
+ int irq = per_cpu(virq_to_irq, cpu)[virq];
+
+ *evtchn = evtchn_from_irq(irq);
+
+ return irq;
}
static enum ipi_vector ipi_from_irq(unsigned irq)
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index 4d3398eff9cdf..19ae31695edcf 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -33,7 +33,6 @@ struct evtchn_ops {
extern const struct evtchn_ops *evtchn_ops;
-int get_evtchn_to_irq(evtchn_port_t evtchn);
void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl);
unsigned int cpu_from_evtchn(evtchn_port_t evtchn);
diff --git a/include/xen/events.h b/include/xen/events.h
index b303bd24e2a6c..07184beaa0a5c 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -102,8 +102,8 @@ void xen_poll_irq_timeout(int irq, u64 timeout);
/* Determine the IRQ which is bound to an event channel */
unsigned int irq_from_evtchn(evtchn_port_t evtchn);
-int irq_from_virq(unsigned int cpu, unsigned int virq);
-evtchn_port_t evtchn_from_irq(unsigned irq);
+int irq_evtchn_from_virq(unsigned int cpu, unsigned int virq,
+ evtchn_port_t *evtchn);
int xen_set_callback_via(uint64_t via);
int xen_evtchn_do_upcall(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0867/1887] xen/events: remove some simple helpers from events_base.c
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (865 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0866/1887] xen/events: reduce externally visible helper functions Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0868/1887] xen/events: drop xen_allocate_irqs_dynamic() Greg Kroah-Hartman
` (131 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Juergen Gross, Oleksandr Tyshchenko,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
[ Upstream commit 3bdb0ac350fe5e6301562143e4573971dd01ae0b ]
The helper functions type_from_irq() and cpu_from_irq() are just one
line functions used only internally.
Open code them where needed. At the same time modify and rename
get_evtchn_to_irq() to return a struct irq_info instead of the IRQ
number.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Stable-dep-of: 07ce121d93a5 ("xen/events: Return -EEXIST for bound VIRQs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_base.c | 97 +++++++++++++-------------------
1 file changed, 38 insertions(+), 59 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index a92b96b575757..72eace5842852 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -247,15 +247,6 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq)
return 0;
}
-static int get_evtchn_to_irq(evtchn_port_t evtchn)
-{
- if (evtchn >= xen_evtchn_max_channels())
- return -1;
- if (evtchn_to_irq[EVTCHN_ROW(evtchn)] == NULL)
- return -1;
- return READ_ONCE(evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)]);
-}
-
/* Get info for IRQ */
static struct irq_info *info_for_irq(unsigned irq)
{
@@ -273,6 +264,19 @@ static void set_info_for_irq(unsigned int irq, struct irq_info *info)
irq_set_chip_data(irq, info);
}
+static struct irq_info *evtchn_to_info(evtchn_port_t evtchn)
+{
+ int irq;
+
+ if (evtchn >= xen_evtchn_max_channels())
+ return NULL;
+ if (evtchn_to_irq[EVTCHN_ROW(evtchn)] == NULL)
+ return NULL;
+ irq = READ_ONCE(evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)]);
+
+ return (irq < 0) ? NULL : info_for_irq(irq);
+}
+
/* Per CPU channel accounting */
static void channels_on_cpu_dec(struct irq_info *info)
{
@@ -428,7 +432,9 @@ static evtchn_port_t evtchn_from_irq(unsigned int irq)
unsigned int irq_from_evtchn(evtchn_port_t evtchn)
{
- return get_evtchn_to_irq(evtchn);
+ struct irq_info *info = evtchn_to_info(evtchn);
+
+ return info ? info->irq : -1;
}
EXPORT_SYMBOL_GPL(irq_from_evtchn);
@@ -472,25 +478,11 @@ static unsigned pirq_from_irq(unsigned irq)
return info->u.pirq.pirq;
}
-static enum xen_irq_type type_from_irq(unsigned irq)
-{
- return info_for_irq(irq)->type;
-}
-
-static unsigned cpu_from_irq(unsigned irq)
-{
- return info_for_irq(irq)->cpu;
-}
-
unsigned int cpu_from_evtchn(evtchn_port_t evtchn)
{
- int irq = get_evtchn_to_irq(evtchn);
- unsigned ret = 0;
-
- if (irq != -1)
- ret = cpu_from_irq(irq);
+ struct irq_info *info = evtchn_to_info(evtchn);
- return ret;
+ return info ? info->cpu : 0;
}
static void do_mask(struct irq_info *info, u8 reason)
@@ -539,13 +531,12 @@ static bool pirq_needs_eoi_flag(unsigned irq)
static void bind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int cpu,
bool force_affinity)
{
- int irq = get_evtchn_to_irq(evtchn);
- struct irq_info *info = info_for_irq(irq);
+ struct irq_info *info = evtchn_to_info(evtchn);
- BUG_ON(irq == -1);
+ BUG_ON(info == NULL);
if (IS_ENABLED(CONFIG_SMP) && force_affinity) {
- struct irq_data *data = irq_get_irq_data(irq);
+ struct irq_data *data = irq_get_irq_data(info->irq);
irq_data_update_affinity(data, cpumask_of(cpu));
irq_data_update_effective_affinity(data, cpumask_of(cpu));
@@ -987,10 +978,10 @@ static void __unbind_from_irq(unsigned int irq)
}
if (VALID_EVTCHN(evtchn)) {
- unsigned int cpu = cpu_from_irq(irq);
+ unsigned int cpu = info->cpu;
struct xenbus_device *dev;
- switch (type_from_irq(irq)) {
+ switch (info->type) {
case IRQT_VIRQ:
per_cpu(virq_to_irq, cpu)[virq_from_irq(irq)] = -1;
break;
@@ -1214,15 +1205,16 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
{
int irq;
int ret;
+ struct irq_info *info;
if (evtchn >= xen_evtchn_max_channels())
return -ENOMEM;
mutex_lock(&irq_mapping_update_lock);
- irq = get_evtchn_to_irq(evtchn);
+ info = evtchn_to_info(evtchn);
- if (irq == -1) {
+ if (!info) {
irq = xen_allocate_irq_dynamic();
if (irq < 0)
goto out;
@@ -1245,8 +1237,8 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
*/
bind_evtchn_to_cpu(evtchn, 0, false);
} else {
- struct irq_info *info = info_for_irq(irq);
- WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
+ WARN_ON(info->type != IRQT_EVTCHN);
+ irq = info->irq;
}
out:
@@ -1585,13 +1577,7 @@ EXPORT_SYMBOL_GPL(xen_set_irq_priority);
int evtchn_make_refcounted(evtchn_port_t evtchn)
{
- int irq = get_evtchn_to_irq(evtchn);
- struct irq_info *info;
-
- if (irq == -1)
- return -ENOENT;
-
- info = info_for_irq(irq);
+ struct irq_info *info = evtchn_to_info(evtchn);
if (!info)
return -ENOENT;
@@ -1606,7 +1592,6 @@ EXPORT_SYMBOL_GPL(evtchn_make_refcounted);
int evtchn_get(evtchn_port_t evtchn)
{
- int irq;
struct irq_info *info;
int err = -ENOENT;
@@ -1615,11 +1600,7 @@ int evtchn_get(evtchn_port_t evtchn)
mutex_lock(&irq_mapping_update_lock);
- irq = get_evtchn_to_irq(evtchn);
- if (irq == -1)
- goto done;
-
- info = info_for_irq(irq);
+ info = evtchn_to_info(evtchn);
if (!info)
goto done;
@@ -1639,10 +1620,11 @@ EXPORT_SYMBOL_GPL(evtchn_get);
void evtchn_put(evtchn_port_t evtchn)
{
- int irq = get_evtchn_to_irq(evtchn);
- if (WARN_ON(irq == -1))
+ struct irq_info *info = evtchn_to_info(evtchn);
+
+ if (WARN_ON(!info))
return;
- unbind_from_irq(irq);
+ unbind_from_irq(info->irq);
}
EXPORT_SYMBOL_GPL(evtchn_put);
@@ -1672,12 +1654,10 @@ struct evtchn_loop_ctrl {
void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
{
- int irq;
- struct irq_info *info;
+ struct irq_info *info = evtchn_to_info(port);
struct xenbus_device *dev;
- irq = get_evtchn_to_irq(port);
- if (irq == -1)
+ if (!info)
return;
/*
@@ -1702,7 +1682,6 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
}
}
- info = info_for_irq(irq);
if (xchg_acquire(&info->is_active, 1))
return;
@@ -1716,7 +1695,7 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl)
info->eoi_time = get_jiffies_64() + event_eoi_delay;
}
- generic_handle_irq(irq);
+ generic_handle_irq(info->irq);
}
int xen_evtchn_do_upcall(void)
@@ -1774,7 +1753,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
mutex_lock(&irq_mapping_update_lock);
/* After resume the irq<->evtchn mappings are all cleared out */
- BUG_ON(get_evtchn_to_irq(evtchn) != -1);
+ BUG_ON(evtchn_to_info(evtchn));
/* Expect irq to have been bound before,
so there should be a proper type */
BUG_ON(info->type == IRQT_UNBOUND);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0868/1887] xen/events: drop xen_allocate_irqs_dynamic()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (866 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0867/1887] xen/events: remove some simple helpers from events_base.c Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0869/1887] xen/events: modify internal [un]bind interfaces Greg Kroah-Hartman
` (130 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Juergen Gross, Oleksandr Tyshchenko,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
[ Upstream commit 5dd9ad32d7758b1a76742f394acf0eb3ac8a636a ]
Instead of having a common function for allocating a single IRQ or a
consecutive number of IRQs, split up the functionality into the callers
of xen_allocate_irqs_dynamic().
This allows to handle any allocation error in xen_irq_init() gracefully
instead of panicing the system. Let xen_irq_init() return the irq_info
pointer or NULL in case of an allocation error.
Additionally set the IRQ into irq_info already at allocation time, as
otherwise the IRQ would be '0' (which is a valid IRQ number) until
being set.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Stable-dep-of: 07ce121d93a5 ("xen/events: Return -EEXIST for bound VIRQs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_base.c | 74 +++++++++++++++++++-------------
1 file changed, 44 insertions(+), 30 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 72eace5842852..fa1c5d7f4aded 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -303,6 +303,13 @@ static void channels_on_cpu_inc(struct irq_info *info)
info->is_accounted = 1;
}
+static void xen_irq_free_desc(unsigned int irq)
+{
+ /* Legacy IRQ descriptors are managed by the arch. */
+ if (irq >= nr_legacy_irqs())
+ irq_free_desc(irq);
+}
+
static void delayed_free_irq(struct work_struct *work)
{
struct irq_info *info = container_of(to_rcu_work(work), struct irq_info,
@@ -314,9 +321,7 @@ static void delayed_free_irq(struct work_struct *work)
kfree(info);
- /* Legacy IRQ descriptors are managed by the arch. */
- if (irq >= nr_legacy_irqs())
- irq_free_desc(irq);
+ xen_irq_free_desc(irq);
}
/* Constructors for packed IRQ information. */
@@ -331,7 +336,6 @@ static int xen_irq_info_common_setup(struct irq_info *info,
BUG_ON(info->type != IRQT_UNBOUND && info->type != type);
info->type = type;
- info->irq = irq;
info->evtchn = evtchn;
info->cpu = cpu;
info->mask_reason = EVT_MASK_REASON_EXPLICIT;
@@ -732,47 +736,45 @@ void xen_irq_lateeoi(unsigned int irq, unsigned int eoi_flags)
}
EXPORT_SYMBOL_GPL(xen_irq_lateeoi);
-static void xen_irq_init(unsigned irq)
+static struct irq_info *xen_irq_init(unsigned int irq)
{
struct irq_info *info;
info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (info == NULL)
- panic("Unable to allocate metadata for IRQ%d\n", irq);
+ if (info) {
+ info->irq = irq;
+ info->type = IRQT_UNBOUND;
+ info->refcnt = -1;
+ INIT_RCU_WORK(&info->rwork, delayed_free_irq);
- info->type = IRQT_UNBOUND;
- info->refcnt = -1;
- INIT_RCU_WORK(&info->rwork, delayed_free_irq);
+ set_info_for_irq(irq, info);
+ /*
+ * Interrupt affinity setting can be immediate. No point
+ * in delaying it until an interrupt is handled.
+ */
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
- set_info_for_irq(irq, info);
- /*
- * Interrupt affinity setting can be immediate. No point
- * in delaying it until an interrupt is handled.
- */
- irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
+ INIT_LIST_HEAD(&info->eoi_list);
+ list_add_tail(&info->list, &xen_irq_list_head);
+ }
- INIT_LIST_HEAD(&info->eoi_list);
- list_add_tail(&info->list, &xen_irq_list_head);
+ return info;
}
-static int __must_check xen_allocate_irqs_dynamic(int nvec)
+static inline int __must_check xen_allocate_irq_dynamic(void)
{
- int i, irq = irq_alloc_descs(-1, 0, nvec, -1);
+ int irq = irq_alloc_desc_from(0, -1);
if (irq >= 0) {
- for (i = 0; i < nvec; i++)
- xen_irq_init(irq + i);
+ if (!xen_irq_init(irq)) {
+ xen_irq_free_desc(irq);
+ irq = -1;
+ }
}
return irq;
}
-static inline int __must_check xen_allocate_irq_dynamic(void)
-{
-
- return xen_allocate_irqs_dynamic(1);
-}
-
static int __must_check xen_allocate_irq_gsi(unsigned gsi)
{
int irq;
@@ -792,7 +794,10 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
else
irq = irq_alloc_desc_at(gsi, -1);
- xen_irq_init(irq);
+ if (!xen_irq_init(irq)) {
+ xen_irq_free_desc(irq);
+ irq = -1;
+ }
return irq;
}
@@ -971,6 +976,11 @@ static void __unbind_from_irq(unsigned int irq)
evtchn_port_t evtchn = evtchn_from_irq(irq);
struct irq_info *info = info_for_irq(irq);
+ if (!info) {
+ xen_irq_free_desc(irq);
+ return;
+ }
+
if (info->refcnt > 0) {
info->refcnt--;
if (info->refcnt != 0)
@@ -1107,11 +1117,14 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
mutex_lock(&irq_mapping_update_lock);
- irq = xen_allocate_irqs_dynamic(nvec);
+ irq = irq_alloc_descs(-1, 0, nvec, -1);
if (irq < 0)
goto out;
for (i = 0; i < nvec; i++) {
+ if (!xen_irq_init(irq + i))
+ goto error_irq;
+
irq_set_chip_and_handler_name(irq + i, &xen_pirq_chip, handle_edge_irq, name);
ret = xen_irq_info_pirq_setup(irq + i, 0, pirq + i, 0, domid,
@@ -1758,6 +1771,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
so there should be a proper type */
BUG_ON(info->type == IRQT_UNBOUND);
+ info->irq = irq;
(void)xen_irq_info_evtchn_setup(irq, evtchn, NULL);
mutex_unlock(&irq_mapping_update_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0869/1887] xen/events: modify internal [un]bind interfaces
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (867 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0868/1887] xen/events: drop xen_allocate_irqs_dynamic() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0870/1887] xen/events: Return -EEXIST for bound VIRQs Greg Kroah-Hartman
` (129 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Juergen Gross, Oleksandr Tyshchenko,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
[ Upstream commit 3fcdaf3d7634338c3f5cbfa7451eb0b6b0024844 ]
Modify the internal bind- and unbind-interfaces to take a struct
irq_info parameter. When allocating a new IRQ pass the pointer from
the allocating function further up.
This will reduce the number of info_for_irq() calls and make the code
more efficient.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Stable-dep-of: 07ce121d93a5 ("xen/events: Return -EEXIST for bound VIRQs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_base.c | 254 +++++++++++++++----------------
1 file changed, 122 insertions(+), 132 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index fa1c5d7f4aded..0a468c2f9895e 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -326,7 +326,6 @@ static void delayed_free_irq(struct work_struct *work)
/* Constructors for packed IRQ information. */
static int xen_irq_info_common_setup(struct irq_info *info,
- unsigned irq,
enum xen_irq_type type,
evtchn_port_t evtchn,
unsigned short cpu)
@@ -341,23 +340,22 @@ static int xen_irq_info_common_setup(struct irq_info *info,
info->mask_reason = EVT_MASK_REASON_EXPLICIT;
raw_spin_lock_init(&info->lock);
- ret = set_evtchn_to_irq(evtchn, irq);
+ ret = set_evtchn_to_irq(evtchn, info->irq);
if (ret < 0)
return ret;
- irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
+ irq_clear_status_flags(info->irq, IRQ_NOREQUEST | IRQ_NOAUTOEN);
return xen_evtchn_port_setup(evtchn);
}
-static int xen_irq_info_evtchn_setup(unsigned irq,
+static int xen_irq_info_evtchn_setup(struct irq_info *info,
evtchn_port_t evtchn,
struct xenbus_device *dev)
{
- struct irq_info *info = info_for_irq(irq);
int ret;
- ret = xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0);
+ ret = xen_irq_info_common_setup(info, IRQT_EVTCHN, evtchn, 0);
info->u.interdomain = dev;
if (dev)
atomic_inc(&dev->event_channels);
@@ -365,50 +363,37 @@ static int xen_irq_info_evtchn_setup(unsigned irq,
return ret;
}
-static int xen_irq_info_ipi_setup(unsigned cpu,
- unsigned irq,
- evtchn_port_t evtchn,
- enum ipi_vector ipi)
+static int xen_irq_info_ipi_setup(struct irq_info *info, unsigned int cpu,
+ evtchn_port_t evtchn, enum ipi_vector ipi)
{
- struct irq_info *info = info_for_irq(irq);
-
info->u.ipi = ipi;
- per_cpu(ipi_to_irq, cpu)[ipi] = irq;
+ per_cpu(ipi_to_irq, cpu)[ipi] = info->irq;
per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
- return xen_irq_info_common_setup(info, irq, IRQT_IPI, evtchn, 0);
+ return xen_irq_info_common_setup(info, IRQT_IPI, evtchn, 0);
}
-static int xen_irq_info_virq_setup(unsigned cpu,
- unsigned irq,
- evtchn_port_t evtchn,
- unsigned virq)
+static int xen_irq_info_virq_setup(struct irq_info *info, unsigned int cpu,
+ evtchn_port_t evtchn, unsigned int virq)
{
- struct irq_info *info = info_for_irq(irq);
-
info->u.virq = virq;
- per_cpu(virq_to_irq, cpu)[virq] = irq;
+ per_cpu(virq_to_irq, cpu)[virq] = info->irq;
- return xen_irq_info_common_setup(info, irq, IRQT_VIRQ, evtchn, 0);
+ return xen_irq_info_common_setup(info, IRQT_VIRQ, evtchn, 0);
}
-static int xen_irq_info_pirq_setup(unsigned irq,
- evtchn_port_t evtchn,
- unsigned pirq,
- unsigned gsi,
- uint16_t domid,
- unsigned char flags)
+static int xen_irq_info_pirq_setup(struct irq_info *info, evtchn_port_t evtchn,
+ unsigned int pirq, unsigned int gsi,
+ uint16_t domid, unsigned char flags)
{
- struct irq_info *info = info_for_irq(irq);
-
info->u.pirq.pirq = pirq;
info->u.pirq.gsi = gsi;
info->u.pirq.domid = domid;
info->u.pirq.flags = flags;
- return xen_irq_info_common_setup(info, irq, IRQT_PIRQ, evtchn, 0);
+ return xen_irq_info_common_setup(info, IRQT_PIRQ, evtchn, 0);
}
static void xen_irq_info_cleanup(struct irq_info *info)
@@ -452,20 +437,16 @@ int irq_evtchn_from_virq(unsigned int cpu, unsigned int virq,
return irq;
}
-static enum ipi_vector ipi_from_irq(unsigned irq)
+static enum ipi_vector ipi_from_irq(struct irq_info *info)
{
- struct irq_info *info = info_for_irq(irq);
-
BUG_ON(info == NULL);
BUG_ON(info->type != IRQT_IPI);
return info->u.ipi;
}
-static unsigned virq_from_irq(unsigned irq)
+static unsigned int virq_from_irq(struct irq_info *info)
{
- struct irq_info *info = info_for_irq(irq);
-
BUG_ON(info == NULL);
BUG_ON(info->type != IRQT_VIRQ);
@@ -532,13 +513,9 @@ static bool pirq_needs_eoi_flag(unsigned irq)
return info->u.pirq.flags & PIRQ_NEEDS_EOI;
}
-static void bind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int cpu,
+static void bind_evtchn_to_cpu(struct irq_info *info, unsigned int cpu,
bool force_affinity)
{
- struct irq_info *info = evtchn_to_info(evtchn);
-
- BUG_ON(info == NULL);
-
if (IS_ENABLED(CONFIG_SMP) && force_affinity) {
struct irq_data *data = irq_get_irq_data(info->irq);
@@ -546,7 +523,7 @@ static void bind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int cpu,
irq_data_update_effective_affinity(data, cpumask_of(cpu));
}
- xen_evtchn_port_bind_to_cpu(evtchn, cpu, info->cpu);
+ xen_evtchn_port_bind_to_cpu(info->evtchn, cpu, info->cpu);
channels_on_cpu_dec(info);
info->cpu = cpu;
@@ -761,23 +738,24 @@ static struct irq_info *xen_irq_init(unsigned int irq)
return info;
}
-static inline int __must_check xen_allocate_irq_dynamic(void)
+static struct irq_info *xen_allocate_irq_dynamic(void)
{
int irq = irq_alloc_desc_from(0, -1);
+ struct irq_info *info = NULL;
if (irq >= 0) {
- if (!xen_irq_init(irq)) {
+ info = xen_irq_init(irq);
+ if (!info)
xen_irq_free_desc(irq);
- irq = -1;
- }
}
- return irq;
+ return info;
}
-static int __must_check xen_allocate_irq_gsi(unsigned gsi)
+static struct irq_info *xen_allocate_irq_gsi(unsigned int gsi)
{
int irq;
+ struct irq_info *info;
/*
* A PV guest has no concept of a GSI (since it has no ACPI
@@ -794,18 +772,15 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
else
irq = irq_alloc_desc_at(gsi, -1);
- if (!xen_irq_init(irq)) {
+ info = xen_irq_init(irq);
+ if (!info)
xen_irq_free_desc(irq);
- irq = -1;
- }
- return irq;
+ return info;
}
-static void xen_free_irq(unsigned irq)
+static void xen_free_irq(struct irq_info *info)
{
- struct irq_info *info = info_for_irq(irq);
-
if (WARN_ON(!info))
return;
@@ -905,7 +880,7 @@ static unsigned int __startup_pirq(unsigned int irq)
goto err;
info->evtchn = evtchn;
- bind_evtchn_to_cpu(evtchn, 0, false);
+ bind_evtchn_to_cpu(info, 0, false);
rc = xen_evtchn_port_setup(evtchn);
if (rc)
@@ -971,10 +946,9 @@ int xen_irq_from_gsi(unsigned gsi)
}
EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
-static void __unbind_from_irq(unsigned int irq)
+static void __unbind_from_irq(struct irq_info *info, unsigned int irq)
{
- evtchn_port_t evtchn = evtchn_from_irq(irq);
- struct irq_info *info = info_for_irq(irq);
+ evtchn_port_t evtchn;
if (!info) {
xen_irq_free_desc(irq);
@@ -987,17 +961,19 @@ static void __unbind_from_irq(unsigned int irq)
return;
}
+ evtchn = info->evtchn;
+
if (VALID_EVTCHN(evtchn)) {
unsigned int cpu = info->cpu;
struct xenbus_device *dev;
switch (info->type) {
case IRQT_VIRQ:
- per_cpu(virq_to_irq, cpu)[virq_from_irq(irq)] = -1;
+ per_cpu(virq_to_irq, cpu)[virq_from_irq(info)] = -1;
break;
case IRQT_IPI:
- per_cpu(ipi_to_irq, cpu)[ipi_from_irq(irq)] = -1;
- per_cpu(ipi_to_evtchn, cpu)[ipi_from_irq(irq)] = 0;
+ per_cpu(ipi_to_irq, cpu)[ipi_from_irq(info)] = -1;
+ per_cpu(ipi_to_evtchn, cpu)[ipi_from_irq(info)] = 0;
break;
case IRQT_EVTCHN:
dev = info->u.interdomain;
@@ -1012,7 +988,7 @@ static void __unbind_from_irq(unsigned int irq)
xen_evtchn_close(evtchn);
}
- xen_free_irq(irq);
+ xen_free_irq(info);
}
/*
@@ -1028,24 +1004,24 @@ static void __unbind_from_irq(unsigned int irq)
int xen_bind_pirq_gsi_to_irq(unsigned gsi,
unsigned pirq, int shareable, char *name)
{
- int irq;
+ struct irq_info *info;
struct physdev_irq irq_op;
int ret;
mutex_lock(&irq_mapping_update_lock);
- irq = xen_irq_from_gsi(gsi);
- if (irq != -1) {
+ ret = xen_irq_from_gsi(gsi);
+ if (ret != -1) {
pr_info("%s: returning irq %d for gsi %u\n",
- __func__, irq, gsi);
+ __func__, ret, gsi);
goto out;
}
- irq = xen_allocate_irq_gsi(gsi);
- if (irq < 0)
+ info = xen_allocate_irq_gsi(gsi);
+ if (!info)
goto out;
- irq_op.irq = irq;
+ irq_op.irq = info->irq;
irq_op.vector = 0;
/* Only the privileged domain can do this. For non-priv, the pcifront
@@ -1053,20 +1029,19 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
* this in the priv domain. */
if (xen_initial_domain() &&
HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
- xen_free_irq(irq);
- irq = -ENOSPC;
+ xen_free_irq(info);
+ ret = -ENOSPC;
goto out;
}
- ret = xen_irq_info_pirq_setup(irq, 0, pirq, gsi, DOMID_SELF,
+ ret = xen_irq_info_pirq_setup(info, 0, pirq, gsi, DOMID_SELF,
shareable ? PIRQ_SHAREABLE : 0);
if (ret < 0) {
- __unbind_from_irq(irq);
- irq = ret;
+ __unbind_from_irq(info, info->irq);
goto out;
}
- pirq_query_unmask(irq);
+ pirq_query_unmask(info->irq);
/* We try to use the handler with the appropriate semantic for the
* type of interrupt: if the interrupt is an edge triggered
* interrupt we use handle_edge_irq.
@@ -1083,16 +1058,18 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
* is the right choice either way.
*/
if (shareable)
- irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
+ irq_set_chip_and_handler_name(info->irq, &xen_pirq_chip,
handle_fasteoi_irq, name);
else
- irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
+ irq_set_chip_and_handler_name(info->irq, &xen_pirq_chip,
handle_edge_irq, name);
+ ret = info->irq;
+
out:
mutex_unlock(&irq_mapping_update_lock);
- return irq;
+ return ret;
}
#ifdef CONFIG_PCI_MSI
@@ -1114,6 +1091,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
int pirq, int nvec, const char *name, domid_t domid)
{
int i, irq, ret;
+ struct irq_info *info;
mutex_lock(&irq_mapping_update_lock);
@@ -1122,12 +1100,13 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
goto out;
for (i = 0; i < nvec; i++) {
- if (!xen_irq_init(irq + i))
+ info = xen_irq_init(irq + i);
+ if (!info)
goto error_irq;
irq_set_chip_and_handler_name(irq + i, &xen_pirq_chip, handle_edge_irq, name);
- ret = xen_irq_info_pirq_setup(irq + i, 0, pirq + i, 0, domid,
+ ret = xen_irq_info_pirq_setup(info, 0, pirq + i, 0, domid,
i == 0 ? 0 : PIRQ_MSI_GROUP);
if (ret < 0)
goto error_irq;
@@ -1139,9 +1118,12 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
out:
mutex_unlock(&irq_mapping_update_lock);
return irq;
+
error_irq:
- while (nvec--)
- __unbind_from_irq(irq + nvec);
+ while (nvec--) {
+ info = info_for_irq(irq + nvec);
+ __unbind_from_irq(info, irq + nvec);
+ }
mutex_unlock(&irq_mapping_update_lock);
return ret;
}
@@ -1177,7 +1159,7 @@ int xen_destroy_irq(int irq)
}
}
- xen_free_irq(irq);
+ xen_free_irq(info);
out:
mutex_unlock(&irq_mapping_update_lock);
@@ -1216,8 +1198,7 @@ EXPORT_SYMBOL_GPL(xen_pirq_from_irq);
static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
struct xenbus_device *dev)
{
- int irq;
- int ret;
+ int ret = -ENOMEM;
struct irq_info *info;
if (evtchn >= xen_evtchn_max_channels())
@@ -1228,17 +1209,16 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
info = evtchn_to_info(evtchn);
if (!info) {
- irq = xen_allocate_irq_dynamic();
- if (irq < 0)
+ info = xen_allocate_irq_dynamic();
+ if (!info)
goto out;
- irq_set_chip_and_handler_name(irq, chip,
+ irq_set_chip_and_handler_name(info->irq, chip,
handle_edge_irq, "event");
- ret = xen_irq_info_evtchn_setup(irq, evtchn, dev);
+ ret = xen_irq_info_evtchn_setup(info, evtchn, dev);
if (ret < 0) {
- __unbind_from_irq(irq);
- irq = ret;
+ __unbind_from_irq(info, info->irq);
goto out;
}
/*
@@ -1248,16 +1228,17 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
* affinity setting is not invoked on them so nothing would
* bind the channel.
*/
- bind_evtchn_to_cpu(evtchn, 0, false);
+ bind_evtchn_to_cpu(info, 0, false);
} else {
WARN_ON(info->type != IRQT_EVTCHN);
- irq = info->irq;
}
+ ret = info->irq;
+
out:
mutex_unlock(&irq_mapping_update_lock);
- return irq;
+ return ret;
}
int bind_evtchn_to_irq(evtchn_port_t evtchn)
@@ -1276,18 +1257,19 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
struct evtchn_bind_ipi bind_ipi;
evtchn_port_t evtchn;
- int ret, irq;
+ struct irq_info *info;
+ int ret;
mutex_lock(&irq_mapping_update_lock);
- irq = per_cpu(ipi_to_irq, cpu)[ipi];
+ ret = per_cpu(ipi_to_irq, cpu)[ipi];
- if (irq == -1) {
- irq = xen_allocate_irq_dynamic();
- if (irq < 0)
+ if (ret == -1) {
+ info = xen_allocate_irq_dynamic();
+ if (!info)
goto out;
- irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
+ irq_set_chip_and_handler_name(info->irq, &xen_percpu_chip,
handle_percpu_irq, "ipi");
bind_ipi.vcpu = xen_vcpu_nr(cpu);
@@ -1296,25 +1278,25 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
BUG();
evtchn = bind_ipi.port;
- ret = xen_irq_info_ipi_setup(cpu, irq, evtchn, ipi);
+ ret = xen_irq_info_ipi_setup(info, cpu, evtchn, ipi);
if (ret < 0) {
- __unbind_from_irq(irq);
- irq = ret;
+ __unbind_from_irq(info, info->irq);
goto out;
}
/*
* Force the affinity mask to the target CPU so proc shows
* the correct target.
*/
- bind_evtchn_to_cpu(evtchn, cpu, true);
+ bind_evtchn_to_cpu(info, cpu, true);
+ ret = info->irq;
} else {
- struct irq_info *info = info_for_irq(irq);
+ info = info_for_irq(ret);
WARN_ON(info == NULL || info->type != IRQT_IPI);
}
out:
mutex_unlock(&irq_mapping_update_lock);
- return irq;
+ return ret;
}
static int bind_interdomain_evtchn_to_irq_chip(struct xenbus_device *dev,
@@ -1383,22 +1365,23 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
{
struct evtchn_bind_virq bind_virq;
evtchn_port_t evtchn = 0;
- int irq, ret;
+ struct irq_info *info;
+ int ret;
mutex_lock(&irq_mapping_update_lock);
- irq = per_cpu(virq_to_irq, cpu)[virq];
+ ret = per_cpu(virq_to_irq, cpu)[virq];
- if (irq == -1) {
- irq = xen_allocate_irq_dynamic();
- if (irq < 0)
+ if (ret == -1) {
+ info = xen_allocate_irq_dynamic();
+ if (!info)
goto out;
if (percpu)
- irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
+ irq_set_chip_and_handler_name(info->irq, &xen_percpu_chip,
handle_percpu_irq, "virq");
else
- irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
+ irq_set_chip_and_handler_name(info->irq, &xen_dynamic_chip,
handle_edge_irq, "virq");
bind_virq.virq = virq;
@@ -1413,10 +1396,9 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
BUG_ON(ret < 0);
}
- ret = xen_irq_info_virq_setup(cpu, irq, evtchn, virq);
+ ret = xen_irq_info_virq_setup(info, cpu, evtchn, virq);
if (ret < 0) {
- __unbind_from_irq(irq);
- irq = ret;
+ __unbind_from_irq(info, info->irq);
goto out;
}
@@ -1424,22 +1406,26 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
* Force the affinity mask for percpu interrupts so proc
* shows the correct target.
*/
- bind_evtchn_to_cpu(evtchn, cpu, percpu);
+ bind_evtchn_to_cpu(info, cpu, percpu);
+ ret = info->irq;
} else {
- struct irq_info *info = info_for_irq(irq);
+ info = info_for_irq(ret);
WARN_ON(info == NULL || info->type != IRQT_VIRQ);
}
out:
mutex_unlock(&irq_mapping_update_lock);
- return irq;
+ return ret;
}
static void unbind_from_irq(unsigned int irq)
{
+ struct irq_info *info;
+
mutex_lock(&irq_mapping_update_lock);
- __unbind_from_irq(irq);
+ info = info_for_irq(irq);
+ __unbind_from_irq(info, irq);
mutex_unlock(&irq_mapping_update_lock);
}
@@ -1772,11 +1758,11 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
BUG_ON(info->type == IRQT_UNBOUND);
info->irq = irq;
- (void)xen_irq_info_evtchn_setup(irq, evtchn, NULL);
+ (void)xen_irq_info_evtchn_setup(info, evtchn, NULL);
mutex_unlock(&irq_mapping_update_lock);
- bind_evtchn_to_cpu(evtchn, info->cpu, false);
+ bind_evtchn_to_cpu(info, info->cpu, false);
/* Unmask the event channel. */
enable_irq(irq);
@@ -1812,7 +1798,7 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) {
int old_cpu = info->cpu;
- bind_evtchn_to_cpu(evtchn, tcpu, false);
+ bind_evtchn_to_cpu(info, tcpu, false);
if (info->type == IRQT_VIRQ) {
int virq = info->u.virq;
@@ -1972,7 +1958,7 @@ static void restore_pirqs(void)
if (rc) {
pr_warn("xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n",
gsi, irq, pirq, rc);
- xen_free_irq(irq);
+ xen_free_irq(info);
continue;
}
@@ -1986,13 +1972,15 @@ static void restore_cpu_virqs(unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
evtchn_port_t evtchn;
+ struct irq_info *info;
int virq, irq;
for (virq = 0; virq < NR_VIRQS; virq++) {
if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
continue;
+ info = info_for_irq(irq);
- BUG_ON(virq_from_irq(irq) != virq);
+ BUG_ON(virq_from_irq(info) != virq);
/* Get a new binding from Xen. */
bind_virq.virq = virq;
@@ -2003,9 +1991,9 @@ static void restore_cpu_virqs(unsigned int cpu)
evtchn = bind_virq.port;
/* Record the new mapping. */
- (void)xen_irq_info_virq_setup(cpu, irq, evtchn, virq);
+ xen_irq_info_virq_setup(info, cpu, evtchn, virq);
/* The affinity mask is still valid */
- bind_evtchn_to_cpu(evtchn, cpu, false);
+ bind_evtchn_to_cpu(info, cpu, false);
}
}
@@ -2013,13 +2001,15 @@ static void restore_cpu_ipis(unsigned int cpu)
{
struct evtchn_bind_ipi bind_ipi;
evtchn_port_t evtchn;
+ struct irq_info *info;
int ipi, irq;
for (ipi = 0; ipi < XEN_NR_IPIS; ipi++) {
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
continue;
+ info = info_for_irq(irq);
- BUG_ON(ipi_from_irq(irq) != ipi);
+ BUG_ON(ipi_from_irq(info) != ipi);
/* Get a new binding from Xen. */
bind_ipi.vcpu = xen_vcpu_nr(cpu);
@@ -2029,9 +2019,9 @@ static void restore_cpu_ipis(unsigned int cpu)
evtchn = bind_ipi.port;
/* Record the new mapping. */
- (void)xen_irq_info_ipi_setup(cpu, irq, evtchn, ipi);
+ xen_irq_info_ipi_setup(info, cpu, evtchn, ipi);
/* The affinity mask is still valid */
- bind_evtchn_to_cpu(evtchn, cpu, false);
+ bind_evtchn_to_cpu(info, cpu, false);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0870/1887] xen/events: Return -EEXIST for bound VIRQs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (868 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0869/1887] xen/events: modify internal [un]bind interfaces Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0871/1887] net: use dst_dev_rcu() in sk_setup_caps() Greg Kroah-Hartman
` (128 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Andryuk, Juergen Gross,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <jason.andryuk@amd.com>
[ Upstream commit 07ce121d93a5e5fb2440a24da3dbf408fcee978e ]
Change find_virq() to return -EEXIST when a VIRQ is bound to a
different CPU than the one passed in. With that, remove the BUG_ON()
from bind_virq_to_irq() to propogate the error upwards.
Some VIRQs are per-cpu, but others are per-domain or global. Those must
be bound to CPU0 and can then migrate elsewhere. The lookup for
per-domain and global will probably fail when migrated off CPU 0,
especially when the current CPU is tracked. This now returns -EEXIST
instead of BUG_ON().
A second call to bind a per-domain or global VIRQ is not expected, but
make it non-fatal to avoid trying to look up the irq, since we don't
know which per_cpu(virq_to_irq) it will be in.
Cc: stable@vger.kernel.org
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Message-ID: <20250828003604.8949-3-jason.andryuk@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/events/events_base.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 0a468c2f9895e..bdfbe27591593 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1324,10 +1324,12 @@ int bind_interdomain_evtchn_to_irq_lateeoi(struct xenbus_device *dev,
}
EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi);
-static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
+static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn,
+ bool percpu)
{
struct evtchn_status status;
evtchn_port_t port;
+ bool exists = false;
memset(&status, 0, sizeof(status));
for (port = 0; port < xen_evtchn_max_channels(); port++) {
@@ -1340,12 +1342,16 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
continue;
if (status.status != EVTCHNSTAT_virq)
continue;
- if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(cpu)) {
+ if (status.u.virq != virq)
+ continue;
+ if (status.vcpu == xen_vcpu_nr(cpu)) {
*evtchn = port;
return 0;
+ } else if (!percpu) {
+ exists = true;
}
}
- return -ENOENT;
+ return exists ? -EEXIST : -ENOENT;
}
/**
@@ -1392,8 +1398,11 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
evtchn = bind_virq.port;
else {
if (ret == -EEXIST)
- ret = find_virq(virq, cpu, &evtchn);
- BUG_ON(ret < 0);
+ ret = find_virq(virq, cpu, &evtchn, percpu);
+ if (ret) {
+ __unbind_from_irq(info, info->irq);
+ goto out;
+ }
}
ret = xen_irq_info_virq_setup(info, cpu, evtchn, virq);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0871/1887] net: use dst_dev_rcu() in sk_setup_caps()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (869 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0870/1887] xen/events: Return -EEXIST for bound VIRQs Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0872/1887] of: Move of_device_(add|register|unregister) to of_platform.h Greg Kroah-Hartman
` (127 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, David Ahern,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 99a2ace61b211b0be861b07fbaa062fca4b58879 ]
Use RCU to protect accesses to dst->dev from sk_setup_caps()
and sk_dst_gso_max_size().
Also use dst_dev_rcu() in ip6_dst_mtu_maybe_forward(),
and ip_dst_mtu_maybe_forward().
ip4_dst_hoplimit() can use dst_dev_net_rcu().
Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/ip.h | 17 +++++++++++++----
include/net/ip6_route.h | 2 +-
include/net/route.h | 2 +-
net/core/sock.c | 10 +++++++---
4 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 49e86b8bf9c9a..855998087701e 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -459,9 +459,14 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
bool forwarding)
{
const struct rtable *rt = container_of(dst, struct rtable, dst);
- struct net *net = dev_net(dst_dev(dst));
- unsigned int mtu;
+ const struct net_device *dev;
+ unsigned int mtu, res;
+ struct net *net;
+
+ rcu_read_lock();
+ dev = dst_dev_rcu(dst);
+ net = dev_net_rcu(dev);
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
ip_mtu_locked(dst) ||
!forwarding) {
@@ -475,7 +480,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
if (mtu)
goto out;
- mtu = READ_ONCE(dst_dev(dst)->mtu);
+ mtu = READ_ONCE(dev->mtu);
if (unlikely(ip_mtu_locked(dst))) {
if (rt->rt_uses_gateway && mtu > 576)
@@ -485,7 +490,11 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
out:
mtu = min_t(unsigned int, mtu, IP_MAX_MTU);
- return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
+ res = mtu - lwtunnel_headroom(dst->lwtstate, mtu);
+
+ rcu_read_unlock();
+
+ return res;
}
static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 9df55c2ee058c..6b7dae7d47dbe 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -337,7 +337,7 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
mtu = IPV6_MIN_MTU;
rcu_read_lock();
- idev = __in6_dev_get(dst->dev);
+ idev = __in6_dev_get(dst_dev_rcu(dst));
if (idev)
mtu = idev->cnf.mtu6;
rcu_read_unlock();
diff --git a/include/net/route.h b/include/net/route.h
index ce608f8830401..4e2f8c3e1f98e 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -362,7 +362,7 @@ static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
const struct net *net;
rcu_read_lock();
- net = dev_net_rcu(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
rcu_read_unlock();
}
diff --git a/net/core/sock.c b/net/core/sock.c
index 8593dc1b33eb3..6f8a15aa4a126 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2395,9 +2395,12 @@ static void sk_trim_gso_size(struct sock *sk)
void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
{
+ const struct net_device *dev;
u32 max_segs = 1;
- sk->sk_route_caps = dst_dev(dst)->features;
+ rcu_read_lock();
+ dev = dst_dev_rcu(dst);
+ sk->sk_route_caps = dev->features;
if (sk_is_tcp(sk))
sk->sk_route_caps |= NETIF_F_GSO;
if (sk->sk_route_caps & NETIF_F_GSO)
@@ -2410,15 +2413,16 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
- sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
+ sk->sk_gso_max_size = READ_ONCE(dev->gso_max_size);
sk_trim_gso_size(sk);
sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
- max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
+ max_segs = max_t(u32, READ_ONCE(dev->gso_max_segs), 1);
}
}
sk->sk_gso_max_segs = max_segs;
sk_dst_set(sk, dst);
+ rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(sk_setup_caps);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0872/1887] of: Move of_device_(add|register|unregister) to of_platform.h
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (870 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0871/1887] net: use dst_dev_rcu() in sk_setup_caps() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0873/1887] of: Move of_device_get_match_data() declaration Greg Kroah-Hartman
` (126 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rob Herring, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring <robh@kernel.org>
[ Upstream commit 4c32fb7dcf65b16cc7b2837ccfc35d00be92bddb ]
As of_device_(add|register|unregister) functions work on struct
platform_device, they should be declared in of_platform.h instead.
This move is transparent for now as both headers include each other.
Link: https://lore.kernel.org/r/20230329-dt-cpu-header-cleanups-v1-2-581e2605fe47@kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/of_device.h | 4 ----
include/linux/of_platform.h | 5 +++++
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 1a803e4335d30..90dabbf1e0258 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -26,10 +26,6 @@ static inline int of_driver_match_device(struct device *dev,
return of_match_device(drv->of_match_table, dev) != NULL;
}
-extern int of_device_add(struct platform_device *pdev);
-extern int of_device_register(struct platform_device *ofdev);
-extern void of_device_unregister(struct platform_device *ofdev);
-
extern const void *of_device_get_match_data(const struct device *dev);
extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len);
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index d15b6cd5e1c3a..8ac5cb933dc3c 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -52,6 +52,11 @@ extern const struct of_device_id of_default_bus_match_table[];
extern struct platform_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent);
+
+extern int of_device_add(struct platform_device *pdev);
+extern int of_device_register(struct platform_device *ofdev);
+extern void of_device_unregister(struct platform_device *ofdev);
+
#ifdef CONFIG_OF
extern struct platform_device *of_find_device_by_node(struct device_node *np);
#else
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0873/1887] of: Move of_device_get_match_data() declaration
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (871 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0872/1887] of: Move of_device_(add|register|unregister) to of_platform.h Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0874/1887] mailbox: Explicitly include correct DT includes Greg Kroah-Hartman
` (125 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rob Herring, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring <robh@kernel.org>
[ Upstream commit 82174a0a9c5cf36a3e421fc1d2c86998d8023f61 ]
of_device.h mostly defines functions for bus drivers whereas
of_device_get_match_data() is used by drivers. Let's move it to of.h.
Link: https://lore.kernel.org/r/20230329-dt-cpu-header-cleanups-v1-3-581e2605fe47@kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/of.h | 6 ++++++
include/linux/of_device.h | 7 -------
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index 2960e609ca05e..9ff3ce1719c0b 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -364,6 +364,7 @@ extern int of_n_addr_cells(struct device_node *np);
extern int of_n_size_cells(struct device_node *np);
extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
+extern const void *of_device_get_match_data(const struct device *dev);
extern int of_modalias_node(struct device_node *node, char *modalias, int len);
extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
extern int __of_parse_phandle_with_args(const struct device_node *np,
@@ -845,6 +846,11 @@ static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np)
return PHYS_ADDR_MAX;
}
+static inline const void *of_device_get_match_data(const struct device *dev)
+{
+ return NULL;
+}
+
#define of_match_ptr(_ptr) NULL
#define of_match_node(_matches, _node) NULL
#endif /* CONFIG_OF */
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 90dabbf1e0258..24b911d3c89a7 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -26,8 +26,6 @@ static inline int of_driver_match_device(struct device *dev,
return of_match_device(drv->of_match_table, dev) != NULL;
}
-extern const void *of_device_get_match_data(const struct device *dev);
-
extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len);
extern int of_device_request_module(struct device *dev);
@@ -63,11 +61,6 @@ static inline int of_driver_match_device(struct device *dev,
static inline void of_device_uevent(struct device *dev,
struct kobj_uevent_env *env) { }
-static inline const void *of_device_get_match_data(const struct device *dev)
-{
- return NULL;
-}
-
static inline int of_device_modalias(struct device *dev,
char *str, ssize_t len)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0874/1887] mailbox: Explicitly include correct DT includes
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (872 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0873/1887] of: Move of_device_get_match_data() declaration Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0875/1887] mailbox: zynqmp-ipi: fix an Excess struct member kernel-doc warning Greg Kroah-Hartman
` (124 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rob Herring, Jassi Brar, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring <robh@kernel.org>
[ Upstream commit e9803aac5097ac74186b074d3176318fd10ec98c ]
The DT of_device.h and of_platform.h date back to the separate
of_platform_bus_type before it as merged into the regular platform bus.
As part of that merge prepping Arm DT support 13 years ago, they
"temporarily" include each other. They also include platform_device.h
and of.h. As a result, there's a pretty much random mix of those include
files used throughout the tree. In order to detangle these headers and
replace the implicit includes with struct declarations, users need to
explicitly include the correct includes.
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mailbox/arm_mhu.c | 1 +
drivers/mailbox/arm_mhu_db.c | 1 -
drivers/mailbox/hi3660-mailbox.c | 1 +
drivers/mailbox/hi6220-mailbox.c | 1 +
drivers/mailbox/imx-mailbox.c | 3 ++-
drivers/mailbox/mailbox-mpfs.c | 1 +
drivers/mailbox/mailbox.c | 1 +
drivers/mailbox/mtk-adsp-mailbox.c | 3 ++-
drivers/mailbox/mtk-cmdq-mailbox.c | 2 +-
drivers/mailbox/omap-mailbox.c | 2 +-
drivers/mailbox/platform_mhu.c | 1 +
drivers/mailbox/rockchip-mailbox.c | 2 +-
drivers/mailbox/sprd-mailbox.c | 2 +-
drivers/mailbox/stm32-ipcc.c | 1 +
drivers/mailbox/tegra-hsp.c | 1 -
drivers/mailbox/zynqmp-ipi-mailbox.c | 2 --
16 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
index 22243cabe0565..537f7bfb7b064 100644
--- a/drivers/mailbox/arm_mhu.c
+++ b/drivers/mailbox/arm_mhu.c
@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
+#include <linux/of.h>
#define INTR_STAT_OFS 0x0
#define INTR_SET_OFS 0x8
diff --git a/drivers/mailbox/arm_mhu_db.c b/drivers/mailbox/arm_mhu_db.c
index aa0a4d83880fc..27a510d469082 100644
--- a/drivers/mailbox/arm_mhu_db.c
+++ b/drivers/mailbox/arm_mhu_db.c
@@ -15,7 +15,6 @@
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#define INTR_STAT_OFS 0x0
#define INTR_SET_OFS 0x8
diff --git a/drivers/mailbox/hi3660-mailbox.c b/drivers/mailbox/hi3660-mailbox.c
index ab24e731a7823..17c29e960fbf8 100644
--- a/drivers/mailbox/hi3660-mailbox.c
+++ b/drivers/mailbox/hi3660-mailbox.c
@@ -11,6 +11,7 @@
#include <linux/iopoll.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c
index fca61f5312d91..cf92523fd30b6 100644
--- a/drivers/mailbox/hi6220-mailbox.c
+++ b/drivers/mailbox/hi6220-mailbox.c
@@ -15,6 +15,7 @@
#include <linux/kfifo.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 3292fb2dc3bf2..5eef59f00abd5 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -14,7 +14,8 @@
#include <linux/kernel.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <linux/slab.h>
diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
index 08aa840cccaca..5fde9b9e6fea8 100644
--- a/drivers/mailbox/mailbox-mpfs.c
+++ b/drivers/mailbox/mailbox-mpfs.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/mailbox_controller.h>
#include <soc/microchip/mpfs.h>
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index a00a02b6709c7..0af89103b034a 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -17,6 +17,7 @@
#include <linux/bitops.h>
#include <linux/mailbox_client.h>
#include <linux/mailbox_controller.h>
+#include <linux/of.h>
#include "mailbox.h"
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
index 182045dd90df9..8bcecddee0eb5 100644
--- a/drivers/mailbox/mtk-adsp-mailbox.c
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -10,7 +10,8 @@
#include <linux/kernel.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
struct mtk_adsp_mbox_priv {
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 3d369c23970cc..1eaab345f4a62 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -15,7 +15,7 @@
#include <linux/platform_device.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox/mtk-cmdq-mailbox.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)
#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 098c82d871371..2f8334c1ef5f4 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -16,7 +16,7 @@
#include <linux/kfifo.h>
#include <linux/err.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/omap-mailbox.h>
diff --git a/drivers/mailbox/platform_mhu.c b/drivers/mailbox/platform_mhu.c
index a5922ac0b0bfd..54161303a36b6 100644
--- a/drivers/mailbox/platform_mhu.c
+++ b/drivers/mailbox/platform_mhu.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mailbox_controller.h>
diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
index e0e9ba8f89993..99f049f76f0c9 100644
--- a/drivers/mailbox/rockchip-mailbox.c
+++ b/drivers/mailbox/rockchip-mailbox.c
@@ -8,8 +8,8 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mailbox_controller.h>
+#include <linux/of.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#define MAILBOX_A2B_INTEN 0x00
diff --git a/drivers/mailbox/sprd-mailbox.c b/drivers/mailbox/sprd-mailbox.c
index 2a43fb375bcb9..109ff60c4ac74 100644
--- a/drivers/mailbox/sprd-mailbox.c
+++ b/drivers/mailbox/sprd-mailbox.c
@@ -11,7 +11,7 @@
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c
index 15d538fe2113b..4ad3653f38666 100644
--- a/drivers/mailbox/stm32-ipcc.c
+++ b/drivers/mailbox/stm32-ipcc.c
@@ -11,6 +11,7 @@
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
index e12cd1a621554..96d034992aaf3 100644
--- a/drivers/mailbox/tegra-hsp.c
+++ b/drivers/mailbox/tegra-hsp.c
@@ -8,7 +8,6 @@
#include <linux/io.h>
#include <linux/mailbox_controller.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 6a48b832950db..90f248ef2a1fc 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -16,8 +16,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
/* IPI agent ID any */
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0875/1887] mailbox: zynqmp-ipi: fix an Excess struct member kernel-doc warning
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (873 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0874/1887] mailbox: Explicitly include correct DT includes Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0876/1887] mailbox: zynqmp: Move of_match structure closer to usage Greg Kroah-Hartman
` (123 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Randy Dunlap, kernel test robot,
linux-arm-kernel, Michal Simek, Jassi Brar, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <rdunlap@infradead.org>
[ Upstream commit b3734a8291ad7fd61e5a51cc540e414bcfbdc0cf ]
kernel test robot reports 2 Excess struct member warnings:
zynqmp-ipi-mailbox.c:92: warning: Excess struct member 'irq' description in 'zynqmp_ipi_mbox'
zynqmp-ipi-mailbox.c:112: warning: Excess struct member 'ipi_mboxes' description in 'zynqmp_ipi_pdata'
The second one is a false positive that is caused by the
__counted_by() attribute. Kees has posted a patch for that, so just
fix the first one.
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202312150705.glrQ4ypv-lkp@intel.com/
Cc: linux-arm-kernel@lists.infradead.org
Reviewed-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mailbox/zynqmp-ipi-mailbox.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 90f248ef2a1fc..c3953abe74b8e 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -81,7 +81,6 @@ struct zynqmp_ipi_mchan {
* @remote_id: remote IPI agent ID
* @mbox: mailbox Controller
* @mchans: array for channels, tx channel and rx channel.
- * @irq: IPI agent interrupt ID
*/
struct zynqmp_ipi_mbox {
struct zynqmp_ipi_pdata *pdata;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0876/1887] mailbox: zynqmp: Move of_match structure closer to usage
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (874 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0875/1887] mailbox: zynqmp-ipi: fix an Excess struct member kernel-doc warning Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0877/1887] mailbox: zynqmp: Move buffered IPI setup to of_match selected routine Greg Kroah-Hartman
` (122 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Levinsky, Jassi Brar,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Levinsky <ben.levinsky@amd.com>
[ Upstream commit 6efb495826a905814e2aaa68dc756694686e864f ]
The of_match structure zynqmp_ipi_of_match is now adjacent to where it
used in the zynqmp_ipi_driver structure for readability.
Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mailbox/zynqmp-ipi-mailbox.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index c3953abe74b8e..6a523759efa8b 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -415,12 +415,6 @@ static struct mbox_chan *zynqmp_ipi_of_xlate(struct mbox_controller *mbox,
return chan;
}
-static const struct of_device_id zynqmp_ipi_of_match[] = {
- { .compatible = "xlnx,zynqmp-ipi-mailbox" },
- {},
-};
-MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);
-
/**
* zynqmp_ipi_mbox_get_buf_res - Get buffer resource from the IPI dev node
*
@@ -694,6 +688,12 @@ static int zynqmp_ipi_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id zynqmp_ipi_of_match[] = {
+ { .compatible = "xlnx,zynqmp-ipi-mailbox" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);
+
static struct platform_driver zynqmp_ipi_driver = {
.probe = zynqmp_ipi_probe,
.remove = zynqmp_ipi_remove,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0877/1887] mailbox: zynqmp: Move buffered IPI setup to of_match selected routine
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (875 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0876/1887] mailbox: zynqmp: Move of_match structure closer to usage Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0878/1887] mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop Greg Kroah-Hartman
` (121 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Levinsky, Jassi Brar,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Levinsky <ben.levinsky@amd.com>
[ Upstream commit 41bcf30100c521c73f0fcf05c3dc31967e6408be ]
Move routine that initializes the mailboxes for send and receive to
a function pointer that is set based on compatible string.
Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
Stable-dep-of: 0aead8197fc1 ("mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mailbox/zynqmp-ipi-mailbox.c | 122 +++++++++++++++++++--------
1 file changed, 87 insertions(+), 35 deletions(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 6a523759efa8b..b3428c714e2f6 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -72,6 +72,10 @@ struct zynqmp_ipi_mchan {
unsigned int chan_type;
};
+struct zynqmp_ipi_mbox;
+
+typedef int (*setup_ipi_fn)(struct zynqmp_ipi_mbox *ipi_mbox, struct device_node *node);
+
/**
* struct zynqmp_ipi_mbox - Description of a ZynqMP IPI mailbox
* platform data.
@@ -81,6 +85,7 @@ struct zynqmp_ipi_mchan {
* @remote_id: remote IPI agent ID
* @mbox: mailbox Controller
* @mchans: array for channels, tx channel and rx channel.
+ * @setup_ipi_fn: Function Pointer to set up IPI Channels
*/
struct zynqmp_ipi_mbox {
struct zynqmp_ipi_pdata *pdata;
@@ -88,6 +93,7 @@ struct zynqmp_ipi_mbox {
u32 remote_id;
struct mbox_controller mbox;
struct zynqmp_ipi_mchan mchans[2];
+ setup_ipi_fn setup_ipi_fn;
};
/**
@@ -464,12 +470,9 @@ static void zynqmp_ipi_mbox_dev_release(struct device *dev)
static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
struct device_node *node)
{
- struct zynqmp_ipi_mchan *mchan;
struct mbox_chan *chans;
struct mbox_controller *mbox;
- struct resource res;
struct device *dev, *mdev;
- const char *name;
int ret;
dev = ipi_mbox->pdata->dev;
@@ -489,6 +492,73 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
}
mdev = &ipi_mbox->dev;
+ /* Get the IPI remote agent ID */
+ ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
+ if (ret < 0) {
+ dev_err(dev, "No IPI remote ID is specified.\n");
+ return ret;
+ }
+
+ ret = ipi_mbox->setup_ipi_fn(ipi_mbox, node);
+ if (ret) {
+ dev_err(dev, "Failed to set up IPI Buffers.\n");
+ return ret;
+ }
+
+ mbox = &ipi_mbox->mbox;
+ mbox->dev = mdev;
+ mbox->ops = &zynqmp_ipi_chan_ops;
+ mbox->num_chans = 2;
+ mbox->txdone_irq = false;
+ mbox->txdone_poll = true;
+ mbox->txpoll_period = 5;
+ mbox->of_xlate = zynqmp_ipi_of_xlate;
+ chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
+ if (!chans)
+ return -ENOMEM;
+ mbox->chans = chans;
+ chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
+ chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
+ ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
+ ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
+ ret = devm_mbox_controller_register(mdev, mbox);
+ if (ret)
+ dev_err(mdev,
+ "Failed to register mbox_controller(%d)\n", ret);
+ else
+ dev_info(mdev,
+ "Registered ZynqMP IPI mbox with TX/RX channels.\n");
+ return ret;
+}
+
+/**
+ * zynqmp_ipi_setup - set up IPI Buffers for classic flow
+ *
+ * @ipi_mbox: pointer to IPI mailbox private data structure
+ * @node: IPI mailbox device node
+ *
+ * This will be used to set up IPI Buffers for ZynqMP SOC if user
+ * wishes to use classic driver usage model on new SOC's with only
+ * buffered IPIs.
+ *
+ * Note that bufferless IPIs and mixed usage of buffered and bufferless
+ * IPIs are not supported with this flow.
+ *
+ * This will be invoked with compatible string "xlnx,zynqmp-ipi-mailbox".
+ *
+ * Return: 0 for success, negative value for failure
+ */
+static int zynqmp_ipi_setup(struct zynqmp_ipi_mbox *ipi_mbox,
+ struct device_node *node)
+{
+ struct zynqmp_ipi_mchan *mchan;
+ struct device *mdev;
+ struct resource res;
+ const char *name;
+ int ret;
+
+ mdev = &ipi_mbox->dev;
+
mchan = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
name = "local_request_region";
ret = zynqmp_ipi_mbox_get_buf_res(node, name, &res);
@@ -563,37 +633,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
if (!mchan->rx_buf)
return -ENOMEM;
- /* Get the IPI remote agent ID */
- ret = of_property_read_u32(node, "xlnx,ipi-id", &ipi_mbox->remote_id);
- if (ret < 0) {
- dev_err(dev, "No IPI remote ID is specified.\n");
- return ret;
- }
-
- mbox = &ipi_mbox->mbox;
- mbox->dev = mdev;
- mbox->ops = &zynqmp_ipi_chan_ops;
- mbox->num_chans = 2;
- mbox->txdone_irq = false;
- mbox->txdone_poll = true;
- mbox->txpoll_period = 5;
- mbox->of_xlate = zynqmp_ipi_of_xlate;
- chans = devm_kzalloc(mdev, 2 * sizeof(*chans), GFP_KERNEL);
- if (!chans)
- return -ENOMEM;
- mbox->chans = chans;
- chans[IPI_MB_CHNL_TX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_TX];
- chans[IPI_MB_CHNL_RX].con_priv = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
- ipi_mbox->mchans[IPI_MB_CHNL_TX].chan_type = IPI_MB_CHNL_TX;
- ipi_mbox->mchans[IPI_MB_CHNL_RX].chan_type = IPI_MB_CHNL_RX;
- ret = devm_mbox_controller_register(mdev, mbox);
- if (ret)
- dev_err(mdev,
- "Failed to register mbox_controller(%d)\n", ret);
- else
- dev_info(mdev,
- "Registered ZynqMP IPI mbox with TX/RX channels.\n");
- return ret;
+ return 0;
}
/**
@@ -621,6 +661,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
struct zynqmp_ipi_pdata *pdata;
struct zynqmp_ipi_mbox *mbox;
int num_mboxes, ret = -EINVAL;
+ setup_ipi_fn ipi_fn;
num_mboxes = of_get_available_child_count(np);
if (num_mboxes == 0) {
@@ -641,9 +682,18 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
return ret;
}
+ ipi_fn = (setup_ipi_fn)device_get_match_data(&pdev->dev);
+ if (!ipi_fn) {
+ dev_err(dev,
+ "Mbox Compatible String is missing IPI Setup fn.\n");
+ return -ENODEV;
+ }
+
pdata->num_mboxes = num_mboxes;
mbox = pdata->ipi_mboxes;
+ mbox->setup_ipi_fn = ipi_fn;
+
for_each_available_child_of_node(np, nc) {
mbox->pdata = pdata;
ret = zynqmp_ipi_mbox_probe(mbox, nc);
@@ -689,7 +739,9 @@ static int zynqmp_ipi_remove(struct platform_device *pdev)
}
static const struct of_device_id zynqmp_ipi_of_match[] = {
- { .compatible = "xlnx,zynqmp-ipi-mailbox" },
+ { .compatible = "xlnx,zynqmp-ipi-mailbox",
+ .data = &zynqmp_ipi_setup,
+ },
{},
};
MODULE_DEVICE_TABLE(of, zynqmp_ipi_of_match);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0878/1887] mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (876 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0877/1887] mailbox: zynqmp: Move buffered IPI setup to of_match selected routine Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0879/1887] cifs: client: fix memory leak in smb3_fs_context_parse_param Greg Kroah-Hartman
` (120 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harini T, Peng Fan, Jassi Brar,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harini T <harini.t@amd.com>
[ Upstream commit 0aead8197fc1a85b0a89646e418feb49a564b029 ]
The cleanup loop was starting at the wrong array index, causing
out-of-bounds access.
Start the loop at the correct index for zero-indexed arrays to prevent
accessing memory beyond the allocated array bounds.
Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller")
Signed-off-by: Harini T <harini.t@amd.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mailbox/zynqmp-ipi-mailbox.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index b3428c714e2f6..c89989c234111 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -646,7 +646,7 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
struct zynqmp_ipi_mbox *ipi_mbox;
int i;
- i = pdata->num_mboxes;
+ i = pdata->num_mboxes - 1;
for (; i >= 0; i--) {
ipi_mbox = &pdata->ipi_mboxes[i];
if (device_is_registered(&ipi_mbox->dev))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0879/1887] cifs: client: fix memory leak in smb3_fs_context_parse_param
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (877 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0878/1887] mailbox: zynqmp-ipi: Fix out-of-bounds access in mailbox cleanup loop Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0880/1887] drm/amdgpu: Show vram vendor only if available Greg Kroah-Hartman
` (119 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+72afd4c236e6bc3f4bac,
Paulo Alcantara (Red Hat), Edward Adam Davis, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit e8c73eb7db0a498cd4b22d2819e6ab1a6f506bd6 ]
The user calls fsconfig twice, but when the program exits, free() only
frees ctx->source for the second fsconfig, not the first.
Regarding fc->source, there is no code in the fs context related to its
memory reclamation.
To fix this memory leak, release the source memory corresponding to ctx
or fc before each parsing.
syzbot reported:
BUG: memory leak
unreferenced object 0xffff888128afa360 (size 96):
backtrace (crc 79c9c7ba):
kstrdup+0x3c/0x80 mm/util.c:84
smb3_fs_context_parse_param+0x229b/0x36c0 fs/smb/client/fs_context.c:1444
BUG: memory leak
unreferenced object 0xffff888112c7d900 (size 96):
backtrace (crc 79c9c7ba):
smb3_fs_context_fullpath+0x70/0x1b0 fs/smb/client/fs_context.c:629
smb3_fs_context_parse_param+0x2266/0x36c0 fs/smb/client/fs_context.c:1438
Reported-by: syzbot+72afd4c236e6bc3f4bac@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=72afd4c236e6bc3f4bac
Cc: stable@vger.kernel.org
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/fs_context.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 35f2c94aafd14..abd4f8587fd0f 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1167,11 +1167,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
cifs_errorf(fc, "Unknown error parsing devname\n");
goto cifs_parse_mount_err;
}
+ kfree(ctx->source);
ctx->source = kstrdup(param->string, GFP_KERNEL);
if (ctx->source == NULL) {
cifs_errorf(fc, "OOM when copying UNC string\n");
goto cifs_parse_mount_err;
}
+ kfree(fc->source);
fc->source = kstrdup(param->string, GFP_KERNEL);
if (fc->source == NULL) {
cifs_errorf(fc, "OOM when copying UNC string\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0880/1887] drm/amdgpu: Show vram vendor only if available
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (878 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0879/1887] cifs: client: fix memory leak in smb3_fs_context_parse_param Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0881/1887] drm/amdgpu: hide VRAM sysfs attributes on GPUs without VRAM Greg Kroah-Hartman
` (118 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lijo Lazar, Hawking Zhang,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <lijo.lazar@amd.com>
[ Upstream commit 89a7c0bd74918f723c94c10452265e25063cba9b ]
Ony if vram vendor info is available, show in sysfs.
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org # 6.7.x
Stable-dep-of: 33cc891b56b9 ("drm/amdgpu: hide VRAM sysfs attributes on GPUs without VRAM")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 24867e96b5209..aef76467c409f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -212,8 +212,23 @@ static struct attribute *amdgpu_vram_mgr_attributes[] = {
NULL
};
+static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct amdgpu_device *adev = drm_to_adev(ddev);
+
+ if (attr == &dev_attr_mem_info_vram_vendor.attr &&
+ !adev->gmc.vram_vendor)
+ return 0;
+
+ return attr->mode;
+}
+
const struct attribute_group amdgpu_vram_mgr_attr_group = {
- .attrs = amdgpu_vram_mgr_attributes
+ .attrs = amdgpu_vram_mgr_attributes,
+ .is_visible = amdgpu_vram_attrs_is_visible
};
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0881/1887] drm/amdgpu: hide VRAM sysfs attributes on GPUs without VRAM
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (879 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0880/1887] drm/amdgpu: Show vram vendor only if available Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0882/1887] accel/habanalabs: support mapping cb with vmalloc-backed coherent memory Greg Kroah-Hartman
` (117 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Mangesh Gadre,
Alex Deucher, Arunpravin Paneer Selvam, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <christian.koenig@amd.com>
[ Upstream commit 33cc891b56b93cad1a83263eaf2e417436f70c82 ]
Otherwise accessing them can cause a crash.
Signed-off-by: Christian König <christian.koenig@amd.com>
Tested-by: Mangesh Gadre <Mangesh.Gadre@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index aef76467c409f..4d8912345c38f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -223,6 +223,9 @@ static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj,
!adev->gmc.vram_vendor)
return 0;
+ if (!ttm_resource_manager_used(&adev->mman.vram_mgr.manager))
+ return 0;
+
return attr->mode;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0882/1887] accel/habanalabs: support mapping cb with vmalloc-backed coherent memory
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (880 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0881/1887] drm/amdgpu: hide VRAM sysfs attributes on GPUs without VRAM Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0883/1887] md/raid10: wait barrier before returning discard request with REQ_NOWAIT Greg Kroah-Hartman
` (116 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Moti Haimovski, Koby Elbaz,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Moti Haimovski <moti.haimovski@intel.com>
[ Upstream commit 513024d5a0e34fd34247043f1876b6138ca52847 ]
When IOMMU is enabled, dma_alloc_coherent() with GFP_USER may return
addresses from the vmalloc range. If such an address is mapped without
VM_MIXEDMAP, vm_insert_page() will trigger a BUG_ON due to the
VM_PFNMAP restriction.
Fix this by checking for vmalloc addresses and setting VM_MIXEDMAP
in the VMA before mapping. This ensures safe mapping and avoids kernel
crashes. The memory is still driver-allocated and cannot be accessed
directly by userspace.
Signed-off-by: Moti Haimovski <moti.haimovski@intel.com>
Reviewed-by: Koby Elbaz <koby.elbaz@intel.com>
Signed-off-by: Koby Elbaz <koby.elbaz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/habanalabs/gaudi/gaudi.c | 19 +++++++++++++++++++
drivers/misc/habanalabs/gaudi2/gaudi2.c | 7 +++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 92560414e8433..7224a4636b685 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -4239,10 +4239,29 @@ static int gaudi_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP |
VM_DONTCOPY | VM_NORESERVE;
+#ifdef _HAS_DMA_MMAP_COHERENT
+ /*
+ * If dma_alloc_coherent() returns a vmalloc address, set VM_MIXEDMAP
+ * so vm_insert_page() can handle it safely. Without this, the kernel
+ * may BUG_ON due to VM_PFNMAP.
+ */
+ if (is_vmalloc_addr(cpu_addr))
+ vm_flags_set(vma, VM_MIXEDMAP);
+
rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr,
(dma_addr - HOST_PHYS_BASE), size);
if (rc)
dev_err(hdev->dev, "dma_mmap_coherent error %d", rc);
+#else
+
+ rc = remap_pfn_range(vma, vma->vm_start,
+ virt_to_phys(cpu_addr) >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+ if (rc)
+ dev_err(hdev->dev, "remap_pfn_range error %d", rc);
+
+ #endif
+
return rc;
}
diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c
index 65e6cae6100a4..e043f4d2343b2 100644
--- a/drivers/misc/habanalabs/gaudi2/gaudi2.c
+++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c
@@ -5603,6 +5603,13 @@ static int gaudi2_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
VM_DONTCOPY | VM_NORESERVE;
#ifdef _HAS_DMA_MMAP_COHERENT
+ /*
+ * If dma_alloc_coherent() returns a vmalloc address, set VM_MIXEDMAP
+ * so vm_insert_page() can handle it safely. Without this, the kernel
+ * may BUG_ON due to VM_PFNMAP.
+ */
+ if (is_vmalloc_addr(cpu_addr))
+ vm_flags_set(vma, VM_MIXEDMAP);
rc = dma_mmap_coherent(hdev->dev, vma, cpu_addr, dma_addr, size);
if (rc)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0883/1887] md/raid10: wait barrier before returning discard request with REQ_NOWAIT
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (881 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0882/1887] accel/habanalabs: support mapping cb with vmalloc-backed coherent memory Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0884/1887] smb: client: fix potential UAF in smb2_close_cached_fid() Greg Kroah-Hartman
` (115 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xiao Ni, Coly Li, Yu Kuai,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiao Ni <xni@redhat.com>
[ Upstream commit 3db4404435397a345431b45f57876a3df133f3b4 ]
raid10_handle_discard should wait barrier before returning a discard bio
which has REQ_NOWAIT. And there is no need to print warning calltrace
if a discard bio has REQ_NOWAIT flag. Quality engineer usually checks
dmesg and reports error if dmesg has warning/error calltrace.
Fixes: c9aa889b035f ("md: raid10 add nowait support")
Signed-off-by: Xiao Ni <xni@redhat.com>
Acked-by: Coly Li <colyli@kernel.org>
Link: https://lore.kernel.org/linux-raid/20250306094938.48952-1-xni@redhat.com
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/md/raid10.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 508b461eabe88..82562c49a14e2 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1676,11 +1676,10 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
return -EAGAIN;
- if (WARN_ON_ONCE(bio->bi_opf & REQ_NOWAIT)) {
+ if (!wait_barrier(conf, bio->bi_opf & REQ_NOWAIT)) {
bio_wouldblock_error(bio);
return 0;
}
- wait_barrier(conf, false);
/*
* Check reshape again to avoid reshape happens after checking
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0884/1887] smb: client: fix potential UAF in smb2_close_cached_fid()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (882 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0883/1887] md/raid10: wait barrier before returning discard request with REQ_NOWAIT Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0885/1887] net: stmmac: Prevent DSA tags from breaking COE Greg Kroah-Hartman
` (114 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jay Shin, Paulo Alcantara (Red Hat),
Henrique Carvalho, Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henrique Carvalho <henrique.carvalho@suse.com>
[ Upstream commit 734e99623c5b65bf2c03e35978a0b980ebc3c2f8 ]
find_or_create_cached_dir() could grab a new reference after kref_put()
had seen the refcount drop to zero but before cfid_list_lock is acquired
in smb2_close_cached_fid(), leading to use-after-free.
Switch to kref_put_lock() so cfid_release() is called with
cfid_list_lock held, closing that gap.
Fixes: ebe98f1447bb ("cifs: enable caching of directories for which a lease is held")
Cc: stable@vger.kernel.org
Reported-by: Jay Shin <jaeshin@redhat.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cached_dir.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index baca533953fd1..3ff56321b7a1e 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -354,7 +354,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
*/
cfid->has_lease = false;
spin_unlock(&cfids->cfid_list_lock);
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ close_cached_dir(cfid);
goto out;
}
spin_unlock(&cfids->cfid_list_lock);
@@ -399,12 +399,14 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
static void
smb2_close_cached_fid(struct kref *ref)
+__releases(&cfid->cfids->cfid_list_lock)
{
struct cached_fid *cfid = container_of(ref, struct cached_fid,
refcount);
int rc;
- spin_lock(&cfid->cfids->cfid_list_lock);
+ lockdep_assert_held(&cfid->cfids->cfid_list_lock);
+
if (cfid->on_list) {
list_del(&cfid->entry);
cfid->on_list = false;
@@ -439,7 +441,7 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
spin_lock(&cfid->cfids->cfid_list_lock);
if (cfid->has_lease) {
cfid->has_lease = false;
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ close_cached_dir(cfid);
}
spin_unlock(&cfid->cfids->cfid_list_lock);
close_cached_dir(cfid);
@@ -448,7 +450,7 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
void close_cached_dir(struct cached_fid *cfid)
{
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock);
}
/*
@@ -510,10 +512,10 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
spin_lock(&cfids->cfid_list_lock);
cfid->has_lease = false;
spin_unlock(&cfids->cfid_list_lock);
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ close_cached_dir(cfid);
}
/* Drop the extra reference opened above*/
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ close_cached_dir(cfid);
}
}
@@ -526,7 +528,7 @@ smb2_cached_lease_break(struct work_struct *work)
spin_lock(&cfid->cfids->cfid_list_lock);
cfid->has_lease = false;
spin_unlock(&cfid->cfids->cfid_list_lock);
- kref_put(&cfid->refcount, smb2_close_cached_fid);
+ close_cached_dir(cfid);
}
int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0885/1887] net: stmmac: Prevent DSA tags from breaking COE
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (883 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0884/1887] smb: client: fix potential UAF in smb2_close_cached_fid() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0886/1887] net: stmmac: Correctly handle Rx checksum offload errors Greg Kroah-Hartman
` (113 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Tresidder, Romain Gantois,
Vladimir Oltean, Linus Walleij, Florian Fainelli, David S. Miller,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Romain Gantois <romain.gantois@bootlin.com>
[ Upstream commit c2945c435c999c63e47f337bc7c13c98c21d0bcc ]
Some DSA tagging protocols change the EtherType field in the MAC header
e.g. DSA_TAG_PROTO_(DSA/EDSA/BRCM/MTK/RTL4C_A/SJA1105). On TX these tagged
frames are ignored by the checksum offload engine and IP header checker of
some stmmac cores.
On RX, the stmmac driver wrongly assumes that checksums have been computed
for these tagged packets, and sets CHECKSUM_UNNECESSARY.
Add an additional check in the stmmac TX and RX hotpaths so that COE is
deactivated for packets with ethertypes that will not trigger the COE and
IP header checks.
Fixes: 6b2c6e4a938f ("net: stmmac: propagate feature flags to vlan")
Cc: <stable@vger.kernel.org>
Reported-by: Richard Tresidder <rtresidd@electromag.com.au>
Link: https://lore.kernel.org/netdev/e5c6c75f-2dfa-4e50-a1fb-6bf4cdb617c2@electromag.com.au/
Reported-by: Romain Gantois <romain.gantois@bootlin.com>
Link: https://lore.kernel.org/netdev/c57283ed-6b9b-b0e6-ee12-5655c1c54495@bootlin.com/
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: ee0aace5f844 ("net: stmmac: Correctly handle Rx checksum offload errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 37 ++++++++++++++++++-
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index f72367ecdb879..e641739efe29c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4335,6 +4335,28 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
+/**
+ * stmmac_has_ip_ethertype() - Check if packet has IP ethertype
+ * @skb: socket buffer to check
+ *
+ * Check if a packet has an ethertype that will trigger the IP header checks
+ * and IP/TCP checksum engine of the stmmac core.
+ *
+ * Return: true if the ethertype can trigger the checksum engine, false
+ * otherwise
+ */
+static bool stmmac_has_ip_ethertype(struct sk_buff *skb)
+{
+ int depth = 0;
+ __be16 proto;
+
+ proto = __vlan_get_protocol(skb, eth_header_parse_protocol(skb),
+ &depth);
+
+ return (depth <= ETH_HLEN) &&
+ (proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6));
+}
+
/**
* stmmac_xmit - Tx entry point of the driver
* @skb : the socket buffer
@@ -4395,6 +4417,17 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
WARN_ON(tx_q->tx_skbuff[first_entry]);
csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
+ /* Packets that won't trigger the COE e.g. most DSA-tagged packets will
+ * have to be checksummed in software.
+ */
+ if (csum_insertion && !stmmac_has_ip_ethertype(skb)) {
+ if (unlikely(skb_checksum_help(skb)))
+ goto dma_map_err;
+ csum_insertion = !csum_insertion;
+ /* skb_checksum_help() may have linearized the skb */
+ nopaged_len = skb_headlen(skb);
+ nfrags = skb_shinfo(skb)->nr_frags;
+ }
if (likely(priv->extend_desc))
desc = (struct dma_desc *)(tx_q->dma_etx + entry);
@@ -4958,7 +4991,7 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
stmmac_rx_vlan(priv->dev, skb);
skb->protocol = eth_type_trans(skb, priv->dev);
- if (unlikely(!coe))
+ if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -5458,7 +5491,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_rx_vlan(priv->dev, skb);
skb->protocol = eth_type_trans(skb, priv->dev);
- if (unlikely(!coe))
+ if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0886/1887] net: stmmac: Correctly handle Rx checksum offload errors
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (884 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0885/1887] net: stmmac: Prevent DSA tags from breaking COE Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0887/1887] ASoC: Intel: avs: Do not share the name pointer between components Greg Kroah-Hartman
` (112 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleksij Rempel, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <o.rempel@pengutronix.de>
[ Upstream commit ee0aace5f844ef59335148875d05bec8764e71e8 ]
The stmmac_rx function would previously set skb->ip_summed to
CHECKSUM_UNNECESSARY if hardware checksum offload (CoE) was enabled
and the packet was of a known IP ethertype.
However, this logic failed to check if the hardware had actually
reported a checksum error. The hardware status, indicating a header or
payload checksum failure, was being ignored at this stage. This could
cause corrupt packets to be passed up the network stack as valid.
This patch corrects the logic by checking the `csum_none` status flag,
which is set when the hardware reports a checksum error. If this flag
is set, skb->ip_summed is now correctly set to CHECKSUM_NONE,
ensuring the kernel's network stack will perform its own validation and
properly handle the corrupt packet.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Link: https://patch.msgid.link/20250818090217.2789521-2-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e641739efe29c..e75a05bd5fd0d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5491,7 +5491,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_rx_vlan(priv->dev, skb);
skb->protocol = eth_type_trans(skb, priv->dev);
- if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
+ if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb) ||
+ (status & csum_none))
skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0887/1887] ASoC: Intel: avs: Do not share the name pointer between components
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (885 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0886/1887] net: stmmac: Correctly handle Rx checksum offload errors Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0888/1887] ima: dont clear IMA_DIGSIG flag when setting or removing non-IMA xattr Greg Kroah-Hartman
` (111 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amadeusz Sławiński,
Cezary Rojewski, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit 4dee5c1cc439b0d5ef87f741518268ad6a95b23d ]
By sharing 'name' directly, tearing down components may lead to
use-after-free errors. Duplicate the name to avoid that.
At the same time, update the order of operations - since commit
cee28113db17 ("ASoC: dmaengine_pcm: Allow passing component name via
config") the framework does not override component->name if set before
invoking the initializer.
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20250818104126.526442-4-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/pcm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 9d3c0ea99a298..b61f753a1c60a 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -879,7 +879,9 @@ static int avs_soc_component_register(struct device *dev, const char *name,
return ret;
/* force name change after ASoC is done with its init */
- acomp->base.name = name;
+ acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL);
+ if (!acomp->base.name)
+ return -ENOMEM;
INIT_LIST_HEAD(&acomp->node);
return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0888/1887] ima: dont clear IMA_DIGSIG flag when setting or removing non-IMA xattr
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (886 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0887/1887] ASoC: Intel: avs: Do not share the name pointer between components Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0889/1887] tcp: use dst_dev_rcu() in tcp_fastopen_active_disable_ofo_check() Greg Kroah-Hartman
` (110 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Coiby Xu, Mimi Zohar, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coiby Xu <coxu@redhat.com>
[ Upstream commit 88b4cbcf6b041ae0f2fc8a34554a5b6a83a2b7cd ]
Currently when both IMA and EVM are in fix mode, the IMA signature will
be reset to IMA hash if a program first stores IMA signature in
security.ima and then writes/removes some other security xattr for the
file.
For example, on Fedora, after booting the kernel with "ima_appraise=fix
evm=fix ima_policy=appraise_tcb" and installing rpm-plugin-ima,
installing/reinstalling a package will not make good reference IMA
signature generated. Instead IMA hash is generated,
# getfattr -m - -d -e hex /usr/bin/bash
# file: usr/bin/bash
security.ima=0x0404...
This happens because when setting security.selinux, the IMA_DIGSIG flag
that had been set early was cleared. As a result, IMA hash is generated
when the file is closed.
Similarly, IMA signature can be cleared on file close after removing
security xattr like security.evm or setting/removing ACL.
Prevent replacing the IMA file signature with a file hash, by preventing
the IMA_DIGSIG flag from being reset.
Here's a minimal C reproducer which sets security.selinux as the last
step which can also replaced by removing security.evm or setting ACL,
#include <stdio.h>
#include <sys/xattr.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main() {
const char* file_path = "/usr/sbin/test_binary";
const char* hex_string = "030204d33204490066306402304";
int length = strlen(hex_string);
char* ima_attr_value;
int fd;
fd = open(file_path, O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd == -1) {
perror("Error opening file");
return 1;
}
ima_attr_value = (char*)malloc(length / 2 );
for (int i = 0, j = 0; i < length; i += 2, j++) {
sscanf(hex_string + i, "%2hhx", &ima_attr_value[j]);
}
if (fsetxattr(fd, "security.ima", ima_attr_value, length/2, 0) == -1) {
perror("Error setting extended attribute");
close(fd);
return 1;
}
const char* selinux_value= "system_u:object_r:bin_t:s0";
if (fsetxattr(fd, "security.selinux", selinux_value, strlen(selinux_value), 0) == -1) {
perror("Error setting extended attribute");
close(fd);
return 1;
}
close(fd);
return 0;
}
Signed-off-by: Coiby Xu <coxu@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/integrity/ima/ima_appraise.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index f9d0bd4d3613b..c76f5030fb55b 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -676,6 +676,15 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
return 0;
}
+/*
+ * ima_reset_appraise_flags - reset ima_iint_cache flags
+ *
+ * @digsig: whether to clear/set IMA_DIGSIG flag, tristate values
+ * 0: clear IMA_DIGSIG
+ * 1: set IMA_DIGSIG
+ * -1: don't change IMA_DIGSIG
+ *
+ */
static void ima_reset_appraise_flags(struct inode *inode, int digsig)
{
struct integrity_iint_cache *iint;
@@ -688,9 +697,9 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
return;
iint->measured_pcrs = 0;
set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
- if (digsig)
+ if (digsig == 1)
set_bit(IMA_DIGSIG, &iint->atomic_flags);
- else
+ else if (digsig == 0)
clear_bit(IMA_DIGSIG, &iint->atomic_flags);
}
@@ -777,6 +786,8 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
} else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
+ } else {
+ digsig = -1;
}
if (result == 1 || evm_revalidate_status(xattr_name)) {
ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
@@ -788,11 +799,13 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
{
- int result;
+ int result, digsig = -1;
result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
if (result == 1 || evm_revalidate_status(xattr_name)) {
- ima_reset_appraise_flags(d_backing_inode(dentry), 0);
+ if (!strcmp(xattr_name, XATTR_NAME_IMA))
+ digsig = 0;
+ ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
if (result == 1)
result = 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0889/1887] tcp: use dst_dev_rcu() in tcp_fastopen_active_disable_ofo_check()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (887 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0888/1887] ima: dont clear IMA_DIGSIG flag when setting or removing non-IMA xattr Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0890/1887] mlx5: Fix default values in create CQ Greg Kroah-Hartman
` (109 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, David Ahern,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit b62a59c18b692f892dcb8109c1c2e653b2abc95c ]
Use RCU to avoid a pair of atomic operations and a potential
UAF on dst_dev()->flags.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/tcp_fastopen.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 156685b4ae68a..bb40b42f13d7b 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -575,11 +575,12 @@ void tcp_fastopen_active_disable_ofo_check(struct sock *sk)
}
} else if (tp->syn_fastopen_ch &&
atomic_read(&sock_net(sk)->ipv4.tfo_active_disable_times)) {
- dst = sk_dst_get(sk);
- dev = dst ? dst_dev(dst) : NULL;
+ rcu_read_lock();
+ dst = __sk_dst_get(sk);
+ dev = dst ? dst_dev_rcu(dst) : NULL;
if (!(dev && (dev->flags & IFF_LOOPBACK)))
atomic_set(&sock_net(sk)->ipv4.tfo_active_disable_times, 0);
- dst_release(dst);
+ rcu_read_unlock();
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0890/1887] mlx5: Fix default values in create CQ
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (888 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0889/1887] tcp: use dst_dev_rcu() in tcp_fastopen_active_disable_ofo_check() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0891/1887] cifs: fix memory leak in smb3_fs_context_parse_param error path Greg Kroah-Hartman
` (108 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Akiva Goldberger, Moshe Shemesh,
Tariq Toukan, Leon Romanovsky, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akiva Goldberger <agoldberger@nvidia.com>
[ Upstream commit e5eba42f01340f73888dfe560be2806057c25913 ]
Currently, CQs without a completion function are assigned the
mlx5_add_cq_to_tasklet function by default. This is problematic since
only user CQs created through the mlx5_ib driver are intended to use
this function.
Additionally, all CQs that will use doorbells instead of polling for
completions must call mlx5_cq_arm. However, the default CQ creation flow
leaves a valid value in the CQ's arm_db field, allowing FW to send
interrupts to polling-only CQs in certain corner cases.
These two factors would allow a polling-only kernel CQ to be triggered
by an EQ interrupt and call a completion function intended only for user
CQs, causing a null pointer exception.
Some areas in the driver have prevented this issue with one-off fixes
but did not address the root cause.
This patch fixes the described issue by adding defaults to the create CQ
flow. It adds a default dummy completion function to protect against
null pointer exceptions, and it sets an invalid command sequence number
by default in kernel CQs to prevent the FW from sending an interrupt to
the CQ until it is armed. User CQs are responsible for their own
initialization values.
Callers of mlx5_core_create_cq are responsible for changing the
completion function and arming the CQ per their needs.
Fixes: cdd04f4d4d71 ("net/mlx5: Add support to create SQ and CQ for ASO")
Signed-off-by: Akiva Goldberger <agoldberger@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Acked-by: Leon Romanovsky <leon@kernel.org>
Link: https://patch.msgid.link/1762681743-1084694-1-git-send-email-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/mlx5/cq.c | 11 +++++---
drivers/net/ethernet/mellanox/mlx5/core/cq.c | 23 +++++++++++++--
.../net/ethernet/mellanox/mlx5/core/en_main.c | 1 -
.../ethernet/mellanox/mlx5/core/fpga/conn.c | 17 ++++++-----
.../mellanox/mlx5/core/steering/dr_send.c | 28 +++++--------------
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++--
include/linux/mlx5/cq.h | 1 +
7 files changed, 45 insertions(+), 42 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 886e9560e913e..b5c2e0e1d82b2 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -1009,15 +1009,18 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
if (cq->create_flags & IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN)
MLX5_SET(cqc, cqc, oi, 1);
+ if (udata) {
+ cq->mcq.comp = mlx5_add_cq_to_tasklet;
+ cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp;
+ } else {
+ cq->mcq.comp = mlx5_ib_cq_comp;
+ }
+
err = mlx5_core_create_cq(dev->mdev, &cq->mcq, cqb, inlen, out, sizeof(out));
if (err)
goto err_cqb;
mlx5_ib_dbg(dev, "cqn 0x%x\n", cq->mcq.cqn);
- if (udata)
- cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp;
- else
- cq->mcq.comp = mlx5_ib_cq_comp;
cq->mcq.event = mlx5_ib_cq_event;
INIT_LIST_HEAD(&cq->wc_list);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
index 4caa1b6f40ba4..d21c14bb3ecfc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
@@ -66,8 +66,8 @@ void mlx5_cq_tasklet_cb(struct tasklet_struct *t)
tasklet_schedule(&ctx->task);
}
-static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
- struct mlx5_eqe *eqe)
+void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
+ struct mlx5_eqe *eqe)
{
unsigned long flags;
struct mlx5_eq_tasklet *tasklet_ctx = cq->tasklet_ctx.priv;
@@ -84,7 +84,15 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
}
spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
}
+EXPORT_SYMBOL(mlx5_add_cq_to_tasklet);
+static void mlx5_core_cq_dummy_cb(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe)
+{
+ mlx5_core_err(cq->eq->core.dev,
+ "CQ default completion callback, CQ #%u\n", cq->cqn);
+}
+
+#define MLX5_CQ_INIT_CMD_SN cpu_to_be32(2 << 28)
/* Callers must verify outbox status in case of err */
int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
u32 *in, int inlen, u32 *out, int outlen)
@@ -110,10 +118,19 @@ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
cq->arm_sn = 0;
cq->eq = eq;
cq->uid = MLX5_GET(create_cq_in, in, uid);
+
+ /* Kernel CQs must set the arm_db address prior to calling
+ * this function, allowing for the proper value to be
+ * initialized. User CQs are responsible for their own
+ * initialization since they do not use the arm_db field.
+ */
+ if (cq->arm_db)
+ *cq->arm_db = MLX5_CQ_INIT_CMD_SN;
+
refcount_set(&cq->refcount, 1);
init_completion(&cq->free);
if (!cq->comp)
- cq->comp = mlx5_add_cq_to_tasklet;
+ cq->comp = mlx5_core_cq_dummy_cb;
/* assuming CQ will be deleted before the EQ */
cq->tasklet_ctx.priv = &eq->tasklet_ctx;
INIT_LIST_HEAD(&cq->tasklet_ctx.list);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index f05fe8074b755..6daaafc7ff9d6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1862,7 +1862,6 @@ static int mlx5e_alloc_cq_common(struct mlx5e_priv *priv,
mcq->set_ci_db = cq->wq_ctrl.db.db;
mcq->arm_db = cq->wq_ctrl.db.db + 1;
*mcq->set_ci_db = 0;
- *mcq->arm_db = 0;
mcq->vector = param->eq_ix;
mcq->comp = mlx5e_completion_event;
mcq->event = mlx5e_cq_error_event;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
index 12abe991583a8..23eadac8c79b6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
@@ -437,6 +437,14 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size)
cqe->op_own = MLX5_CQE_INVALID << 4 | MLX5_CQE_OWNER_MASK;
}
+ conn->cq.mcq.cqe_sz = 64;
+ conn->cq.mcq.set_ci_db = conn->cq.wq_ctrl.db.db;
+ conn->cq.mcq.arm_db = conn->cq.wq_ctrl.db.db + 1;
+ *conn->cq.mcq.set_ci_db = 0;
+ conn->cq.mcq.vector = 0;
+ conn->cq.mcq.comp = mlx5_fpga_conn_cq_complete;
+ conn->cq.mcq.uar = fdev->conn_res.uar;
+
inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
sizeof(u64) * conn->cq.wq_ctrl.buf.npages;
in = kvzalloc(inlen, GFP_KERNEL);
@@ -468,16 +476,7 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size)
if (err)
goto err_cqwq;
- conn->cq.mcq.cqe_sz = 64;
- conn->cq.mcq.set_ci_db = conn->cq.wq_ctrl.db.db;
- conn->cq.mcq.arm_db = conn->cq.wq_ctrl.db.db + 1;
- *conn->cq.mcq.set_ci_db = 0;
- *conn->cq.mcq.arm_db = 0;
- conn->cq.mcq.vector = 0;
- conn->cq.mcq.comp = mlx5_fpga_conn_cq_complete;
- conn->cq.mcq.uar = fdev->conn_res.uar;
tasklet_setup(&conn->cq.tasklet, mlx5_fpga_conn_cq_tasklet);
-
mlx5_fpga_dbg(fdev, "Created CQ #0x%x\n", conn->cq.mcq.cqn);
goto out;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
index ef19a66f52335..5a9fb24856ab9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
@@ -748,12 +748,6 @@ static int dr_prepare_qp_to_rts(struct mlx5dr_domain *dmn)
return 0;
}
-static void dr_cq_complete(struct mlx5_core_cq *mcq,
- struct mlx5_eqe *eqe)
-{
- pr_err("CQ completion CQ: #%u\n", mcq->cqn);
-}
-
static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
struct mlx5_uars_page *uar,
size_t ncqe)
@@ -789,6 +783,13 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
cqe->op_own = MLX5_CQE_INVALID << 4 | MLX5_CQE_OWNER_MASK;
}
+ cq->mcq.cqe_sz = 64;
+ cq->mcq.set_ci_db = cq->wq_ctrl.db.db;
+ cq->mcq.arm_db = cq->wq_ctrl.db.db + 1;
+ *cq->mcq.set_ci_db = 0;
+ cq->mcq.vector = 0;
+ cq->mcq.uar = uar;
+
inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
sizeof(u64) * cq->wq_ctrl.buf.npages;
in = kvzalloc(inlen, GFP_KERNEL);
@@ -813,27 +814,12 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev,
pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas);
mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas);
- cq->mcq.comp = dr_cq_complete;
-
err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out));
kvfree(in);
if (err)
goto err_cqwq;
- cq->mcq.cqe_sz = 64;
- cq->mcq.set_ci_db = cq->wq_ctrl.db.db;
- cq->mcq.arm_db = cq->wq_ctrl.db.db + 1;
- *cq->mcq.set_ci_db = 0;
-
- /* set no-zero value, in order to avoid the HW to run db-recovery on
- * CQ that used in polling mode.
- */
- *cq->mcq.arm_db = cpu_to_be32(2 << 28);
-
- cq->mcq.vector = 0;
- cq->mcq.uar = uar;
-
return cq;
err_cqwq:
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 74d295312466f..a599259af8632 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -594,6 +594,8 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
vcq->mcq.set_ci_db = vcq->db.db;
vcq->mcq.arm_db = vcq->db.db + 1;
vcq->mcq.cqe_sz = 64;
+ vcq->mcq.comp = mlx5_vdpa_cq_comp;
+ vcq->cqe = num_ent;
err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent);
if (err)
@@ -633,10 +635,6 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent)
if (err)
goto err_vec;
- vcq->mcq.comp = mlx5_vdpa_cq_comp;
- vcq->cqe = num_ent;
- vcq->mcq.set_ci_db = vcq->db.db;
- vcq->mcq.arm_db = vcq->db.db + 1;
mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index);
kfree(in);
return 0;
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index cb15308b5cb0b..804432fd0f271 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -183,6 +183,7 @@ static inline void mlx5_cq_put(struct mlx5_core_cq *cq)
complete(&cq->free);
}
+void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe);
int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
u32 *in, int inlen, u32 *out, int outlen);
int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0891/1887] cifs: fix memory leak in smb3_fs_context_parse_param error path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (889 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0890/1887] mlx5: Fix default values in create CQ Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0892/1887] scsi: ufs: ufs-qcom: Fix UFS OCP issue during UFS power down (PC=3) Greg Kroah-Hartman
` (107 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+87be6809ed9bf6d718e3,
David Howells, Shaurya Rane, Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
[ Upstream commit 7e4d9120cfa413dd34f4f434befc5dbe6c38b2e5 ]
Add proper cleanup of ctx->source and fc->source to the
cifs_parse_mount_err error handler. This ensures that memory allocated
for the source strings is correctly freed on all error paths, matching
the cleanup already performed in the success path by
smb3_cleanup_fs_context_contents().
Pointers are also set to NULL after freeing to prevent potential
double-free issues.
This change fixes a memory leak originally detected by syzbot. The
leak occurred when processing Opt_source mount options if an error
happened after ctx->source and fc->source were successfully
allocated but before the function completed.
The specific leak sequence was:
1. ctx->source = smb3_fs_context_fullpath(ctx, '/') allocates memory
2. fc->source = kstrdup(ctx->source, GFP_KERNEL) allocates more memory
3. A subsequent error jumps to cifs_parse_mount_err
4. The old error handler freed passwords but not the source strings,
causing the memory to leak.
This issue was not addressed by commit e8c73eb7db0a ("cifs: client:
fix memory leak in smb3_fs_context_parse_param"), which only fixed
leaks from repeated fsconfig() calls but not this error path.
Patch updated with minor change suggested by kernel test robot
Reported-by: syzbot+87be6809ed9bf6d718e3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=87be6809ed9bf6d718e3
Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/fs_context.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index abd4f8587fd0f..bd19aab1f3c6b 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1511,6 +1511,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
cifs_parse_mount_err:
kfree_sensitive(ctx->password);
ctx->password = NULL;
+ kfree(ctx->source);
+ ctx->source = NULL;
+ kfree(fc->source);
+ fc->source = NULL;
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0892/1887] scsi: ufs: ufs-qcom: Fix UFS OCP issue during UFS power down (PC=3)
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (890 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0891/1887] cifs: fix memory leak in smb3_fs_context_parse_param error path Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0893/1887] lan966x: Fix sleeping in atomic context Greg Kroah-Hartman
` (106 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nitin Rawat, Manivannan Sadhasivam,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
[ Upstream commit 5127be409c6c3815c4a7d8f6d88043e44f9b9543 ]
According to UFS specifications, the power-off sequence for a UFS device
includes:
- Sending an SSU command with Power_Condition=3 and await a response.
- Asserting RST_N low.
- Turning off REF_CLK.
- Turning off VCC.
- Turning off VCCQ/VCCQ2.
As part of ufs shutdown, after the SSU command completion, asserting
hardware reset (HWRST) triggers the device firmware to wake up and
execute its reset routine. This routine initializes hardware blocks and
takes a few milliseconds to complete. During this time, the ICCQ draws a
large current.
This large ICCQ current may cause issues for the regulator which is
supplying power to UFS, because the turn off request from UFS driver to
the regulator framework will be immediately followed by low power
mode(LPM) request by regulator framework. This is done by framework
because UFS which is the only client is requesting for disable. So if
the rail is still in the process of shutting down while ICCQ exceeds LPM
current thresholds, and LPM mode is activated in hardware during this
state, it may trigger an overcurrent protection (OCP) fault in the
regulator.
To prevent this, a 10ms delay is added after asserting HWRST. This
allows the reset operation to complete while power rails remain active
and in high-power mode.
Currently there is no way for Host to query whether the reset is
completed or not and hence this the delay is based on experiments with
Qualcomm UFS controllers across multiple UFS vendors.
Signed-off-by: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20251012173828.9880-1-nitin.rawat@oss.qualcomm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/host/ufs-qcom.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index ecd5939f4c9a6..3d5d10612bfd7 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -590,7 +590,18 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
/* reset the connected UFS device during power down */
ufs_qcom_device_reset_ctrl(hba, true);
-
+ /*
+ * After sending the SSU command, asserting the rst_n
+ * line causes the device firmware to wake up and
+ * execute its reset routine.
+ *
+ * During this process, the device may draw current
+ * beyond the permissible limit for low-power mode (LPM).
+ * A 10ms delay, based on experimental observations,
+ * allows the UFS device to complete its hardware reset
+ * before transitioning the power rail to LPM.
+ */
+ usleep_range(10000, 11000);
} else if (!ufs_qcom_is_link_active(hba)) {
ufs_qcom_disable_lane_clks(host);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0893/1887] lan966x: Fix sleeping in atomic context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (891 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0892/1887] scsi: ufs: ufs-qcom: Fix UFS OCP issue during UFS power down (PC=3) Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0894/1887] scsi: imm: Fix use-after-free bug caused by unfinished delayed work Greg Kroah-Hartman
` (105 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Horatiu Vultur, Jacob Keller,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <horatiu.vultur@microchip.com>
[ Upstream commit 0216721ce71252f60d89af49c8dff613358058d3 ]
The following warning was seen when we try to connect using ssh to the device.
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 104, name: dropbear
preempt_count: 1, expected: 0
INFO: lockdep is turned off.
CPU: 0 UID: 0 PID: 104 Comm: dropbear Tainted: G W 6.18.0-rc2-00399-g6f1ab1b109b9-dirty #530 NONE
Tainted: [W]=WARN
Hardware name: Generic DT based system
Call trace:
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x7c/0xac
dump_stack_lvl from __might_resched+0x16c/0x2b0
__might_resched from __mutex_lock+0x64/0xd34
__mutex_lock from mutex_lock_nested+0x1c/0x24
mutex_lock_nested from lan966x_stats_get+0x5c/0x558
lan966x_stats_get from dev_get_stats+0x40/0x43c
dev_get_stats from dev_seq_printf_stats+0x3c/0x184
dev_seq_printf_stats from dev_seq_show+0x10/0x30
dev_seq_show from seq_read_iter+0x350/0x4ec
seq_read_iter from seq_read+0xfc/0x194
seq_read from proc_reg_read+0xac/0x100
proc_reg_read from vfs_read+0xb0/0x2b0
vfs_read from ksys_read+0x6c/0xec
ksys_read from ret_fast_syscall+0x0/0x1c
Exception stack(0xf0b11fa8 to 0xf0b11ff0)
1fa0: 00000001 00001000 00000008 be9048d8 00001000 00000001
1fc0: 00000001 00001000 00000008 00000003 be905920 0000001e 00000000 00000001
1fe0: 0005404c be9048c0 00018684 b6ec2cd8
It seems that we are using a mutex in a atomic context which is wrong.
Change the mutex with a spinlock.
Fixes: 12c2d0a5b8e2 ("net: lan966x: add ethtool configuration and statistics")
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20251105074955.1766792-1-horatiu.vultur@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../microchip/lan966x/lan966x_ethtool.c | 18 +++++++++---------
.../ethernet/microchip/lan966x/lan966x_main.c | 2 --
.../ethernet/microchip/lan966x/lan966x_main.h | 4 ++--
3 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
index 06811c60d598e..df10a0b68a08e 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
@@ -294,7 +294,7 @@ static void lan966x_stats_update(struct lan966x *lan966x)
{
int i, j;
- mutex_lock(&lan966x->stats_lock);
+ spin_lock(&lan966x->stats_lock);
for (i = 0; i < lan966x->num_phys_ports; i++) {
uint idx = i * lan966x->num_stats;
@@ -310,7 +310,7 @@ static void lan966x_stats_update(struct lan966x *lan966x)
}
}
- mutex_unlock(&lan966x->stats_lock);
+ spin_unlock(&lan966x->stats_lock);
}
static int lan966x_get_sset_count(struct net_device *dev, int sset)
@@ -365,7 +365,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev,
idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
+ spin_lock(&lan966x->stats_lock);
mac_stats->FramesTransmittedOK =
lan966x->stats[idx + SYS_COUNT_TX_UC] +
@@ -424,7 +424,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev,
lan966x->stats[idx + SYS_COUNT_RX_LONG] +
lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
- mutex_unlock(&lan966x->stats_lock);
+ spin_unlock(&lan966x->stats_lock);
}
static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
@@ -450,7 +450,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev,
idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
+ spin_lock(&lan966x->stats_lock);
rmon_stats->undersize_pkts =
lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
@@ -508,7 +508,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev,
lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
- mutex_unlock(&lan966x->stats_lock);
+ spin_unlock(&lan966x->stats_lock);
*ranges = lan966x_rmon_ranges;
}
@@ -614,7 +614,7 @@ void lan966x_stats_get(struct net_device *dev,
idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
+ spin_lock(&lan966x->stats_lock);
stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];
@@ -696,7 +696,7 @@ void lan966x_stats_get(struct net_device *dev,
stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];
- mutex_unlock(&lan966x->stats_lock);
+ spin_unlock(&lan966x->stats_lock);
}
int lan966x_stats_init(struct lan966x *lan966x)
@@ -712,7 +712,7 @@ int lan966x_stats_init(struct lan966x *lan966x)
return -ENOMEM;
/* Init stats worker */
- mutex_init(&lan966x->stats_lock);
+ spin_lock_init(&lan966x->stats_lock);
snprintf(queue_name, sizeof(queue_name), "%s-stats",
dev_name(lan966x->dev));
lan966x->stats_queue = create_singlethread_workqueue(queue_name);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 8347def40f9d4..4a85cd5ebcce0 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -1182,7 +1182,6 @@ static int lan966x_probe(struct platform_device *pdev)
cancel_delayed_work_sync(&lan966x->stats_work);
destroy_workqueue(lan966x->stats_queue);
- mutex_destroy(&lan966x->stats_lock);
return err;
}
@@ -1197,7 +1196,6 @@ static int lan966x_remove(struct platform_device *pdev)
cancel_delayed_work_sync(&lan966x->stats_work);
destroy_workqueue(lan966x->stats_queue);
- mutex_destroy(&lan966x->stats_lock);
lan966x_mac_purge_entries(lan966x);
lan966x_mdb_deinit(lan966x);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index ff5736d2c7a6b..3f8b724eac47e 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -231,8 +231,8 @@ struct lan966x {
const struct lan966x_stat_layout *stats_layout;
u32 num_stats;
- /* workqueue for reading stats */
- struct mutex stats_lock;
+ /* lock for reading stats */
+ spinlock_t stats_lock;
u64 *stats;
struct delayed_work stats_work;
struct workqueue_struct *stats_queue;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0894/1887] scsi: imm: Fix use-after-free bug caused by unfinished delayed work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (892 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0893/1887] lan966x: Fix sleeping in atomic context Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0895/1887] can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing data Greg Kroah-Hartman
` (104 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Duoming Zhou, Martin K. Petersen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <duoming@zju.edu.cn>
[ Upstream commit ab58153ec64fa3fc9aea09ca09dc9322e0b54a7c ]
The delayed work item 'imm_tq' is initialized in imm_attach() and
scheduled via imm_queuecommand() for processing SCSI commands. When the
IMM parallel port SCSI host adapter is detached through imm_detach(),
the imm_struct device instance is deallocated.
However, the delayed work might still be pending or executing
when imm_detach() is called, leading to use-after-free bugs
when the work function imm_interrupt() accesses the already
freed imm_struct memory.
The race condition can occur as follows:
CPU 0(detach thread) | CPU 1
| imm_queuecommand()
| imm_queuecommand_lck()
imm_detach() | schedule_delayed_work()
kfree(dev) //FREE | imm_interrupt()
| dev = container_of(...) //USE
dev-> //USE
Add disable_delayed_work_sync() in imm_detach() to guarantee proper
cancellation of the delayed work item before imm_struct is deallocated.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/20251028100149.40721-1-duoming@zju.edu.cn
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/imm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 7a499d621c258..9754c0e28c363 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -1269,6 +1269,7 @@ static void imm_detach(struct parport *pb)
if (dev->dev->port == pb) {
list_del_init(&dev->list);
scsi_remove_host(dev->host);
+ cancel_delayed_work_sync(&dev->imm_tq);
scsi_host_put(dev->host);
parport_unregister_device(dev->dev);
kfree(dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0895/1887] can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing data
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (893 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0894/1887] scsi: imm: Fix use-after-free bug caused by unfinished delayed work Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0896/1887] bpf: Fix stackmap overflow check in __bpf_get_stackid() Greg Kroah-Hartman
` (103 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Marc Kleine-Budde, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <mkl@pengutronix.de>
[ Upstream commit 395d988f93861101ec89d0dd9e3b876ae9392a5b ]
The URB received in gs_usb_receive_bulk_callback() contains a struct
gs_host_frame. The length of the data after the header depends on the
gs_host_frame hf::flags and the active device features (e.g. time
stamping).
Introduce a new function gs_usb_get_minimum_length() and check that we have
at least received the required amount of data before accessing it. Only
copy the data to that skb that has actually been received.
Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-3-a29b42eacada@pengutronix.de
[mkl: rename gs_usb_get_minimum_length() -> +gs_usb_get_minimum_rx_length()]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/usb/gs_usb.c | 59 +++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index d0fe0e5e9021f..1f021366afab5 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -251,6 +251,11 @@ struct canfd_quirk {
u8 quirk;
} __packed;
+/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates
+ * a regular RX'ed CAN frame
+ */
+#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff
+
struct gs_host_frame {
struct_group(header,
u32 echo_id;
@@ -523,6 +528,37 @@ static void gs_usb_set_timestamp(struct gs_can *dev, struct sk_buff *skb,
return;
}
+static unsigned int
+gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf,
+ unsigned int *data_length_p)
+{
+ unsigned int minimum_length, data_length = 0;
+
+ if (hf->flags & GS_CAN_FLAG_FD) {
+ if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX)
+ data_length = can_fd_dlc2len(hf->can_dlc);
+
+ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+ /* timestamp follows data field of max size */
+ minimum_length = struct_size(hf, canfd_ts, 1);
+ else
+ minimum_length = sizeof(hf->header) + data_length;
+ } else {
+ if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX &&
+ !(hf->can_id & cpu_to_le32(CAN_RTR_FLAG)))
+ data_length = can_cc_dlc2len(hf->can_dlc);
+
+ if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+ /* timestamp follows data field of max size */
+ minimum_length = struct_size(hf, classic_can_ts, 1);
+ else
+ minimum_length = sizeof(hf->header) + data_length;
+ }
+
+ *data_length_p = data_length;
+ return minimum_length;
+}
+
static void gs_usb_receive_bulk_callback(struct urb *urb)
{
struct gs_usb *parent = urb->context;
@@ -531,7 +567,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
int rc;
struct net_device_stats *stats;
struct gs_host_frame *hf = urb->transfer_buffer;
- unsigned int minimum_length;
+ unsigned int minimum_length, data_length;
struct gs_tx_context *txc;
struct can_frame *cf;
struct canfd_frame *cfd;
@@ -574,20 +610,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
if (!netif_running(netdev))
goto resubmit_urb;
- if (hf->echo_id == -1) { /* normal rx */
+ minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length);
+ if (urb->actual_length < minimum_length) {
+ stats->rx_errors++;
+ stats->rx_length_errors++;
+
+ if (net_ratelimit())
+ netdev_err(netdev,
+ "short read (actual_length=%u, minimum_length=%u)\n",
+ urb->actual_length, minimum_length);
+
+ goto resubmit_urb;
+ }
+
+ if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */
if (hf->flags & GS_CAN_FLAG_FD) {
skb = alloc_canfd_skb(dev->netdev, &cfd);
if (!skb)
goto resubmit_urb;
cfd->can_id = le32_to_cpu(hf->can_id);
- cfd->len = can_fd_dlc2len(hf->can_dlc);
+ cfd->len = data_length;
if (hf->flags & GS_CAN_FLAG_BRS)
cfd->flags |= CANFD_BRS;
if (hf->flags & GS_CAN_FLAG_ESI)
cfd->flags |= CANFD_ESI;
- memcpy(cfd->data, hf->canfd->data, cfd->len);
+ memcpy(cfd->data, hf->canfd->data, data_length);
} else {
skb = alloc_can_skb(dev->netdev, &cf);
if (!skb)
@@ -596,7 +645,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
cf->can_id = le32_to_cpu(hf->can_id);
can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
- memcpy(cf->data, hf->classic_can->data, 8);
+ memcpy(cf->data, hf->classic_can->data, data_length);
/* ERROR frames tell us information about the controller */
if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0896/1887] bpf: Fix stackmap overflow check in __bpf_get_stackid()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (894 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0895/1887] can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing data Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0897/1887] RDMA/rxe: Fix null deref on srq->rq.queue after resize failure Greg Kroah-Hartman
` (102 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+c9b724fbb41cf2538b7b,
Arnaud Lecomte, Andrii Nakryiko, Yonghong Song, Song Liu,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaud Lecomte <contact@arnaud-lcm.com>
[ Upstream commit 23f852daa4bab4d579110e034e4d513f7d490846 ]
Syzkaller reported a KASAN slab-out-of-bounds write in __bpf_get_stackid()
when copying stack trace data. The issue occurs when the perf trace
contains more stack entries than the stack map bucket can hold,
leading to an out-of-bounds write in the bucket's data array.
Fixes: ee2a098851bf ("bpf: Adjust BPF stack helper functions to accommodate skip > 0")
Reported-by: syzbot+c9b724fbb41cf2538b7b@syzkaller.appspotmail.com
Signed-off-by: Arnaud Lecomte <contact@arnaud-lcm.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Acked-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/bpf/20251025192941.1500-1-contact@arnaud-lcm.com
Closes: https://syzkaller.appspot.com/bug?extid=c9b724fbb41cf2538b7b
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/stackmap.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index f0fd936cef319..dcbc3b314d5c3 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -219,7 +219,7 @@ static long __bpf_get_stackid(struct bpf_map *map,
struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
struct stack_map_bucket *bucket, *new_bucket, *old_bucket;
u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
- u32 hash, id, trace_nr, trace_len;
+ u32 hash, id, trace_nr, trace_len, max_depth;
bool user = flags & BPF_F_USER_STACK;
u64 *ips;
bool hash_matches;
@@ -228,7 +228,10 @@ static long __bpf_get_stackid(struct bpf_map *map,
/* skipping more than usable stack trace */
return -EFAULT;
- trace_nr = trace->nr - skip;
+ max_depth = map->value_size / stack_map_data_size(map) + skip;
+ if (max_depth > sysctl_perf_event_max_stack)
+ max_depth = sysctl_perf_event_max_stack;
+ trace_nr = min_t(u32, trace->nr - skip, max_depth - skip);
trace_len = trace_nr * sizeof(u64);
ips = trace->ip + skip;
hash = jhash2((u32 *)ips, trace_len / sizeof(u32), 0);
@@ -357,15 +360,11 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx,
return -EFAULT;
nr_kernel = count_kernel_ip(trace);
+ __u64 nr = trace->nr; /* save original */
if (kernel) {
- __u64 nr = trace->nr;
-
trace->nr = nr_kernel;
ret = __bpf_get_stackid(map, trace, flags);
-
- /* restore nr */
- trace->nr = nr;
} else { /* user */
u64 skip = flags & BPF_F_SKIP_FIELD_MASK;
@@ -376,6 +375,10 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx,
flags = (flags & ~BPF_F_SKIP_FIELD_MASK) | skip;
ret = __bpf_get_stackid(map, trace, flags);
}
+
+ /* restore nr */
+ trace->nr = nr;
+
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0897/1887] RDMA/rxe: Fix null deref on srq->rq.queue after resize failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (895 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0896/1887] bpf: Fix stackmap overflow check in __bpf_get_stackid() Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0898/1887] scsi: qla2xxx: Clear cmds after chip reset Greg Kroah-Hartman
` (101 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liu Yi, Zhu Yanjun, Leon Romanovsky,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <yanjun.zhu@linux.dev>
[ Upstream commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 ]
A NULL pointer dereference can occur in rxe_srq_chk_attr() when
ibv_modify_srq() is invoked twice in succession under certain error
conditions. The first call may fail in rxe_queue_resize(), which leads
rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then
triggers a crash (null deref) when accessing
srq->rq.queue->buf->index_mask.
Call Trace:
<TASK>
rxe_modify_srq+0x170/0x480 [rdma_rxe]
? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe]
? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs]
? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs]
ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs]
? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs]
? tryinc_node_nr_active+0xe6/0x150
? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs]
ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs]
? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs]
? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs]
ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs]
? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs]
ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs]
? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs]
? __pfx___raw_spin_lock_irqsave+0x10/0x10
? __pfx_do_vfs_ioctl+0x10/0x10
? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0
? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10
ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs]
? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs]
__x64_sys_ioctl+0x138/0x1c0
do_syscall_64+0x82/0x250
? fdget_pos+0x58/0x4c0
? ksys_write+0xf3/0x1c0
? __pfx_ksys_write+0x10/0x10
? do_syscall_64+0xc8/0x250
? __pfx_vm_mmap_pgoff+0x10/0x10
? fget+0x173/0x230
? fput+0x2a/0x80
? ksys_mmap_pgoff+0x224/0x4c0
? do_syscall_64+0xc8/0x250
? do_user_addr_fault+0x37b/0xfe0
? clear_bhb_loop+0x50/0xa0
? clear_bhb_loop+0x50/0xa0
? clear_bhb_loop+0x50/0xa0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fixes: 8700e3e7c485 ("Soft RoCE driver")
Tested-by: Liu Yi <asatsuyu.liu@gmail.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c
index 038a9cd55413e..82e872fd8f45d 100644
--- a/drivers/infiniband/sw/rxe/rxe_srq.c
+++ b/drivers/infiniband/sw/rxe/rxe_srq.c
@@ -161,18 +161,13 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,
&srq->rq.producer_lock,
&srq->rq.consumer_lock);
if (err)
- goto err2;
+ return err;
}
if (mask & IB_SRQ_LIMIT)
srq->limit = attr->srq_limit;
return 0;
-
-err2:
- rxe_queue_cleanup(q);
- srq->rq.queue = NULL;
- return err;
}
void rxe_srq_cleanup(struct rxe_pool_elem *elem)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0898/1887] scsi: qla2xxx: Clear cmds after chip reset
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (896 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0897/1887] RDMA/rxe: Fix null deref on srq->rq.queue after resize failure Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0899/1887] staging: most: remove broken i2c driver Greg Kroah-Hartman
` (100 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dmitry Bogdanov, Tony Battersby,
Martin K. Petersen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Battersby <tonyb@cybernetics.com>
[ Upstream commit d46c69a087aa3d1513f7a78f871b80251ea0c1ae ]
Commit aefed3e5548f ("scsi: qla2xxx: target: Fix offline port handling
and host reset handling") caused two problems:
1. Commands sent to FW, after chip reset got stuck and never freed as FW
is not going to respond to them anymore.
2. BUG_ON(cmd->sg_mapped) in qlt_free_cmd(). Commit 26f9ce53817a
("scsi: qla2xxx: Fix missed DMA unmap for aborted commands")
attempted to fix this, but introduced another bug under different
circumstances when two different CPUs were racing to call
qlt_unmap_sg() at the same time: BUG_ON(!valid_dma_direction(dir)) in
dma_unmap_sg_attrs().
So revert "scsi: qla2xxx: Fix missed DMA unmap for aborted commands" and
partially revert "scsi: qla2xxx: target: Fix offline port handling and
host reset handling" at __qla2x00_abort_all_cmds.
Fixes: aefed3e5548f ("scsi: qla2xxx: target: Fix offline port handling and host reset handling")
Fixes: 26f9ce53817a ("scsi: qla2xxx: Fix missed DMA unmap for aborted commands")
Co-developed-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
Link: https://patch.msgid.link/0e7e5d26-e7a0-42d1-8235-40eeb27f3e98@cybernetics.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_os.c | 20 ++++++++++++++++++--
drivers/scsi/qla2xxx/qla_target.c | 5 +----
drivers/scsi/qla2xxx/qla_target.h | 1 +
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 0b21fb29a9fc5..38e2b31237025 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1883,10 +1883,26 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
continue;
}
cmd = (struct qla_tgt_cmd *)sp;
- cmd->aborted = 1;
+
+ if (cmd->sg_mapped)
+ qlt_unmap_sg(vha, cmd);
+
+ if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
+ cmd->aborted = 1;
+ cmd->write_data_transferred = 0;
+ cmd->state = QLA_TGT_STATE_DATA_IN;
+ ha->tgt.tgt_ops->handle_data(cmd);
+ } else {
+ ha->tgt.tgt_ops->free_cmd(cmd);
+ }
break;
case TYPE_TGT_TMCMD:
- /* Skip task management functions. */
+ /*
+ * Currently, only ABTS response gets on the
+ * outstanding_cmds[]
+ */
+ ha->tgt.tgt_ops->free_mcmd(
+ (struct qla_tgt_mgmt_cmd *) sp);
break;
default:
break;
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 043cfa10c7167..7136ec5ded35b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2504,7 +2504,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
return -1;
}
-static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
+void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
{
struct qla_hw_data *ha;
struct qla_qpair *qpair;
@@ -3834,9 +3834,6 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
spin_lock_irqsave(&cmd->cmd_lock, flags);
if (cmd->aborted) {
- if (cmd->sg_mapped)
- qlt_unmap_sg(vha, cmd);
-
spin_unlock_irqrestore(&cmd->cmd_lock, flags);
/*
* It's normal to see 2 calls in this path:
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 7df86578214f1..e674a81eb527f 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -1060,6 +1060,7 @@ extern int qlt_abort_cmd(struct qla_tgt_cmd *);
extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
+extern void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd);
extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *);
extern void qlt_enable_vha(struct scsi_qla_host *);
extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0899/1887] staging: most: remove broken i2c driver
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (897 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0898/1887] scsi: qla2xxx: Clear cmds after chip reset Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0900/1887] ksmbd: vfs: fix race on m_flags in vfs_cache Greg Kroah-Hartman
` (99 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Gromm, Johan Hovold,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 495df2da6944477d282d5cc0c13174d06e25b310 ]
The MOST I2C driver has been completely broken for five years without
anyone noticing so remove the driver from staging.
Specifically, commit 723de0f9171e ("staging: most: remove device from
interface structure") started requiring drivers to set the interface
device pointer before registration, but the I2C driver was never updated
which results in a NULL pointer dereference if anyone ever tries to
probe it.
Fixes: 723de0f9171e ("staging: most: remove device from interface structure")
Cc: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20251029093442.29256-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/most/Kconfig | 2 -
drivers/staging/most/Makefile | 1 -
drivers/staging/most/i2c/Kconfig | 13 --
drivers/staging/most/i2c/Makefile | 4 -
drivers/staging/most/i2c/i2c.c | 371 ------------------------------
5 files changed, 391 deletions(-)
delete mode 100644 drivers/staging/most/i2c/Kconfig
delete mode 100644 drivers/staging/most/i2c/Makefile
delete mode 100644 drivers/staging/most/i2c/i2c.c
diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig
index 6f420cbcdcfff..e89658df6f124 100644
--- a/drivers/staging/most/Kconfig
+++ b/drivers/staging/most/Kconfig
@@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig"
source "drivers/staging/most/dim2/Kconfig"
-source "drivers/staging/most/i2c/Kconfig"
-
endif
diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile
index 8b3fc5a7af514..e45084df7803a 100644
--- a/drivers/staging/most/Makefile
+++ b/drivers/staging/most/Makefile
@@ -3,4 +3,3 @@
obj-$(CONFIG_MOST_NET) += net/
obj-$(CONFIG_MOST_VIDEO) += video/
obj-$(CONFIG_MOST_DIM2) += dim2/
-obj-$(CONFIG_MOST_I2C) += i2c/
diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig
deleted file mode 100644
index ff64283cbad18..0000000000000
--- a/drivers/staging/most/i2c/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# MOST I2C configuration
-#
-
-config MOST_I2C
- tristate "I2C"
- depends on I2C
- help
- Say Y here if you want to connect via I2C to network transceiver.
-
- To compile this driver as a module, choose M here: the
- module will be called most_i2c.
diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile
deleted file mode 100644
index 71099dd0f85b9..0000000000000
--- a/drivers/staging/most/i2c/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_MOST_I2C) += most_i2c.o
-
-most_i2c-objs := i2c.o
diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c
deleted file mode 100644
index 285a071f02be1..0000000000000
--- a/drivers/staging/most/i2c/i2c.c
+++ /dev/null
@@ -1,371 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * i2c.c - Hardware Dependent Module for I2C Interface
- *
- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/most.h>
-
-enum { CH_RX, CH_TX, NUM_CHANNELS };
-
-#define MAX_BUFFERS_CONTROL 32
-#define MAX_BUF_SIZE_CONTROL 256
-
-/**
- * list_first_mbo - get the first mbo from a list
- * @ptr: the list head to take the mbo from.
- */
-#define list_first_mbo(ptr) \
- list_first_entry(ptr, struct mbo, list)
-
-static unsigned int polling_rate;
-module_param(polling_rate, uint, 0644);
-MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)");
-
-struct hdm_i2c {
- struct most_interface most_iface;
- struct most_channel_capability capabilities[NUM_CHANNELS];
- struct i2c_client *client;
- struct rx {
- struct delayed_work dwork;
- struct list_head list;
- bool int_disabled;
- unsigned int delay;
- } rx;
- char name[64];
-};
-
-#define to_hdm(iface) container_of(iface, struct hdm_i2c, most_iface)
-
-static irqreturn_t most_irq_handler(int, void *);
-static void pending_rx_work(struct work_struct *);
-
-/**
- * configure_channel - called from MOST core to configure a channel
- * @most_iface: interface the channel belongs to
- * @ch_idx: channel to be configured
- * @channel_config: structure that holds the configuration information
- *
- * Return 0 on success, negative on failure.
- *
- * Receives configuration information from MOST core and initialize the
- * corresponding channel.
- */
-static int configure_channel(struct most_interface *most_iface,
- int ch_idx,
- struct most_channel_config *channel_config)
-{
- int ret;
- struct hdm_i2c *dev = to_hdm(most_iface);
- unsigned int delay, pr;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (channel_config->data_type != MOST_CH_CONTROL) {
- pr_err("bad data type for channel %d\n", ch_idx);
- return -EPERM;
- }
-
- if (channel_config->direction != dev->capabilities[ch_idx].direction) {
- pr_err("bad direction for channel %d\n", ch_idx);
- return -EPERM;
- }
-
- if (channel_config->direction == MOST_CH_RX) {
- if (!polling_rate) {
- if (dev->client->irq <= 0) {
- pr_err("bad irq: %d\n", dev->client->irq);
- return -ENOENT;
- }
- dev->rx.int_disabled = false;
- ret = request_irq(dev->client->irq, most_irq_handler, 0,
- dev->client->name, dev);
- if (ret) {
- pr_err("request_irq(%d) failed: %d\n",
- dev->client->irq, ret);
- return ret;
- }
- } else {
- delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate);
- dev->rx.delay = delay ? delay : 1;
- pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay);
- pr_info("polling rate is %u Hz\n", pr);
- }
- }
-
- return 0;
-}
-
-/**
- * enqueue - called from MOST core to enqueue a buffer for data transfer
- * @most_iface: intended interface
- * @ch_idx: ID of the channel the buffer is intended for
- * @mbo: pointer to the buffer object
- *
- * Return 0 on success, negative on failure.
- *
- * Transmit the data over I2C if it is a "write" request or push the buffer into
- * list if it is an "read" request
- */
-static int enqueue(struct most_interface *most_iface,
- int ch_idx, struct mbo *mbo)
-{
- struct hdm_i2c *dev = to_hdm(most_iface);
- int ret;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (ch_idx == CH_RX) {
- /* RX */
- if (!polling_rate)
- disable_irq(dev->client->irq);
- cancel_delayed_work_sync(&dev->rx.dwork);
- list_add_tail(&mbo->list, &dev->rx.list);
- if (dev->rx.int_disabled || polling_rate)
- pending_rx_work(&dev->rx.dwork.work);
- if (!polling_rate)
- enable_irq(dev->client->irq);
- } else {
- /* TX */
- ret = i2c_master_send(dev->client, mbo->virt_address,
- mbo->buffer_length);
- if (ret <= 0) {
- mbo->processed_length = 0;
- mbo->status = MBO_E_INVAL;
- } else {
- mbo->processed_length = mbo->buffer_length;
- mbo->status = MBO_SUCCESS;
- }
- mbo->complete(mbo);
- }
-
- return 0;
-}
-
-/**
- * poison_channel - called from MOST core to poison buffers of a channel
- * @most_iface: pointer to the interface the channel to be poisoned belongs to
- * @ch_idx: corresponding channel ID
- *
- * Return 0 on success, negative on failure.
- *
- * If channel direction is RX, complete the buffers in list with
- * status MBO_E_CLOSE
- */
-static int poison_channel(struct most_interface *most_iface,
- int ch_idx)
-{
- struct hdm_i2c *dev = to_hdm(most_iface);
- struct mbo *mbo;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (ch_idx == CH_RX) {
- if (!polling_rate)
- free_irq(dev->client->irq, dev);
- cancel_delayed_work_sync(&dev->rx.dwork);
-
- while (!list_empty(&dev->rx.list)) {
- mbo = list_first_mbo(&dev->rx.list);
- list_del(&mbo->list);
-
- mbo->processed_length = 0;
- mbo->status = MBO_E_CLOSE;
- mbo->complete(mbo);
- }
- }
-
- return 0;
-}
-
-static void do_rx_work(struct hdm_i2c *dev)
-{
- struct mbo *mbo;
- unsigned char msg[MAX_BUF_SIZE_CONTROL];
- int ret;
- u16 pml, data_size;
-
- /* Read PML (2 bytes) */
- ret = i2c_master_recv(dev->client, msg, 2);
- if (ret <= 0) {
- pr_err("Failed to receive PML\n");
- return;
- }
-
- pml = (msg[0] << 8) | msg[1];
- if (!pml)
- return;
-
- data_size = pml + 2;
-
- /* Read the whole message, including PML */
- ret = i2c_master_recv(dev->client, msg, data_size);
- if (ret <= 0) {
- pr_err("Failed to receive a Port Message\n");
- return;
- }
-
- mbo = list_first_mbo(&dev->rx.list);
- list_del(&mbo->list);
-
- mbo->processed_length = min(data_size, mbo->buffer_length);
- memcpy(mbo->virt_address, msg, mbo->processed_length);
- mbo->status = MBO_SUCCESS;
- mbo->complete(mbo);
-}
-
-/**
- * pending_rx_work - Read pending messages through I2C
- * @work: definition of this work item
- *
- * Invoked by the Interrupt Service Routine, most_irq_handler()
- */
-static void pending_rx_work(struct work_struct *work)
-{
- struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work);
-
- if (list_empty(&dev->rx.list))
- return;
-
- do_rx_work(dev);
-
- if (polling_rate) {
- schedule_delayed_work(&dev->rx.dwork, dev->rx.delay);
- } else {
- dev->rx.int_disabled = false;
- enable_irq(dev->client->irq);
- }
-}
-
-/*
- * most_irq_handler - Interrupt Service Routine
- * @irq: irq number
- * @_dev: private data
- *
- * Schedules a delayed work
- *
- * By default the interrupt line behavior is Active Low. Once an interrupt is
- * generated by the device, until driver clears the interrupt (by reading
- * the PMP message), device keeps the interrupt line in low state. Since i2c
- * read is done in work queue, the interrupt line must be disabled temporarily
- * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue,
- * after reading the message.
- *
- * Note: If we use the interrupt line in Falling edge mode, there is a
- * possibility to miss interrupts when ISR is getting executed.
- *
- */
-static irqreturn_t most_irq_handler(int irq, void *_dev)
-{
- struct hdm_i2c *dev = _dev;
-
- disable_irq_nosync(irq);
- dev->rx.int_disabled = true;
- schedule_delayed_work(&dev->rx.dwork, 0);
-
- return IRQ_HANDLED;
-}
-
-/*
- * i2c_probe - i2c probe handler
- * @client: i2c client device structure
- * @id: i2c client device id
- *
- * Return 0 on success, negative on failure.
- *
- * Register the i2c client device as a MOST interface
- */
-static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct hdm_i2c *dev;
- int ret, i;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- /* ID format: i2c-<bus>-<address> */
- snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x",
- client->adapter->nr, client->addr);
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- dev->capabilities[i].data_type = MOST_CH_CONTROL;
- dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL;
- dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL;
- }
- dev->capabilities[CH_RX].direction = MOST_CH_RX;
- dev->capabilities[CH_RX].name_suffix = "rx";
- dev->capabilities[CH_TX].direction = MOST_CH_TX;
- dev->capabilities[CH_TX].name_suffix = "tx";
-
- dev->most_iface.interface = ITYPE_I2C;
- dev->most_iface.description = dev->name;
- dev->most_iface.num_channels = NUM_CHANNELS;
- dev->most_iface.channel_vector = dev->capabilities;
- dev->most_iface.configure = configure_channel;
- dev->most_iface.enqueue = enqueue;
- dev->most_iface.poison_channel = poison_channel;
-
- INIT_LIST_HEAD(&dev->rx.list);
-
- INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work);
-
- dev->client = client;
- i2c_set_clientdata(client, dev);
-
- ret = most_register_interface(&dev->most_iface);
- if (ret) {
- pr_err("Failed to register i2c as a MOST interface\n");
- kfree(dev);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * i2c_remove - i2c remove handler
- * @client: i2c client device structure
- *
- * Return 0 on success.
- *
- * Unregister the i2c client device as a MOST interface
- */
-static void i2c_remove(struct i2c_client *client)
-{
- struct hdm_i2c *dev = i2c_get_clientdata(client);
-
- most_deregister_interface(&dev->most_iface);
- kfree(dev);
-}
-
-static const struct i2c_device_id i2c_id[] = {
- { "most_i2c", 0 },
- { }, /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(i2c, i2c_id);
-
-static struct i2c_driver i2c_driver = {
- .driver = {
- .name = "hdm_i2c",
- },
- .probe = i2c_probe,
- .remove = i2c_remove,
- .id_table = i2c_id,
-};
-
-module_i2c_driver(i2c_driver);
-
-MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>");
-MODULE_DESCRIPTION("I2C Hardware Dependent Module");
-MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0900/1887] ksmbd: vfs: fix race on m_flags in vfs_cache
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (898 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0899/1887] staging: most: remove broken i2c driver Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0901/1887] Input: alps - fix use-after-free bugs caused by dev3_register_work Greg Kroah-Hartman
` (98 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qianchang Zhao, Zhitong Liu,
Namjae Jeon, Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qianchang Zhao <pioooooooooip@gmail.com>
[ Upstream commit 991f8a79db99b14c48d20d2052c82d65b9186cad ]
ksmbd maintains delete-on-close and pending-delete state in
ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under
inconsistent locking: some paths read and modify m_flags under
ci->m_lock while others do so without taking the lock at all.
Examples:
- ksmbd_query_inode_status() and __ksmbd_inode_close() use
ci->m_lock when checking or updating m_flags.
- ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(),
ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close()
used to read and modify m_flags without ci->m_lock.
This creates a potential data race on m_flags when multiple threads
open, close and delete the same file concurrently. In the worst case
delete-on-close and pending-delete bits can be lost or observed in an
inconsistent state, leading to confusing delete semantics (files that
stay on disk after delete-on-close, or files that disappear while still
in use).
Fix it by:
- Making ksmbd_query_inode_status() look at m_flags under ci->m_lock
after dropping inode_hash_lock.
- Adding ci->m_lock protection to all helpers that read or modify
m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(),
ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()).
- Keeping the existing ci->m_lock protection in __ksmbd_inode_close(),
and moving the actual unlink/xattr removal outside the lock.
This unifies the locking around m_flags and removes the data race while
preserving the existing delete-on-close behaviour.
Reported-by: Qianchang Zhao <pioooooooooip@gmail.com>
Reported-by: Zhitong Liu <liuzhitong1993@gmail.com>
Signed-off-by: Qianchang Zhao <pioooooooooip@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/vfs_cache.c | 86 +++++++++++++++++++++++++++------------
1 file changed, 61 insertions(+), 25 deletions(-)
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 4b35e4f960694..d10cd67d6793c 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -104,40 +104,62 @@ int ksmbd_query_inode_status(struct dentry *dentry)
read_lock(&inode_hash_lock);
ci = __ksmbd_inode_lookup(dentry);
- if (ci) {
- ret = KSMBD_INODE_STATUS_OK;
- if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
- ret = KSMBD_INODE_STATUS_PENDING_DELETE;
- atomic_dec(&ci->m_count);
- }
read_unlock(&inode_hash_lock);
+ if (!ci)
+ return ret;
+
+ read_lock(&ci->m_lock);
+ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
+ ret = KSMBD_INODE_STATUS_PENDING_DELETE;
+ else
+ ret = KSMBD_INODE_STATUS_OK;
+ read_unlock(&ci->m_lock);
+
+ atomic_dec(&ci->m_count);
return ret;
}
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp)
{
- return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS));
+ struct ksmbd_inode *ci = fp->f_ci;
+ int ret;
+
+ read_lock(&ci->m_lock);
+ ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS));
+ read_unlock(&ci->m_lock);
+
+ return ret;
}
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp)
{
- fp->f_ci->m_flags |= S_DEL_PENDING;
+ struct ksmbd_inode *ci = fp->f_ci;
+
+ write_lock(&ci->m_lock);
+ ci->m_flags |= S_DEL_PENDING;
+ write_unlock(&ci->m_lock);
}
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp)
{
- fp->f_ci->m_flags &= ~S_DEL_PENDING;
+ struct ksmbd_inode *ci = fp->f_ci;
+
+ write_lock(&ci->m_lock);
+ ci->m_flags &= ~S_DEL_PENDING;
+ write_unlock(&ci->m_lock);
}
void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp,
int file_info)
{
- if (ksmbd_stream_fd(fp)) {
- fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM;
- return;
- }
+ struct ksmbd_inode *ci = fp->f_ci;
- fp->f_ci->m_flags |= S_DEL_ON_CLS;
+ write_lock(&ci->m_lock);
+ if (ksmbd_stream_fd(fp))
+ ci->m_flags |= S_DEL_ON_CLS_STREAM;
+ else
+ ci->m_flags |= S_DEL_ON_CLS;
+ write_unlock(&ci->m_lock);
}
static void ksmbd_inode_hash(struct ksmbd_inode *ci)
@@ -249,26 +271,40 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
struct file *filp;
filp = fp->filp;
- if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) {
- ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
- err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp),
- &filp->f_path,
- fp->stream.name);
- if (err)
- pr_err("remove xattr failed : %s\n",
- fp->stream.name);
+
+ if (ksmbd_stream_fd(fp)) {
+ bool remove_stream_xattr = false;
+
+ write_lock(&ci->m_lock);
+ if (ci->m_flags & S_DEL_ON_CLS_STREAM) {
+ ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
+ remove_stream_xattr = true;
+ }
+ write_unlock(&ci->m_lock);
+
+ if (remove_stream_xattr) {
+ err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp),
+ &filp->f_path,
+ fp->stream.name);
+ if (err)
+ pr_err("remove xattr failed : %s\n",
+ fp->stream.name);
+ }
}
if (atomic_dec_and_test(&ci->m_count)) {
+ bool do_unlink = false;
+
write_lock(&ci->m_lock);
if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
- write_unlock(&ci->m_lock);
- ksmbd_vfs_unlink(filp);
- write_lock(&ci->m_lock);
+ do_unlink = true;
}
write_unlock(&ci->m_lock);
+ if (do_unlink)
+ ksmbd_vfs_unlink(filp);
+
ksmbd_inode_free(ci);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0901/1887] Input: alps - fix use-after-free bugs caused by dev3_register_work
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (899 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0900/1887] ksmbd: vfs: fix race on m_flags in vfs_cache Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0902/1887] svcrdma: bound check rq_pages index in inline path Greg Kroah-Hartman
` (97 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Duoming Zhou,
Dmitry Torokhov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <duoming@zju.edu.cn>
[ Upstream commit bf40644ef8c8a288742fa45580897ed0e0289474 ]
The dev3_register_work delayed work item is initialized within
alps_reconnect() and scheduled upon receipt of the first bare
PS/2 packet from an external PS/2 device connected to the ALPS
touchpad. During device detachment, the original implementation
calls flush_workqueue() in psmouse_disconnect() to ensure
completion of dev3_register_work. However, the flush_workqueue()
in psmouse_disconnect() only blocks and waits for work items that
were already queued to the workqueue prior to its invocation. Any
work items submitted after flush_workqueue() is called are not
included in the set of tasks that the flush operation awaits.
This means that after flush_workqueue() has finished executing,
the dev3_register_work could still be scheduled. Although the
psmouse state is set to PSMOUSE_CMD_MODE in psmouse_disconnect(),
the scheduling of dev3_register_work remains unaffected.
The race condition can occur as follows:
CPU 0 (cleanup path) | CPU 1 (delayed work)
psmouse_disconnect() |
psmouse_set_state() |
flush_workqueue() | alps_report_bare_ps2_packet()
alps_disconnect() | psmouse_queue_work()
kfree(priv); // FREE | alps_register_bare_ps2_mouse()
| priv = container_of(work...); // USE
| priv->dev3 // USE
Add disable_delayed_work_sync() in alps_disconnect() to ensure
that dev3_register_work is properly canceled and prevented from
executing after the alps_data structure has been deallocated.
This bug is identified by static analysis.
Fixes: 04aae283ba6a ("Input: ALPS - do not mix trackstick and external PS/2 mouse data")
Cc: stable@kernel.org
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/b57b0a9ccca51a3f06be141bfc02b9ffe69d1845.1765939397.git.duoming@zju.edu.cn
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/mouse/alps.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index dd08ce97e7c90..b23f8cf72fe96 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -2971,6 +2971,8 @@ static void alps_disconnect(struct psmouse *psmouse)
psmouse_reset(psmouse);
del_timer_sync(&priv->timer);
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+ cancel_delayed_work_sync(&priv->dev3_register_work);
if (priv->dev2)
input_unregister_device(priv->dev2);
if (!IS_ERR_OR_NULL(priv->dev3))
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0902/1887] svcrdma: bound check rq_pages index in inline path
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (900 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0901/1887] Input: alps - fix use-after-free bugs caused by dev3_register_work Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:49 ` [PATCH 6.1 0903/1887] Input: lkkbd - disable pending work before freeing device Greg Kroah-Hartman
` (96 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Joshua Rogers, Chuck Lever,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <linux@joshua.hu>
[ Upstream commit d1bea0ce35b6095544ee82bb54156fc62c067e58 ]
svc_rdma_copy_inline_range indexed rqstp->rq_pages[rc_curpage] without
verifying rc_curpage stays within the allocated page array. Add guards
before the first use and after advancing to a new page.
Fixes: d7cc73972661 ("svcrdma: support multiple Read chunks per RPC")
Cc: stable@vger.kernel.org
Signed-off-by: Joshua Rogers <linux@joshua.hu>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/xprtrdma/svc_rdma_rw.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c
index 1bc9dfa1e5bbc..e455f16440334 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_rw.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c
@@ -811,6 +811,9 @@ static int svc_rdma_copy_inline_range(struct svc_rdma_read_info *info,
for (page_no = 0; page_no < numpages; page_no++) {
unsigned int page_len;
+ if (&rqstp->rq_pages[info->ri_pageno] >= rqstp->rq_page_end)
+ return -EINVAL;
+
page_len = min_t(unsigned int, remaining,
PAGE_SIZE - info->ri_pageoff);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0903/1887] Input: lkkbd - disable pending work before freeing device
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (901 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0902/1887] svcrdma: bound check rq_pages index in inline path Greg Kroah-Hartman
@ 2026-10-28 16:49 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0904/1887] usb: gadget: ffs: remove ENTER() macro Greg Kroah-Hartman
` (95 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Minseong Kim, Dmitry Torokhov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minseong Kim <ii4gsp@gmail.com>
[ Upstream commit e58c88f0cb2d8ed89de78f6f17409d29cfab6c5c ]
lkkbd_interrupt() schedules lk->tq via schedule_work(), and the work
handler lkkbd_reinit() dereferences the lkkbd structure and its
serio/input_dev fields.
lkkbd_disconnect() and error paths in lkkbd_connect() free the lkkbd
structure without preventing the reinit work from being queued again
until serio_close() returns. This can allow the work handler to run
after the structure has been freed, leading to a potential use-after-free.
Use disable_work_sync() instead of cancel_work_sync() to ensure the
reinit work cannot be re-queued, and call it both in lkkbd_disconnect()
and in lkkbd_connect() error paths after serio_open().
Signed-off-by: Minseong Kim <ii4gsp@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251212052314.16139-1-ii4gsp@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/lkkbd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 047b654b3752c..7b57577a1715c 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -671,6 +671,7 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
return 0;
fail3: serio_close(serio);
+ cancel_work_sync(&lk->tq);
fail2: serio_set_drvdata(serio, NULL);
fail1: input_free_device(input_dev);
kfree(lk);
@@ -687,6 +688,7 @@ static void lkkbd_disconnect(struct serio *serio)
input_get_device(lk->dev);
input_unregister_device(lk->dev);
serio_close(serio);
+ cancel_work_sync(&lk->tq);
serio_set_drvdata(serio, NULL);
input_put_device(lk->dev);
kfree(lk);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0904/1887] usb: gadget: ffs: remove ENTER() macro
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (902 preceding siblings ...)
2026-10-28 16:49 ` [PATCH 6.1 0903/1887] Input: lkkbd - disable pending work before freeing device Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0905/1887] usb: gadget: Support already-mapped DMA SGs Greg Kroah-Hartman
` (94 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linyu Yuan, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linyu Yuan <quic_linyyuan@quicinc.com>
[ Upstream commit f54134b3fc7954dbaa4da42198286e49bcb48ed7 ]
ENTER() used to show function name which called during runtime, ftrace can
be used to get same information, let's remove it.
Signed-off-by: Linyu Yuan <quic_linyyuan@quicinc.com>
Link: https://lore.kernel.org/r/1679911940-4727-1-git-send-email-quic_linyyuan@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: e5bf5ee26663 ("functionfs: fix the open/removal races")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 94 ------------------------------
drivers/usb/gadget/function/u_fs.h | 2 -
drivers/usb/gadget/legacy/g_ffs.c | 9 ---
3 files changed, 105 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index bbc15211611ac..3a1f823d71acf 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -336,8 +336,6 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
ssize_t ret;
char *data;
- ENTER();
-
/* Fast check if setup was canceled */
if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED)
return -EIDRM;
@@ -513,8 +511,6 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
size_t n;
int ret;
- ENTER();
-
/* Fast check if setup was canceled */
if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED)
return -EIDRM;
@@ -619,8 +615,6 @@ static int ffs_ep0_open(struct inode *inode, struct file *file)
{
struct ffs_data *ffs = inode->i_private;
- ENTER();
-
if (ffs->state == FFS_CLOSING)
return -EBUSY;
@@ -634,8 +628,6 @@ static int ffs_ep0_release(struct inode *inode, struct file *file)
{
struct ffs_data *ffs = file->private_data;
- ENTER();
-
ffs_data_closed(ffs);
return 0;
@@ -647,8 +639,6 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
struct usb_gadget *gadget = ffs->gadget;
long ret;
- ENTER();
-
if (code == FUNCTIONFS_INTERFACE_REVMAP) {
struct ffs_function *func = ffs->func;
ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
@@ -722,7 +712,6 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
{
struct ffs_io_data *io_data = req->context;
- ENTER();
if (req->status)
io_data->status = req->status;
else
@@ -875,8 +864,6 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
struct ffs_io_data *io_data = req->context;
struct ffs_data *ffs = io_data->ffs;
- ENTER();
-
io_data->status = req->status ? req->status : req->actual;
INIT_WORK(&io_data->work, ffs_user_copy_worker);
@@ -1179,8 +1166,6 @@ ffs_epfile_open(struct inode *inode, struct file *file)
{
struct ffs_epfile *epfile = inode->i_private;
- ENTER();
-
if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
return -ENODEV;
@@ -1197,8 +1182,6 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
unsigned long flags;
int value;
- ENTER();
-
spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
if (io_data && io_data->ep && io_data->req)
@@ -1216,8 +1199,6 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
struct ffs_io_data io_data, *p = &io_data;
ssize_t res;
- ENTER();
-
if (!is_sync_kiocb(kiocb)) {
p = kzalloc(sizeof(io_data), GFP_KERNEL);
if (!p)
@@ -1259,8 +1240,6 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
struct ffs_io_data io_data, *p = &io_data;
ssize_t res;
- ENTER();
-
if (!is_sync_kiocb(kiocb)) {
p = kzalloc(sizeof(io_data), GFP_KERNEL);
if (!p)
@@ -1313,8 +1292,6 @@ ffs_epfile_release(struct inode *inode, struct file *file)
{
struct ffs_epfile *epfile = inode->i_private;
- ENTER();
-
ffs_data_closed(epfile->ffs);
return 0;
@@ -1327,8 +1304,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
struct ffs_ep *ep;
int ret;
- ENTER();
-
if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
return -ENODEV;
@@ -1438,8 +1413,6 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
{
struct inode *inode;
- ENTER();
-
inode = new_inode(sb);
if (inode) {
@@ -1471,8 +1444,6 @@ static struct dentry *ffs_sb_create_file(struct super_block *sb,
struct dentry *dentry;
struct inode *inode;
- ENTER();
-
dentry = d_alloc_name(sb->s_root, name);
if (!dentry)
return NULL;
@@ -1507,8 +1478,6 @@ static int ffs_sb_fill(struct super_block *sb, struct fs_context *fc)
struct inode *inode;
struct ffs_data *ffs = data->ffs_data;
- ENTER();
-
ffs->sb = sb;
data->ffs_data = NULL;
sb->s_fs_info = ffs;
@@ -1560,8 +1529,6 @@ static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
struct fs_parse_result result;
int opt;
- ENTER();
-
opt = fs_parse(fc, ffs_fs_fs_parameters, param, &result);
if (opt < 0)
return opt;
@@ -1611,8 +1578,6 @@ static int ffs_fs_get_tree(struct fs_context *fc)
struct ffs_data *ffs;
int ret;
- ENTER();
-
if (!fc->source)
return invalf(fc, "No source specified");
@@ -1679,8 +1644,6 @@ static int ffs_fs_init_fs_context(struct fs_context *fc)
static void
ffs_fs_kill_sb(struct super_block *sb)
{
- ENTER();
-
kill_litter_super(sb);
if (sb->s_fs_info)
ffs_data_closed(sb->s_fs_info);
@@ -1702,8 +1665,6 @@ static int functionfs_init(void)
{
int ret;
- ENTER();
-
ret = register_filesystem(&ffs_fs_type);
if (!ret)
pr_info("file system registered\n");
@@ -1715,8 +1676,6 @@ static int functionfs_init(void)
static void functionfs_cleanup(void)
{
- ENTER();
-
pr_info("unloading\n");
unregister_filesystem(&ffs_fs_type);
}
@@ -1729,15 +1688,11 @@ static void ffs_data_reset(struct ffs_data *ffs);
static void ffs_data_get(struct ffs_data *ffs)
{
- ENTER();
-
refcount_inc(&ffs->ref);
}
static void ffs_data_opened(struct ffs_data *ffs)
{
- ENTER();
-
refcount_inc(&ffs->ref);
if (atomic_add_return(1, &ffs->opened) == 1 &&
ffs->state == FFS_DEACTIVATED) {
@@ -1748,8 +1703,6 @@ static void ffs_data_opened(struct ffs_data *ffs)
static void ffs_data_put(struct ffs_data *ffs)
{
- ENTER();
-
if (refcount_dec_and_test(&ffs->ref)) {
pr_info("%s(): freeing\n", __func__);
ffs_data_clear(ffs);
@@ -1768,8 +1721,6 @@ static void ffs_data_closed(struct ffs_data *ffs)
struct ffs_epfile *epfiles;
unsigned long flags;
- ENTER();
-
if (atomic_dec_and_test(&ffs->opened)) {
if (ffs->no_disconnect) {
ffs->state = FFS_DEACTIVATED;
@@ -1804,8 +1755,6 @@ static struct ffs_data *ffs_data_new(const char *dev_name)
if (!ffs)
return NULL;
- ENTER();
-
ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name);
if (!ffs->io_completion_wq) {
kfree(ffs);
@@ -1833,8 +1782,6 @@ static void ffs_data_clear(struct ffs_data *ffs)
struct ffs_epfile *epfiles;
unsigned long flags;
- ENTER();
-
ffs_closed(ffs);
BUG_ON(ffs->gadget);
@@ -1866,8 +1813,6 @@ static void ffs_data_clear(struct ffs_data *ffs)
static void ffs_data_reset(struct ffs_data *ffs)
{
- ENTER();
-
ffs_data_clear(ffs);
ffs->raw_descs_data = NULL;
@@ -1901,8 +1846,6 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
struct usb_gadget_strings **lang;
int first_id;
- ENTER();
-
if ((ffs->state != FFS_ACTIVE
|| test_and_set_bit(FFS_FL_BOUND, &ffs->flags)))
return -EBADFD;
@@ -1934,8 +1877,6 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
static void functionfs_unbind(struct ffs_data *ffs)
{
- ENTER();
-
if (!WARN_ON(!ffs->gadget)) {
/* dequeue before freeing ep0req */
usb_ep_dequeue(ffs->gadget->ep0, ffs->ep0req);
@@ -1954,8 +1895,6 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
struct ffs_epfile *epfile, *epfiles;
unsigned i, count;
- ENTER();
-
count = ffs->eps_count;
epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL);
if (!epfiles)
@@ -1986,8 +1925,6 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
{
struct ffs_epfile *epfile = epfiles;
- ENTER();
-
for (; count; --count, ++epfile) {
BUG_ON(mutex_is_locked(&epfile->mutex));
__ffs_epfile_read_buffer_free(epfile);
@@ -2111,8 +2048,6 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
u8 length;
int ret;
- ENTER();
-
/* At least two bytes are required: length and type */
if (len < 2) {
pr_vdebug("descriptor too short\n");
@@ -2251,8 +2186,6 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
unsigned long num = 0;
int current_class = -1;
- ENTER();
-
for (;;) {
int ret;
@@ -2290,8 +2223,6 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
struct ffs_desc_helper *helper = priv;
struct usb_endpoint_descriptor *d;
- ENTER();
-
switch (type) {
case FFS_DESCRIPTOR:
break;
@@ -2373,8 +2304,6 @@ static int __must_check ffs_do_single_os_desc(char *data, unsigned len,
int ret;
const unsigned _len = len;
- ENTER();
-
/* loop over all ext compat/ext prop descriptors */
while (feature_count--) {
ret = entity(type, h, data, len, priv);
@@ -2396,8 +2325,6 @@ static int __must_check ffs_do_os_descs(unsigned count,
const unsigned _len = len;
unsigned long num = 0;
- ENTER();
-
for (num = 0; num < count; ++num) {
int ret;
enum ffs_os_desc_type type;
@@ -2460,8 +2387,6 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
struct ffs_data *ffs = priv;
u8 length;
- ENTER();
-
switch (type) {
case FFS_OS_DESC_EXT_COMPAT: {
struct usb_ext_compat_desc *d = data;
@@ -2537,8 +2462,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
int ret = -EINVAL, i;
struct ffs_desc_helper helper;
- ENTER();
-
if (get_unaligned_le32(data + 4) != len)
goto error;
@@ -2669,8 +2592,6 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
const char *data = _data;
struct usb_string *s;
- ENTER();
-
if (len < 16 ||
get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
get_unaligned_le32(data + 4) != len)
@@ -3129,8 +3050,6 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
struct ffs_data *ffs_data;
int ret;
- ENTER();
-
/*
* Legacy gadget triggers binding in functionfs_ready_callback,
* which already uses locking; taking the same lock here would
@@ -3207,8 +3126,6 @@ static int _ffs_func_bind(struct usb_configuration *c,
vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length);
char *vlabuf;
- ENTER();
-
/* Has descriptors only for speeds gadget does not support */
if (!(full | high | super))
return -ENOTSUPP;
@@ -3411,8 +3328,6 @@ static int ffs_func_setup(struct usb_function *f,
unsigned long flags;
int ret;
- ENTER();
-
pr_vdebug("creq->bRequestType = %02x\n", creq->bRequestType);
pr_vdebug("creq->bRequest = %02x\n", creq->bRequest);
pr_vdebug("creq->wValue = %04x\n", le16_to_cpu(creq->wValue));
@@ -3487,13 +3402,11 @@ static bool ffs_func_req_match(struct usb_function *f,
static void ffs_func_suspend(struct usb_function *f)
{
- ENTER();
ffs_event_add(ffs_func_from_usb(f)->ffs, FUNCTIONFS_SUSPEND);
}
static void ffs_func_resume(struct usb_function *f)
{
- ENTER();
ffs_event_add(ffs_func_from_usb(f)->ffs, FUNCTIONFS_RESUME);
}
@@ -3657,7 +3570,6 @@ static void ffs_func_unbind(struct usb_configuration *c,
unsigned count = ffs->eps_count;
unsigned long flags;
- ENTER();
if (ffs->func == func) {
ffs_func_eps_disable(func);
ffs->func = NULL;
@@ -3697,8 +3609,6 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
{
struct ffs_function *func;
- ENTER();
-
func = kzalloc(sizeof(*func), GFP_KERNEL);
if (!func)
return ERR_PTR(-ENOMEM);
@@ -3799,7 +3709,6 @@ static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data)
int ret = 0;
struct ffs_dev *ffs_dev;
- ENTER();
ffs_dev_lock();
ffs_dev = _ffs_find_dev(dev_name);
@@ -3822,7 +3731,6 @@ static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data)
static void ffs_release_dev(struct ffs_dev *ffs_dev)
{
- ENTER();
ffs_dev_lock();
if (ffs_dev && ffs_dev->mounted) {
@@ -3844,7 +3752,6 @@ static int ffs_ready(struct ffs_data *ffs)
struct ffs_dev *ffs_obj;
int ret = 0;
- ENTER();
ffs_dev_lock();
ffs_obj = ffs->private_data;
@@ -3877,7 +3784,6 @@ static void ffs_closed(struct ffs_data *ffs)
struct f_fs_opts *opts;
struct config_item *ci;
- ENTER();
ffs_dev_lock();
ffs_obj = ffs->private_data;
diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h
index f102ec23f3afd..4b3365f23fd75 100644
--- a/drivers/usb/gadget/function/u_fs.h
+++ b/drivers/usb/gadget/function/u_fs.h
@@ -32,8 +32,6 @@
# define ffs_dump_mem(prefix, ptr, len) do { } while (0)
#endif /* VERBOSE_DEBUG */
-#define ENTER() pr_vdebug("%s()\n", __func__)
-
struct f_fs_opts;
struct ffs_dev {
diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c
index ae6d8f7092b8e..097854683e5b3 100644
--- a/drivers/usb/gadget/legacy/g_ffs.c
+++ b/drivers/usb/gadget/legacy/g_ffs.c
@@ -180,8 +180,6 @@ static int __init gfs_init(void)
int i;
int ret = 0;
- ENTER();
-
if (func_num < 2) {
gfs_single_func = true;
func_num = 1;
@@ -242,8 +240,6 @@ static void __exit gfs_exit(void)
{
int i;
- ENTER();
-
if (gfs_registered)
usb_composite_unregister(&gfs_driver);
gfs_registered = false;
@@ -316,8 +312,6 @@ static int gfs_bind(struct usb_composite_dev *cdev)
#endif
int ret, i;
- ENTER();
-
if (missing_funcs)
return -ENODEV;
#if defined CONFIG_USB_FUNCTIONFS_ETH
@@ -445,9 +439,6 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
{
int i;
- ENTER();
-
-
#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
usb_put_function(f_rndis);
usb_put_function_instance(fi_rndis);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0905/1887] usb: gadget: Support already-mapped DMA SGs
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (903 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0904/1887] usb: gadget: ffs: remove ENTER() macro Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0906/1887] usb: gadget: functionfs: Factorize wait-for-endpoint code Greg Kroah-Hartman
` (93 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Paul Cercueil, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Cercueil <paul@crapouillou.net>
[ Upstream commit 99f638dd49ca80538addec6b3733ddb5784c9373 ]
Add a new 'sg_was_mapped' field to the struct usb_request. This field
can be used to indicate that the scatterlist associated to the USB
transfer has already been mapped into the DMA space, and it does not
have to be done internally.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Link: https://lore.kernel.org/r/20240130122340.54813-2-paul@crapouillou.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: e5bf5ee26663 ("functionfs: fix the open/removal races")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/udc/core.c | 7 ++++++-
include/linux/usb/gadget.h | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index addcff2f77110..bc9c060c9e27d 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -913,6 +913,11 @@ int usb_gadget_map_request_by_dev(struct device *dev,
if (req->length == 0)
return 0;
+ if (req->sg_was_mapped) {
+ req->num_mapped_sgs = req->num_sgs;
+ return 0;
+ }
+
if (req->num_sgs) {
int mapped;
@@ -958,7 +963,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_map_request);
void usb_gadget_unmap_request_by_dev(struct device *dev,
struct usb_request *req, int is_in)
{
- if (req->length == 0)
+ if (req->length == 0 || req->sg_was_mapped)
return;
if (req->num_mapped_sgs) {
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 14090bafe5ac7..ea15f30198570 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -53,6 +53,7 @@ struct usb_ep;
* @short_not_ok: When reading data, makes short packets be
* treated as errors (queue stops advancing till cleanup).
* @dma_mapped: Indicates if request has been mapped to DMA (internal)
+ * @sg_was_mapped: Set if the scatterlist has been mapped before the request
* @complete: Function called when request completes, so this request and
* its buffer may be re-used. The function will always be called with
* interrupts disabled, and it must not sleep.
@@ -113,6 +114,7 @@ struct usb_request {
unsigned zero:1;
unsigned short_not_ok:1;
unsigned dma_mapped:1;
+ unsigned sg_was_mapped:1;
void (*complete)(struct usb_ep *ep,
struct usb_request *req);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0906/1887] usb: gadget: functionfs: Factorize wait-for-endpoint code
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (904 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0905/1887] usb: gadget: Support already-mapped DMA SGs Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0907/1887] functionfs, gadgetfs: use simple_recursive_removal() Greg Kroah-Hartman
` (92 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Paul Cercueil, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Cercueil <paul@crapouillou.net>
[ Upstream commit 799970a5b15deec8bbcb098b11a73d8acc55d075 ]
This exact same code was duplicated in two different places.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Link: https://lore.kernel.org/r/20240130122340.54813-3-paul@crapouillou.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: e5bf5ee26663 ("functionfs: fix the open/removal races")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 48 +++++++++++++++++-------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 3a1f823d71acf..e3a4d5819f004 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -952,31 +952,44 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile,
return ret;
}
-static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+static struct ffs_ep *ffs_epfile_wait_ep(struct file *file)
{
struct ffs_epfile *epfile = file->private_data;
- struct usb_request *req;
struct ffs_ep *ep;
- char *data = NULL;
- ssize_t ret, data_len = -EINVAL;
- int halt;
-
- /* Are we still active? */
- if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
- return -ENODEV;
+ int ret;
/* Wait for endpoint to be enabled */
ep = epfile->ep;
if (!ep) {
if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ return ERR_PTR(-EAGAIN);
ret = wait_event_interruptible(
epfile->ffs->wait, (ep = epfile->ep));
if (ret)
- return -EINTR;
+ return ERR_PTR(-EINTR);
}
+ return ep;
+}
+
+static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+{
+ struct ffs_epfile *epfile = file->private_data;
+ struct usb_request *req;
+ struct ffs_ep *ep;
+ char *data = NULL;
+ ssize_t ret, data_len = -EINVAL;
+ int halt;
+
+ /* Are we still active? */
+ if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
+ return -ENODEV;
+
+ ep = ffs_epfile_wait_ep(file);
+ if (IS_ERR(ep))
+ return PTR_ERR(ep);
+
/* Do we halt? */
halt = (!io_data->read == !epfile->in);
if (halt && epfile->isoc)
@@ -1308,16 +1321,9 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
return -ENODEV;
/* Wait for endpoint to be enabled */
- ep = epfile->ep;
- if (!ep) {
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
- ret = wait_event_interruptible(
- epfile->ffs->wait, (ep = epfile->ep));
- if (ret)
- return -EINTR;
- }
+ ep = ffs_epfile_wait_ep(file);
+ if (IS_ERR(ep))
+ return PTR_ERR(ep);
spin_lock_irq(&epfile->ffs->eps_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0907/1887] functionfs, gadgetfs: use simple_recursive_removal()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (905 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0906/1887] usb: gadget: functionfs: Factorize wait-for-endpoint code Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0908/1887] functionfs: fix the open/removal races Greg Kroah-Hartman
` (91 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner, Al Viro,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
[ Upstream commit bad356bb50e64170f8af14a00797a04313846aeb ]
usual mount leaks if something had been bound on top of disappearing
files there.
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Stable-dep-of: e5bf5ee26663 ("functionfs: fix the open/removal races")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 3 +--
drivers/usb/gadget/legacy/inode.c | 7 +------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index e3a4d5819f004..42095e9b472fa 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1935,8 +1935,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
BUG_ON(mutex_is_locked(&epfile->mutex));
__ffs_epfile_read_buffer_free(epfile);
if (epfile->dentry) {
- d_delete(epfile->dentry);
- dput(epfile->dentry);
+ simple_recursive_removal(epfile->dentry, NULL);
epfile->dentry = NULL;
}
}
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index 471f3f83753b0..9ef922c537b4b 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -1547,7 +1547,6 @@ static void destroy_ep_files (struct dev_data *dev)
spin_lock_irq (&dev->lock);
while (!list_empty(&dev->epfiles)) {
struct ep_data *ep;
- struct inode *parent;
struct dentry *dentry;
/* break link to FS */
@@ -1557,7 +1556,6 @@ static void destroy_ep_files (struct dev_data *dev)
dentry = ep->dentry;
ep->dentry = NULL;
- parent = d_inode(dentry->d_parent);
/* break link to controller */
mutex_lock(&ep->lock);
@@ -1572,10 +1570,7 @@ static void destroy_ep_files (struct dev_data *dev)
put_ep (ep);
/* break link to dcache */
- inode_lock(parent);
- d_delete (dentry);
- dput (dentry);
- inode_unlock(parent);
+ simple_recursive_removal(dentry, NULL);
spin_lock_irq (&dev->lock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0908/1887] functionfs: fix the open/removal races
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (906 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0907/1887] functionfs, gadgetfs: use simple_recursive_removal() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0909/1887] MIPS: ftrace: Fix memory corruption when kernel is located beyond 32 bits Greg Kroah-Hartman
` (90 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Al Viro, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
[ Upstream commit e5bf5ee266633cb18fff6f98f0b7d59a62819eee ]
ffs_epfile_open() can race with removal, ending up with file->private_data
pointing to freed object.
There is a total count of opened files on functionfs (both ep0 and
dynamic ones) and when it hits zero, dynamic files get removed.
Unfortunately, that removal can happen while another thread is
in ffs_epfile_open(), but has not incremented the count yet.
In that case open will succeed, leaving us with UAF on any subsequent
read() or write().
The root cause is that ffs->opened is misused; atomic_dec_and_test() vs.
atomic_add_return() is not a good idea, when object remains visible all
along.
To untangle that
* serialize openers on ffs->mutex (both for ep0 and for dynamic files)
* have dynamic ones use atomic_inc_not_zero() and fail if we had
zero ->opened; in that case the file we are opening is doomed.
* have the inodes of dynamic files marked on removal (from the
callback of simple_recursive_removal()) - clear ->i_private there.
* have open of dynamic ones verify they hadn't been already removed,
along with checking that state is FFS_ACTIVE.
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 54 ++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 42095e9b472fa..b3979b24e3186 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -613,13 +613,22 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
static int ffs_ep0_open(struct inode *inode, struct file *file)
{
- struct ffs_data *ffs = inode->i_private;
+ struct ffs_data *ffs = inode->i_sb->s_fs_info;
+ int ret;
- if (ffs->state == FFS_CLOSING)
- return -EBUSY;
+ /* Acquire mutex */
+ ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
+ if (ret < 0)
+ return ret;
- file->private_data = ffs;
ffs_data_opened(ffs);
+ if (ffs->state == FFS_CLOSING) {
+ ffs_data_closed(ffs);
+ mutex_unlock(&ffs->mutex);
+ return -EBUSY;
+ }
+ mutex_unlock(&ffs->mutex);
+ file->private_data = ffs;
return stream_open(inode, file);
}
@@ -1177,14 +1186,34 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
static int
ffs_epfile_open(struct inode *inode, struct file *file)
{
- struct ffs_epfile *epfile = inode->i_private;
+ struct ffs_data *ffs = inode->i_sb->s_fs_info;
+ struct ffs_epfile *epfile;
+ int ret;
- if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
+ /* Acquire mutex */
+ ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
+ if (ret < 0)
+ return ret;
+
+ if (!atomic_inc_not_zero(&ffs->opened)) {
+ mutex_unlock(&ffs->mutex);
return -ENODEV;
+ }
+ refcount_inc(&ffs->ref);
+ /*
+ * we want the state to be FFS_ACTIVE; FFS_ACTIVE alone is
+ * not enough, though - we might have been through FFS_CLOSING
+ * and back to FFS_ACTIVE, with our file already removed.
+ */
+ epfile = smp_load_acquire(&inode->i_private);
+ if (unlikely(ffs->state != FFS_ACTIVE || !epfile)) {
+ mutex_unlock(&ffs->mutex);
+ ffs_data_closed(ffs);
+ return -ENODEV;
+ }
+ mutex_unlock(&ffs->mutex);
file->private_data = epfile;
- ffs_data_opened(epfile->ffs);
-
return stream_open(inode, file);
}
@@ -1303,7 +1332,7 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
static int
ffs_epfile_release(struct inode *inode, struct file *file)
{
- struct ffs_epfile *epfile = inode->i_private;
+ struct ffs_epfile *epfile = file->private_data;
ffs_data_closed(epfile->ffs);
@@ -1927,6 +1956,11 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
return 0;
}
+static void clear_one(struct dentry *dentry)
+{
+ smp_store_release(&dentry->d_inode->i_private, NULL);
+}
+
static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
{
struct ffs_epfile *epfile = epfiles;
@@ -1935,7 +1969,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
BUG_ON(mutex_is_locked(&epfile->mutex));
__ffs_epfile_read_buffer_free(epfile);
if (epfile->dentry) {
- simple_recursive_removal(epfile->dentry, NULL);
+ simple_recursive_removal(epfile->dentry, clear_one);
epfile->dentry = NULL;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0909/1887] MIPS: ftrace: Fix memory corruption when kernel is located beyond 32 bits
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (907 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0908/1887] functionfs: fix the open/removal races Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0910/1887] drm/msm/dpu: Add missing NULL pointer check for pingpong interface Greg Kroah-Hartman
` (89 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory CLEMENT, Thomas Bogendoerfer,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory CLEMENT <gregory.clement@bootlin.com>
[ Upstream commit 36dac9a3dda1f2bae343191bc16b910c603cac25 ]
Since commit e424054000878 ("MIPS: Tracing: Reduce the overhead of
dynamic Function Tracer"), the macro UASM_i_LA_mostly has been used,
and this macro can generate more than 2 instructions. At the same
time, the code in ftrace assumes that no more than 2 instructions can
be generated, which is why it stores them in an int[2] array. However,
as previously noted, the macro UASM_i_LA_mostly (and now UASM_i_LA)
causes a buffer overflow when _mcount is beyond 32 bits. This leads to
corruption of the variables located in the __read_mostly section.
This corruption was observed because the variable
__cpu_primary_thread_mask was corrupted, causing a hang very early
during boot.
This fix prevents the corruption by avoiding the generation of
instructions if they could exceed 2 instructions in
length. Fortunately, insn_la_mcount is only used if the instrumented
code is located outside the kernel code section, so dynamic ftrace can
still be used, albeit in a more limited scope. This is still
preferable to corrupting memory and/or crashing the kernel.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/kernel/ftrace.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index f39e85fd58fa9..b15615b285690 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -54,10 +54,20 @@ static inline void ftrace_dyn_arch_init_insns(void)
u32 *buf;
unsigned int v1;
- /* la v1, _mcount */
- v1 = 3;
- buf = (u32 *)&insn_la_mcount[0];
- UASM_i_LA(&buf, v1, MCOUNT_ADDR);
+ /* If we are not in compat space, the number of generated
+ * instructions will exceed the maximum expected limit of 2.
+ * To prevent buffer overflow, we avoid generating them.
+ * insn_la_mcount will not be used later in ftrace_make_call.
+ */
+ if (uasm_in_compat_space_p(MCOUNT_ADDR)) {
+ /* la v1, _mcount */
+ v1 = 3;
+ buf = (u32 *)&insn_la_mcount[0];
+ UASM_i_LA(&buf, v1, MCOUNT_ADDR);
+ } else {
+ pr_warn("ftrace: mcount address beyond 32 bits is not supported (%lX)\n",
+ MCOUNT_ADDR);
+ }
/* jal (ftrace_caller + 8), jump over the first two instruction */
buf = (u32 *)&insn_jal_ftrace_caller;
@@ -189,6 +199,13 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
unsigned int new;
unsigned long ip = rec->ip;
+ /* When the code to patch does not belong to the kernel code
+ * space, we must use insn_la_mcount. However, if MCOUNT_ADDR
+ * is not in compat space, insn_la_mcount is not usable.
+ */
+ if (!core_kernel_text(ip) && !uasm_in_compat_space_p(MCOUNT_ADDR))
+ return -EFAULT;
+
new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
#ifdef CONFIG_64BIT
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0910/1887] drm/msm/dpu: Add missing NULL pointer check for pingpong interface
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (908 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0909/1887] MIPS: ftrace: Fix memory corruption when kernel is located beyond 32 bits Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0911/1887] net: dsa: properly keep track of conduit reference Greg Kroah-Hartman
` (88 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolay Kuratov, Dmitry Baryshkov,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Kuratov <kniv@yandex-team.ru>
[ Upstream commit 88733a0b64872357e5ecd82b7488121503cb9cc6 ]
It is checked almost always in dpu_encoder_phys_wb_setup_ctl(), but in a
single place the check is missing.
Also use convenient locals instead of phys_enc->* where available.
Cc: stable@vger.kernel.org
Fixes: d7d0e73f7de33 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback")
Signed-off-by: Nikolay Kuratov <kniv@yandex-team.ru>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/693860/
Link: https://lore.kernel.org/r/20251211093630.171014-1-kniv@yandex-team.ru
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 462fa58c660df..d76c7a2e44bf2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -212,14 +212,12 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
if (mode_3d && hw_pp && hw_pp->merge_3d)
intf_cfg.merge_3d = hw_pp->merge_3d->idx;
- if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)
- phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
- mode_3d);
+ if (hw_pp && hw_pp->merge_3d && hw_pp->merge_3d->ops.setup_3d_mode)
+ hw_pp->merge_3d->ops.setup_3d_mode(hw_pp->merge_3d, mode_3d);
/* setup which pp blk will connect to this wb */
- if (hw_pp && phys_enc->hw_wb->ops.bind_pingpong_blk)
- phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, true,
- phys_enc->hw_pp->idx);
+ if (hw_pp && hw_wb->ops.bind_pingpong_blk)
+ hw_wb->ops.bind_pingpong_blk(hw_wb, true, hw_pp->idx);
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
} else if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0911/1887] net: dsa: properly keep track of conduit reference
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (909 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0910/1887] drm/msm/dpu: Add missing NULL pointer check for pingpong interface Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0912/1887] btrfs: fix NULL dereference on root when tracing inode eviction Greg Kroah-Hartman
` (87 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ma Ke, Jonas Gorski, Vladimir Oltean,
Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <vladimir.oltean@nxp.com>
[ Upstream commit 06e219f6a706c367c93051f408ac61417643d2f9 ]
Problem description
-------------------
DSA has a mumbo-jumbo of reference handling of the conduit net device
and its kobject which, sadly, is just wrong and doesn't make sense.
There are two distinct problems.
1. The OF path, which uses of_find_net_device_by_node(), never releases
the elevated refcount on the conduit's kobject. Nominally, the OF and
non-OF paths should result in objects having identical reference
counts taken, and it is already suspicious that
dsa_dev_to_net_device() has a put_device() call which is missing in
dsa_port_parse_of(), but we can actually even verify that an issue
exists. With CONFIG_DEBUG_KOBJECT_RELEASE=y, if we run this command
"before" and "after" applying this patch:
(unbind the conduit driver for net device eno2)
echo 0000:00:00.2 > /sys/bus/pci/drivers/fsl_enetc/unbind
we see these lines in the output diff which appear only with the patch
applied:
kobject: 'eno2' (ffff002009a3a6b8): kobject_release, parent 0000000000000000 (delayed 1000)
kobject: '109' (ffff0020099d59a0): kobject_release, parent 0000000000000000 (delayed 1000)
2. After we find the conduit interface one way (OF) or another (non-OF),
it can get unregistered at any time, and DSA remains with a long-lived,
but in this case stale, cpu_dp->conduit pointer. Holding the net
device's underlying kobject isn't actually of much help, it just
prevents it from being freed (but we never need that kobject
directly). What helps us to prevent the net device from being
unregistered is the parallel netdev reference mechanism (dev_hold()
and dev_put()).
Actually we actually use that netdev tracker mechanism implicitly on
user ports since commit 2f1e8ea726e9 ("net: dsa: link interfaces with
the DSA master to get rid of lockdep warnings"), via netdev_upper_dev_link().
But time still passes at DSA switch probe time between the initial
of_find_net_device_by_node() code and the user port creation time, time
during which the conduit could unregister itself and DSA wouldn't know
about it.
So we have to run of_find_net_device_by_node() under rtnl_lock() to
prevent that from happening, and release the lock only with the netdev
tracker having acquired the reference.
Do we need to keep the reference until dsa_unregister_switch() /
dsa_switch_shutdown()?
1: Maybe yes. A switch device will still be registered even if all user
ports failed to probe, see commit 86f8b1c01a0a ("net: dsa: Do not
make user port errors fatal"), and the cpu_dp->conduit pointers
remain valid. I haven't audited all call paths to see whether they
will actually use the conduit in lack of any user port, but if they
do, it seems safer to not rely on user ports for that reference.
2. Definitely yes. We support changing the conduit which a user port is
associated to, and we can get into a situation where we've moved all
user ports away from a conduit, thus no longer hold any reference to
it via the net device tracker. But we shouldn't let it go nonetheless
- see the next change in relation to dsa_tree_find_first_conduit()
and LAG conduits which disappear.
We have to be prepared to return to the physical conduit, so the CPU
port must explicitly keep another reference to it. This is also to
say: the user ports and their CPU ports may not always keep a
reference to the same conduit net device, and both are needed.
As for the conduit's kobject for the /sys/class/net/ entry, we don't
care about it, we can release it as soon as we hold the net device
object itself.
History and blame attribution
-----------------------------
The code has been refactored so many times, it is very difficult to
follow and properly attribute a blame, but I'll try to make a short
history which I hope to be correct.
We have two distinct probing paths:
- one for OF, introduced in 2016 in commit 83c0afaec7b7 ("net: dsa: Add
new binding implementation")
- one for non-OF, introduced in 2017 in commit 71e0bbde0d88 ("net: dsa:
Add support for platform data")
These are both complete rewrites of the original probing paths (which
used struct dsa_switch_driver and other weird stuff, instead of regular
devices on their respective buses for register access, like MDIO, SPI,
I2C etc):
- one for OF, introduced in 2013 in commit 5e95329b701c ("dsa: add
device tree bindings to register DSA switches")
- one for non-OF, introduced in 2008 in commit 91da11f870f0 ("net:
Distributed Switch Architecture protocol support")
except for tiny bits and pieces like dsa_dev_to_net_device() which were
seemingly carried over since the original commit, and used to this day.
The point is that the original probing paths received a fix in 2015 in
the form of commit 679fb46c5785 ("net: dsa: Add missing master netdev
dev_put() calls"), but the fix never made it into the "new" (dsa2)
probing paths that can still be traced to today, and the fixed probing
path was later deleted in 2019 in commit 93e86b3bc842 ("net: dsa: Remove
legacy probing support").
That is to say, the new probing paths were never quite correct in this
area.
The existence of the legacy probing support which was deleted in 2019
explains why dsa_dev_to_net_device() returns a conduit with elevated
refcount (because it was supposed to be released during
dsa_remove_dst()). After the removal of the legacy code, the only user
of dsa_dev_to_net_device() calls dev_put(conduit) immediately after this
function returns. This pattern makes no sense today, and can only be
interpreted historically to understand why dev_hold() was there in the
first place.
Change details
--------------
Today we have a better netdev tracking infrastructure which we should
use. Logically netdev_hold() belongs in common code
(dsa_port_parse_cpu(), where dp->conduit is assigned), but there is a
tradeoff to be made with the rtnl_lock() section which would become a
bit too long if we did that - dsa_port_parse_cpu() also calls
request_module(). So we duplicate a bit of logic in order for the
callers of dsa_port_parse_cpu() to be the ones responsible of holding
the conduit reference and releasing it on error. This shortens the
rtnl_lock() section significantly.
In the dsa_switch_probe() error path, dsa_switch_release_ports() will be
called in a number of situations, one being where dsa_port_parse_cpu()
maybe didn't get the chance to run at all (a different port failed
earlier, etc). So we have to test for the conduit being NULL prior to
calling netdev_put().
There have still been so many transformations to the code since the
blamed commits (rename master -> conduit, commit 0650bf52b31f ("net:
dsa: be compatible with masters which unregister on shutdown")), that it
only makes sense to fix the code using the best methods available today
and see how it can be backported to stable later. I suspect the fix
cannot even be backported to kernels which lack dsa_switch_shutdown(),
and I suspect this is also maybe why the long-lived conduit reference
didn't make it into the new DSA probing paths at the time (problems
during shutdown).
Because dsa_dev_to_net_device() has a single call site and has to be
changed anyway, the logic was just absorbed into the non-OF
dsa_port_parse().
Tested on the ocelot/felix switch and on dsa_loop, both on the NXP
LS1028A with CONFIG_DEBUG_KOBJECT_RELEASE=y.
Reported-by: Ma Ke <make24@iscas.ac.cn>
Closes: https://lore.kernel.org/netdev/20251214131204.4684-1-make24@iscas.ac.cn/
Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation")
Fixes: 71e0bbde0d88 ("net: dsa: Add support for platform data")
Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20251215150236.3931670-1-vladimir.oltean@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/dsa.h | 1 +
net/dsa/dsa2.c | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index e26bace774799..9e5f04dac4204 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -310,6 +310,7 @@ struct dsa_port {
struct devlink_port devlink_port;
struct phylink *pl;
struct phylink_config pl_config;
+ netdevice_tracker conduit_tracker;
struct dsa_lag *lag;
struct net_device *hsr_dev;
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 9ecb5e34e484e..51befa73bfd69 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -1541,14 +1541,25 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
if (ethernet) {
struct net_device *master;
const char *user_protocol;
+ int err;
+ rtnl_lock();
master = of_find_net_device_by_node(ethernet);
of_node_put(ethernet);
- if (!master)
+ if (!master) {
+ rtnl_unlock();
return -EPROBE_DEFER;
+ }
+
+ netdev_hold(master, &dp->conduit_tracker, GFP_KERNEL);
+ put_device(&master->dev);
+ rtnl_unlock();
user_protocol = of_get_property(dn, "dsa-tag-protocol", NULL);
- return dsa_port_parse_cpu(dp, master, user_protocol);
+ err = dsa_port_parse_cpu(dp, master, user_protocol);
+ if (err)
+ netdev_put(master, &dp->conduit_tracker);
+ return err;
}
if (link)
@@ -1668,14 +1679,23 @@ static int dsa_port_parse(struct dsa_port *dp, const char *name,
{
if (!strcmp(name, "cpu")) {
struct net_device *master;
+ int err;
+ rtnl_lock();
master = dsa_dev_to_net_device(dev);
- if (!master)
+ if (!master) {
+ rtnl_unlock();
return -EPROBE_DEFER;
+ }
+ netdev_hold(master, &dp->conduit_tracker, GFP_KERNEL);
dev_put(master);
+ rtnl_unlock();
- return dsa_port_parse_cpu(dp, master, NULL);
+ err = dsa_port_parse_cpu(dp, master, NULL);
+ if (err)
+ netdev_put(master, &dp->conduit_tracker);
+ return err;
}
if (!strcmp(name, "dsa"))
@@ -1743,6 +1763,9 @@ static void dsa_switch_release_ports(struct dsa_switch *ds)
struct dsa_vlan *v, *n;
dsa_switch_for_each_port_safe(dp, next, ds) {
+ if (dsa_port_is_cpu(dp) && dp->master)
+ netdev_put(dp->master, &dp->conduit_tracker);
+
/* These are either entries that upper layers lost track of
* (probably due to bugs), or installed through interfaces
* where one does not necessarily have to remove them, like
@@ -1887,8 +1910,10 @@ void dsa_switch_shutdown(struct dsa_switch *ds)
/* Disconnect from further netdevice notifiers on the master,
* since netdev_uses_dsa() will now return false.
*/
- dsa_switch_for_each_cpu_port(dp, ds)
+ dsa_switch_for_each_cpu_port(dp, ds) {
dp->master->dsa_ptr = NULL;
+ netdev_put(dp->master, &dp->conduit_tracker);
+ }
rtnl_unlock();
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0912/1887] btrfs: fix NULL dereference on root when tracing inode eviction
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (910 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0911/1887] net: dsa: properly keep track of conduit reference Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0913/1887] phy: qcom-qusb2: Fix NULL pointer dereference on early suspend Greg Kroah-Hartman
` (86 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d991fea1b4b23b1f6bf8,
Miquel Sabaté Solà, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Sabaté Solà <mssola@mssola.com>
[ Upstream commit f157dd661339fc6f5f2b574fe2429c43bd309534 ]
When evicting an inode the first thing we do is to setup tracing for it,
which implies fetching the root's id. But in btrfs_evict_inode() the
root might be NULL, as implied in the next check that we do in
btrfs_evict_inode().
Hence, we either should set the ->root_objectid to 0 in case the root is
NULL, or we move tracing setup after checking that the root is not
NULL. Setting the rootid to 0 at least gives us the possibility to trace
this call even in the case when the root is NULL, so that's the solution
taken here.
Fixes: 1abe9b8a138c ("Btrfs: add initial tracepoint support for btrfs")
Reported-by: syzbot+d991fea1b4b23b1f6bf8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d991fea1b4b23b1f6bf8
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/trace/events/btrfs.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index b2b41b98ec6d0..dcb861e813f2f 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -225,8 +225,8 @@ DECLARE_EVENT_CLASS(btrfs__inode,
__entry->generation = BTRFS_I(inode)->generation;
__entry->last_trans = BTRFS_I(inode)->last_trans;
__entry->logged_trans = BTRFS_I(inode)->logged_trans;
- __entry->root_objectid =
- BTRFS_I(inode)->root->root_key.objectid;
+ __entry->root_objectid = BTRFS_I(inode)->root ?
+ BTRFS_I(inode)->root->root_key.objectid : 0;
),
TP_printk_btrfs("root=%llu(%s) gen=%llu ino=%llu blocks=%llu "
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0913/1887] phy: qcom-qusb2: Fix NULL pointer dereference on early suspend
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (911 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0912/1887] btrfs: fix NULL dereference on root when tracing inode eviction Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0914/1887] iio: imu: st_lsm6dsx: fix LSM6DSV sensor description Greg Kroah-Hartman
` (85 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Loic Poulain, Dmitry Baryshkov,
Abel Vesa, Vinod Koul, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Loic Poulain <loic.poulain@oss.qualcomm.com>
[ Upstream commit 1ca52c0983c34fca506921791202ed5bdafd5306 ]
Enabling runtime PM before attaching the QPHY instance as driver data
can lead to a NULL pointer dereference in runtime PM callbacks that
expect valid driver data. There is a small window where the suspend
callback may run after PM runtime enabling and before runtime forbid.
This causes a sporadic crash during boot:
```
Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a1
[...]
CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.16.7+ #116 PREEMPT
Workqueue: pm pm_runtime_work
pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : qusb2_phy_runtime_suspend+0x14/0x1e0 [phy_qcom_qusb2]
lr : pm_generic_runtime_suspend+0x2c/0x44
[...]
```
Attach the QPHY instance as driver data before enabling runtime PM to
prevent NULL pointer dereference in runtime PM callbacks.
Reorder pm_runtime_enable() and pm_runtime_forbid() to prevent a
short window where an unnecessary runtime suspend can occur.
Use the devres-managed version to ensure PM runtime is symmetrically
disabled during driver removal for proper cleanup.
Fixes: 891a96f65ac3 ("phy: qcom-qusb2: Add support for runtime PM")
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://patch.msgid.link/20251219085640.114473-1-loic.poulain@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 2ef638b32e8f0..9ee689e3ae337 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -1061,31 +1061,31 @@ static int qusb2_phy_probe(struct platform_device *pdev)
or->hsdisc_trim.override = true;
}
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ dev_set_drvdata(dev, qphy);
+
/*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
*/
+ pm_runtime_set_active(dev);
pm_runtime_forbid(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create phy, %d\n", ret);
- pm_runtime_disable(dev);
return ret;
}
qphy->phy = generic_phy;
- dev_set_drvdata(dev, qphy);
phy_set_drvdata(generic_phy, qphy);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (!IS_ERR(phy_provider))
dev_info(dev, "Registered Qcom-QUSB2 phy\n");
- else
- pm_runtime_disable(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0914/1887] iio: imu: st_lsm6dsx: fix LSM6DSV sensor description
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (912 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0913/1887] phy: qcom-qusb2: Fix NULL pointer dereference on early suspend Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0915/1887] iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection Greg Kroah-Hartman
` (84 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jonathan Cameron,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo@kernel.org>
[ Upstream commit d94fbd9231a2b4062cf5972629999402ea7dd6fa ]
Fix sensor ODR description for LSM6DSV/LSM6DSVX
Fixes: a1c6d631ff12 ("iio: imu: st_lsm6dsx: add support to LSM6DSV")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/653e14bf79bb88d8581d2bc42da2f784caaf3776.1668417770.git.lorenzo@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Stable-dep-of: c34e2e2d67b3 ("iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index d692b0f1f7622..6936db2e72f88 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -34,6 +34,13 @@
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 3KB
*
+ * - LSM6DSV/LSM6DSV16X:
+ * - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240,
+ * 480, 960
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ * - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000
+ * - FIFO size: 3KB
+ *
* - LSM9DS1/LSM6DS0:
* - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0915/1887] iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (913 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0914/1887] iio: imu: st_lsm6dsx: fix LSM6DSV sensor description Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0916/1887] wifi: mac80211: dont WARN for connections on invalid channels Greg Kroah-Hartman
` (83 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Francesco Lavra, Andy Shevchenko,
Lorenzo Bianconi, Jonathan Cameron, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Lavra <flavra@baylibre.com>
[ Upstream commit c34e2e2d67b3bb8d5a6d09b0d6dac845cdd13fb3 ]
The st_lsm6dsx_acc_channels array of struct iio_chan_spec has a non-NULL
event_spec field, indicating support for IIO events. However, event
detection is not supported for all sensors, and if userspace tries to
configure accelerometer wakeup events on a sensor device that does not
support them (e.g. LSM6DS0), st_lsm6dsx_write_event() dereferences a NULL
pointer when trying to write to the wakeup register.
Define an additional struct iio_chan_spec array whose members have a NULL
event_spec field, and use this array instead of st_lsm6dsx_acc_channels for
sensors without event detection capability.
Fixes: b5969abfa8b8 ("iio: imu: st_lsm6dsx: add motion events")
Signed-off-by: Francesco Lavra <flavra@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 6936db2e72f88..3b3a04e5d9497 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -83,6 +83,13 @@ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
+static const struct iio_chan_spec st_lsm6ds0_acc_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
@@ -124,8 +131,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
- .chan = st_lsm6dsx_acc_channels,
- .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ .chan = st_lsm6ds0_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6ds0_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6ds0_gyro_channels,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0916/1887] wifi: mac80211: dont WARN for connections on invalid channels
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (914 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0915/1887] iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0917/1887] wifi: rtw88: debugfs: support multiple adapters debugging Greg Kroah-Hartman
` (82 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+639af5aa411f2581ad38,
Johannes Berg, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 99067b58a408a384d2a45c105eb3dce980a862ce ]
It's not clear (to me) how exactly syzbot managed to hit this,
but it seems conceivable that e.g. regulatory changed and has
disabled a channel between scanning (channel is checked to be
usable by cfg80211_get_ies_channel_number) and connecting on
the channel later.
With one scenario that isn't covered elsewhere described above,
the warning isn't good, replace it with a (more informative)
error message.
Reported-by: syzbot+639af5aa411f2581ad38@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20251202102511.5a8fb5184fa3.I961ee41b8f10538a54b8565dbf03ec1696e80e03@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mlme.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 56120762c7fbf..05c7eda181968 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -452,7 +452,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
tracking ? 0 :
IEEE80211_CHAN_DISABLED)) {
- if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
+ if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT) {
+ sdata_info(sdata,
+ "unusable channel (%d MHz) for connection\n",
+ chandef->chan->center_freq);
ret = IEEE80211_CONN_DISABLE_HT |
IEEE80211_CONN_DISABLE_VHT |
IEEE80211_CONN_DISABLE_HE |
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0917/1887] wifi: rtw88: debugfs: support multiple adapters debugging
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (915 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0916/1887] wifi: mac80211: dont WARN for connections on invalid channels Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0918/1887] wifi: rtw88: Use devm_kmemdup() in rtw_set_supported_band() Greg Kroah-Hartman
` (81 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ping-Ke Shih <pkshih@realtek.com>
[ Upstream commit 8db6c1ca64664ef9b071e6eeb646023ac5b240a8 ]
Originally in order to read partial registers from large area, we write
a range value stored into a static variable and read registers according
to the static variable.
However, if we install more than one adapters supported by this driver,
the static variables will be overwritten by latter adapters. To resolve
the problem, move the static variables to struct rtw_dev for each adapter.
With changes, smatch spends too much time to parse rtw_debugfs_init():
debug.c:1289 rtw_debugfs_init() parse error: turning off implications
after 60 seconds
Move stuffs of adding debugfs entries to three rtw_debugfs_add_xxx()
functions.
Reported-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Closes: https://lore.kernel.org/linux-wireless/cd6a2acf3c2c36d938b40140b52a779516f446a9.camel@realtek.com/T/#m27662022c70d9f893ba96f6c6a8dd8fce2434dfe
Tested-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240718064155.38955-1-pkshih@realtek.com
Stable-dep-of: 2ba12401cc1f ("wifi: rtw88: Use devm_kmemdup() in rtw_set_supported_band()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/debug.c | 303 ++++++++++++---------
drivers/net/wireless/realtek/rtw88/debug.h | 2 +
drivers/net/wireless/realtek/rtw88/main.c | 1 +
drivers/net/wireless/realtek/rtw88/main.h | 3 +-
4 files changed, 180 insertions(+), 129 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index abd750c3c28e5..017783a1c2d9a 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -43,6 +43,62 @@ struct rtw_debugfs_priv {
};
};
+struct rtw_debugfs {
+ struct rtw_debugfs_priv mac_0;
+ struct rtw_debugfs_priv mac_1;
+ struct rtw_debugfs_priv mac_2;
+ struct rtw_debugfs_priv mac_3;
+ struct rtw_debugfs_priv mac_4;
+ struct rtw_debugfs_priv mac_5;
+ struct rtw_debugfs_priv mac_6;
+ struct rtw_debugfs_priv mac_7;
+ struct rtw_debugfs_priv mac_10;
+ struct rtw_debugfs_priv mac_11;
+ struct rtw_debugfs_priv mac_12;
+ struct rtw_debugfs_priv mac_13;
+ struct rtw_debugfs_priv mac_14;
+ struct rtw_debugfs_priv mac_15;
+ struct rtw_debugfs_priv mac_16;
+ struct rtw_debugfs_priv mac_17;
+ struct rtw_debugfs_priv bb_8;
+ struct rtw_debugfs_priv bb_9;
+ struct rtw_debugfs_priv bb_a;
+ struct rtw_debugfs_priv bb_b;
+ struct rtw_debugfs_priv bb_c;
+ struct rtw_debugfs_priv bb_d;
+ struct rtw_debugfs_priv bb_e;
+ struct rtw_debugfs_priv bb_f;
+ struct rtw_debugfs_priv bb_18;
+ struct rtw_debugfs_priv bb_19;
+ struct rtw_debugfs_priv bb_1a;
+ struct rtw_debugfs_priv bb_1b;
+ struct rtw_debugfs_priv bb_1c;
+ struct rtw_debugfs_priv bb_1d;
+ struct rtw_debugfs_priv bb_1e;
+ struct rtw_debugfs_priv bb_1f;
+ struct rtw_debugfs_priv bb_2c;
+ struct rtw_debugfs_priv bb_2d;
+ struct rtw_debugfs_priv bb_40;
+ struct rtw_debugfs_priv bb_41;
+ struct rtw_debugfs_priv rf_dump;
+ struct rtw_debugfs_priv tx_pwr_tbl;
+ struct rtw_debugfs_priv write_reg;
+ struct rtw_debugfs_priv h2c;
+ struct rtw_debugfs_priv rf_write;
+ struct rtw_debugfs_priv rf_read;
+ struct rtw_debugfs_priv read_reg;
+ struct rtw_debugfs_priv fix_rate;
+ struct rtw_debugfs_priv dump_cam;
+ struct rtw_debugfs_priv rsvd_page;
+ struct rtw_debugfs_priv phy_info;
+ struct rtw_debugfs_priv coex_enable;
+ struct rtw_debugfs_priv coex_info;
+ struct rtw_debugfs_priv edcca_enable;
+ struct rtw_debugfs_priv fw_crash;
+ struct rtw_debugfs_priv force_lowest_basic_rate;
+ struct rtw_debugfs_priv dm_cap;
+};
+
static const char * const rtw_dm_cap_strs[] = {
[RTW_DM_CAP_NA] = "NA",
[RTW_DM_CAP_TXGAPK] = "TXGAPK",
@@ -512,7 +568,7 @@ static int rtw_debug_get_bb_page(struct seq_file *m, void *v)
return 0;
}
-static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
+static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v)
{
struct rtw_debugfs_priv *debugfs_priv = m->private;
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
@@ -1060,139 +1116,102 @@ static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
return 0;
}
-#define rtw_debug_impl_mac(page, addr) \
-static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
+#define rtw_debug_priv_mac(addr) \
+{ \
.cb_read = rtw_debug_get_mac_page, \
.cb_data = addr, \
}
-rtw_debug_impl_mac(0, 0x0000);
-rtw_debug_impl_mac(1, 0x0100);
-rtw_debug_impl_mac(2, 0x0200);
-rtw_debug_impl_mac(3, 0x0300);
-rtw_debug_impl_mac(4, 0x0400);
-rtw_debug_impl_mac(5, 0x0500);
-rtw_debug_impl_mac(6, 0x0600);
-rtw_debug_impl_mac(7, 0x0700);
-rtw_debug_impl_mac(10, 0x1000);
-rtw_debug_impl_mac(11, 0x1100);
-rtw_debug_impl_mac(12, 0x1200);
-rtw_debug_impl_mac(13, 0x1300);
-rtw_debug_impl_mac(14, 0x1400);
-rtw_debug_impl_mac(15, 0x1500);
-rtw_debug_impl_mac(16, 0x1600);
-rtw_debug_impl_mac(17, 0x1700);
-
-#define rtw_debug_impl_bb(page, addr) \
-static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
+#define rtw_debug_priv_bb(addr) \
+{ \
.cb_read = rtw_debug_get_bb_page, \
.cb_data = addr, \
}
-rtw_debug_impl_bb(8, 0x0800);
-rtw_debug_impl_bb(9, 0x0900);
-rtw_debug_impl_bb(a, 0x0a00);
-rtw_debug_impl_bb(b, 0x0b00);
-rtw_debug_impl_bb(c, 0x0c00);
-rtw_debug_impl_bb(d, 0x0d00);
-rtw_debug_impl_bb(e, 0x0e00);
-rtw_debug_impl_bb(f, 0x0f00);
-rtw_debug_impl_bb(18, 0x1800);
-rtw_debug_impl_bb(19, 0x1900);
-rtw_debug_impl_bb(1a, 0x1a00);
-rtw_debug_impl_bb(1b, 0x1b00);
-rtw_debug_impl_bb(1c, 0x1c00);
-rtw_debug_impl_bb(1d, 0x1d00);
-rtw_debug_impl_bb(1e, 0x1e00);
-rtw_debug_impl_bb(1f, 0x1f00);
-rtw_debug_impl_bb(2c, 0x2c00);
-rtw_debug_impl_bb(2d, 0x2d00);
-rtw_debug_impl_bb(40, 0x4000);
-rtw_debug_impl_bb(41, 0x4100);
-
-static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
- .cb_read = rtw_debug_get_rf_dump,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = {
- .cb_read = rtw_debugfs_get_tx_pwr_tbl,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
- .cb_write = rtw_debugfs_set_write_reg,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_h2c = {
- .cb_write = rtw_debugfs_set_h2c,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
- .cb_write = rtw_debugfs_set_rf_write,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
- .cb_write = rtw_debugfs_set_rf_read,
- .cb_read = rtw_debugfs_get_rf_read,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
- .cb_write = rtw_debugfs_set_read_reg,
- .cb_read = rtw_debugfs_get_read_reg,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = {
- .cb_write = rtw_debugfs_set_fix_rate,
- .cb_read = rtw_debugfs_get_fix_rate,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
- .cb_write = rtw_debugfs_set_single_input,
- .cb_read = rtw_debugfs_get_dump_cam,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
- .cb_write = rtw_debugfs_set_rsvd_page,
- .cb_read = rtw_debugfs_get_rsvd_page,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
- .cb_read = rtw_debugfs_get_phy_info,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = {
- .cb_write = rtw_debugfs_set_coex_enable,
- .cb_read = rtw_debugfs_get_coex_enable,
-};
-
-static struct rtw_debugfs_priv rtw_debug_priv_coex_info = {
- .cb_read = rtw_debugfs_get_coex_info,
-};
+#define rtw_debug_priv_get(name) \
+{ \
+ .cb_read = rtw_debugfs_get_ ##name, \
+}
-static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
- .cb_write = rtw_debugfs_set_edcca_enable,
- .cb_read = rtw_debugfs_get_edcca_enable,
-};
+#define rtw_debug_priv_set(name) \
+{ \
+ .cb_write = rtw_debugfs_set_ ##name, \
+}
-static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = {
- .cb_write = rtw_debugfs_set_fw_crash,
- .cb_read = rtw_debugfs_get_fw_crash,
-};
+#define rtw_debug_priv_set_and_get(name) \
+{ \
+ .cb_write = rtw_debugfs_set_ ##name, \
+ .cb_read = rtw_debugfs_get_ ##name, \
+}
-static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = {
- .cb_write = rtw_debugfs_set_force_lowest_basic_rate,
- .cb_read = rtw_debugfs_get_force_lowest_basic_rate,
-};
+#define rtw_debug_priv_set_single_and_get(name) \
+{ \
+ .cb_write = rtw_debugfs_set_single_input, \
+ .cb_read = rtw_debugfs_get_ ##name, \
+}
-static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
- .cb_write = rtw_debugfs_set_dm_cap,
- .cb_read = rtw_debugfs_get_dm_cap,
+static const struct rtw_debugfs rtw_debugfs_templ = {
+ .mac_0 = rtw_debug_priv_mac(0x0000),
+ .mac_1 = rtw_debug_priv_mac(0x0100),
+ .mac_2 = rtw_debug_priv_mac(0x0200),
+ .mac_3 = rtw_debug_priv_mac(0x0300),
+ .mac_4 = rtw_debug_priv_mac(0x0400),
+ .mac_5 = rtw_debug_priv_mac(0x0500),
+ .mac_6 = rtw_debug_priv_mac(0x0600),
+ .mac_7 = rtw_debug_priv_mac(0x0700),
+ .mac_10 = rtw_debug_priv_mac(0x1000),
+ .mac_11 = rtw_debug_priv_mac(0x1100),
+ .mac_12 = rtw_debug_priv_mac(0x1200),
+ .mac_13 = rtw_debug_priv_mac(0x1300),
+ .mac_14 = rtw_debug_priv_mac(0x1400),
+ .mac_15 = rtw_debug_priv_mac(0x1500),
+ .mac_16 = rtw_debug_priv_mac(0x1600),
+ .mac_17 = rtw_debug_priv_mac(0x1700),
+ .bb_8 = rtw_debug_priv_bb(0x0800),
+ .bb_9 = rtw_debug_priv_bb(0x0900),
+ .bb_a = rtw_debug_priv_bb(0x0a00),
+ .bb_b = rtw_debug_priv_bb(0x0b00),
+ .bb_c = rtw_debug_priv_bb(0x0c00),
+ .bb_d = rtw_debug_priv_bb(0x0d00),
+ .bb_e = rtw_debug_priv_bb(0x0e00),
+ .bb_f = rtw_debug_priv_bb(0x0f00),
+ .bb_18 = rtw_debug_priv_bb(0x1800),
+ .bb_19 = rtw_debug_priv_bb(0x1900),
+ .bb_1a = rtw_debug_priv_bb(0x1a00),
+ .bb_1b = rtw_debug_priv_bb(0x1b00),
+ .bb_1c = rtw_debug_priv_bb(0x1c00),
+ .bb_1d = rtw_debug_priv_bb(0x1d00),
+ .bb_1e = rtw_debug_priv_bb(0x1e00),
+ .bb_1f = rtw_debug_priv_bb(0x1f00),
+ .bb_2c = rtw_debug_priv_bb(0x2c00),
+ .bb_2d = rtw_debug_priv_bb(0x2d00),
+ .bb_40 = rtw_debug_priv_bb(0x4000),
+ .bb_41 = rtw_debug_priv_bb(0x4100),
+ .rf_dump = rtw_debug_priv_get(rf_dump),
+ .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl),
+ .write_reg = rtw_debug_priv_set(write_reg),
+ .h2c = rtw_debug_priv_set(h2c),
+ .rf_write = rtw_debug_priv_set(rf_write),
+ .rf_read = rtw_debug_priv_set_and_get(rf_read),
+ .read_reg = rtw_debug_priv_set_and_get(read_reg),
+ .fix_rate = rtw_debug_priv_set_and_get(fix_rate),
+ .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam),
+ .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page),
+ .phy_info = rtw_debug_priv_get(phy_info),
+ .coex_enable = rtw_debug_priv_set_and_get(coex_enable),
+ .coex_info = rtw_debug_priv_get(coex_info),
+ .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable),
+ .fw_crash = rtw_debug_priv_set_and_get(fw_crash),
+ .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate),
+ .dm_cap = rtw_debug_priv_set_and_get(dm_cap),
};
#define rtw_debugfs_add_core(name, mode, fopname, parent) \
do { \
- rtw_debug_priv_ ##name.rtwdev = rtwdev; \
+ struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \
+ priv->rtwdev = rtwdev; \
if (IS_ERR(debugfs_create_file(#name, mode, \
- parent, &rtw_debug_priv_ ##name,\
+ parent, priv, \
&file_ops_ ##fopname))) \
pr_debug("Unable to initialize debugfs:%s\n", \
#name); \
@@ -1205,12 +1224,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
#define rtw_debugfs_add_r(name) \
rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
-void rtw_debugfs_init(struct rtw_dev *rtwdev)
+static
+void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
{
- struct dentry *debugfs_topdir;
-
- debugfs_topdir = debugfs_create_dir("rtw88",
- rtwdev->hw->wiphy->debugfsdir);
rtw_debugfs_add_w(write_reg);
rtw_debugfs_add_rw(read_reg);
rtw_debugfs_add_w(rf_write);
@@ -1222,6 +1238,17 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
rtw_debugfs_add_r(coex_info);
rtw_debugfs_add_rw(coex_enable);
rtw_debugfs_add_w(h2c);
+ rtw_debugfs_add_r(rf_dump);
+ rtw_debugfs_add_r(tx_pwr_tbl);
+ rtw_debugfs_add_rw(edcca_enable);
+ rtw_debugfs_add_rw(fw_crash);
+ rtw_debugfs_add_rw(force_lowest_basic_rate);
+ rtw_debugfs_add_rw(dm_cap);
+}
+
+static
+void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
+{
rtw_debugfs_add_r(mac_0);
rtw_debugfs_add_r(mac_1);
rtw_debugfs_add_r(mac_2);
@@ -1238,6 +1265,11 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
rtw_debugfs_add_r(bb_d);
rtw_debugfs_add_r(bb_e);
rtw_debugfs_add_r(bb_f);
+}
+
+static
+void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)
+{
rtw_debugfs_add_r(mac_10);
rtw_debugfs_add_r(mac_11);
rtw_debugfs_add_r(mac_12);
@@ -1260,14 +1292,29 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
rtw_debugfs_add_r(bb_40);
rtw_debugfs_add_r(bb_41);
}
- rtw_debugfs_add_r(rf_dump);
- rtw_debugfs_add_r(tx_pwr_tbl);
- rtw_debugfs_add_rw(edcca_enable);
- rtw_debugfs_add_rw(fw_crash);
- rtw_debugfs_add_rw(force_lowest_basic_rate);
- rtw_debugfs_add_rw(dm_cap);
}
+void rtw_debugfs_init(struct rtw_dev *rtwdev)
+{
+ struct dentry *debugfs_topdir;
+
+ rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ),
+ GFP_KERNEL);
+ if (!rtwdev->debugfs)
+ return;
+
+ debugfs_topdir = debugfs_create_dir("rtw88",
+ rtwdev->hw->wiphy->debugfsdir);
+
+ rtw_debugfs_add_basic(rtwdev, debugfs_topdir);
+ rtw_debugfs_add_sec0(rtwdev, debugfs_topdir);
+ rtw_debugfs_add_sec1(rtwdev, debugfs_topdir);
+}
+
+void rtw_debugfs_deinit(struct rtw_dev *rtwdev)
+{
+ kfree(rtwdev->debugfs);
+}
#endif /* CONFIG_RTW88_DEBUGFS */
#ifdef CONFIG_RTW88_DEBUG
diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h
index 066792dd96afb..3db8d0bd0ed91 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.h
+++ b/drivers/net/wireless/realtek/rtw88/debug.h
@@ -31,11 +31,13 @@ enum rtw_debug_mask {
#ifdef CONFIG_RTW88_DEBUGFS
void rtw_debugfs_init(struct rtw_dev *rtwdev);
+void rtw_debugfs_deinit(struct rtw_dev *rtwdev);
void rtw_debugfs_get_simple_phy_info(struct seq_file *m);
#else
static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {}
+static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {}
#endif /* CONFIG_RTW88_DEBUGFS */
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 53c61758d57a0..6546420a8135f 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2242,6 +2242,7 @@ void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
ieee80211_unregister_hw(hw);
rtw_unset_supported_band(hw, chip);
+ rtw_debugfs_deinit(rtwdev);
}
EXPORT_SYMBOL(rtw_unregister_hw);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 2976e3fd72885..8d84ffcc29e2e 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -50,6 +50,7 @@ extern const struct ieee80211_ops rtw_ops;
#define RTW_MAX_CHANNEL_NUM_5G 49
struct rtw_dev;
+struct rtw_debugfs;
enum rtw_hci_type {
RTW_HCI_TYPE_PCIE,
@@ -2036,7 +2037,7 @@ struct rtw_dev {
bool beacon_loss;
struct completion lps_leave_check;
- struct dentry *debugfs;
+ struct rtw_debugfs *debugfs;
u8 sta_cnt;
u32 rts_threshold;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0918/1887] wifi: rtw88: Use devm_kmemdup() in rtw_set_supported_band()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (916 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0917/1887] wifi: rtw88: debugfs: support multiple adapters debugging Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0919/1887] net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels Greg Kroah-Hartman
` (80 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
[ Upstream commit 2ba12401cc1f2d970fa2e7d5b15abde3f5abd40d ]
Simplify the code by using device managed memory allocations.
This also fixes a memory leak in rtw_register_hw(). The supported bands
were not freed in the error path.
Copied from commit 145df52a8671 ("wifi: rtw89: Convert
rtw89_core_set_supported_band to use devm_*").
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/1aa7fdef-2d5b-4a31-a4e9-fac8257ed30d@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/main.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 6546420a8135f..32459c6ebecdf 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1605,11 +1605,13 @@ static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev)
static void rtw_set_supported_band(struct ieee80211_hw *hw,
const struct rtw_chip_info *chip)
{
- struct rtw_dev *rtwdev = hw->priv;
struct ieee80211_supported_band *sband;
+ struct rtw_dev *rtwdev = hw->priv;
+ struct device *dev = rtwdev->dev;
if (chip->band & RTW_BAND_2G) {
- sband = kmemdup(&rtw_band_2ghz, sizeof(*sband), GFP_KERNEL);
+ sband = devm_kmemdup(dev, &rtw_band_2ghz, sizeof(*sband),
+ GFP_KERNEL);
if (!sband)
goto err_out;
if (chip->ht_supported)
@@ -1618,7 +1620,8 @@ static void rtw_set_supported_band(struct ieee80211_hw *hw,
}
if (chip->band & RTW_BAND_5G) {
- sband = kmemdup(&rtw_band_5ghz, sizeof(*sband), GFP_KERNEL);
+ sband = devm_kmemdup(dev, &rtw_band_5ghz, sizeof(*sband),
+ GFP_KERNEL);
if (!sband)
goto err_out;
if (chip->ht_supported)
@@ -1634,13 +1637,6 @@ static void rtw_set_supported_band(struct ieee80211_hw *hw,
rtw_err(rtwdev, "failed to set supported band\n");
}
-static void rtw_unset_supported_band(struct ieee80211_hw *hw,
- const struct rtw_chip_info *chip)
-{
- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
-}
-
static void rtw_vif_smps_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
@@ -2238,10 +2234,7 @@ EXPORT_SYMBOL(rtw_register_hw);
void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
{
- const struct rtw_chip_info *chip = rtwdev->chip;
-
ieee80211_unregister_hw(hw);
- rtw_unset_supported_band(hw, chip);
rtw_debugfs_deinit(rtwdev);
}
EXPORT_SYMBOL(rtw_unregister_hw);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0919/1887] net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (917 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0918/1887] wifi: rtw88: Use devm_kmemdup() in rtw_set_supported_band() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0920/1887] fs/ntfs3: handle attr_set_size() errors when truncating files Greg Kroah-Hartman
` (79 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johan Hovold, Chris Lew,
Manivannan Sadhasivam, Jeff Hugo, Loic Poulain, Paolo Abeni,
Sasha Levin, Jeff Johnson
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
[ Upstream commit 51731792a25cb312ca94cdccfa139eb46de1b2ef ]
MHI stack offers the 'auto_queue' feature, which allows the MHI stack to
auto queue the buffers for the RX path (DL channel). Though this feature
simplifies the client driver design, it introduces race between the client
drivers and the MHI stack. For instance, with auto_queue, the 'dl_callback'
for the DL channel may get called before the client driver is fully probed.
This means, by the time the dl_callback gets called, the client driver's
structures might not be initialized, leading to NULL ptr dereference.
Currently, the drivers have to workaround this issue by initializing the
internal structures before calling mhi_prepare_for_transfer_autoqueue().
But even so, there is a chance that the client driver's internal code path
may call the MHI queue APIs before mhi_prepare_for_transfer_autoqueue() is
called, leading to similar NULL ptr dereference. This issue has been
reported on the Qcom X1E80100 CRD machines affecting boot.
So to properly fix all these races, drop the MHI 'auto_queue' feature
altogether and let the client driver (QRTR) manage the RX buffers manually.
In the QRTR driver, queue the RX buffers based on the ring length during
probe and recycle the buffers in 'dl_callback' once they are consumed. This
also warrants removing the setting of 'auto_queue' flag from controller
drivers.
Currently, this 'auto_queue' feature is only enabled for IPCR DL channel.
So only the QRTR client driver requires the modification.
Fixes: 227fee5fc99e ("bus: mhi: core: Add an API for auto queueing buffers for DL channel")
Fixes: 68a838b84eff ("net: qrtr: start MHI channel after endpoit creation")
Reported-by: Johan Hovold <johan@kernel.org>
Closes: https://lore.kernel.org/linux-arm-msm/ZyTtVdkCCES0lkl4@hovoldconsulting.com
Suggested-by: Chris Lew <quic_clew@quicinc.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Acked-by: Jeff Johnson <jjohnson@kernel.org> # drivers/net/wireless/ath/...
Acked-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251218-qrtr-fix-v2-1-c7499bfcfbe0@oss.qualcomm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bus/mhi/host/pci_generic.c | 20 +--------
drivers/net/wireless/ath/ath11k/mhi.c | 4 --
net/qrtr/mhi.c | 61 +++++++++++++++++++++++----
3 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
index 4bb4bcd45b0a6..5a070ea4710c3 100644
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
@@ -77,22 +77,6 @@ struct mhi_pci_dev_info {
.doorbell_mode_switch = false, \
}
-#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \
- { \
- .num = ch_num, \
- .name = ch_name, \
- .num_elements = el_count, \
- .event_ring = ev_ring, \
- .dir = DMA_FROM_DEVICE, \
- .ee_mask = BIT(MHI_EE_AMSS), \
- .pollcfg = 0, \
- .doorbell = MHI_DB_BRST_DISABLE, \
- .lpm_notify = false, \
- .offload_channel = false, \
- .doorbell_mode_switch = false, \
- .auto_queue = true, \
- }
-
#define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \
{ \
.num_elements = el_count, \
@@ -231,7 +215,7 @@ static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {
MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0),
MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0),
MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0),
- MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0),
+ MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0),
MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0),
MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2),
@@ -467,7 +451,7 @@ static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = {
MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),
MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),
MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0),
- MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0),
+ MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0),
MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1),
MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2),
};
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index 4bea36cc71085..0e838721aafb2 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -60,7 +60,6 @@ static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
- .auto_queue = false,
},
{
.num = 21,
@@ -74,7 +73,6 @@ static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
- .auto_queue = true,
},
};
@@ -153,7 +151,6 @@ static struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = {
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
- .auto_queue = false,
},
{
.num = 21,
@@ -167,7 +164,6 @@ static struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = {
.lpm_notify = false,
.offload_channel = false,
.doorbell_mode_switch = false,
- .auto_queue = true,
},
};
diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c
index 9ced13c0627a7..aa9cd496b549f 100644
--- a/net/qrtr/mhi.c
+++ b/net/qrtr/mhi.c
@@ -24,13 +24,25 @@ static void qcom_mhi_qrtr_dl_callback(struct mhi_device *mhi_dev,
struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev);
int rc;
- if (!qdev || mhi_res->transaction_status)
+ if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status != -ENOTCONN))
return;
+ /* Channel got reset. So just free the buffer */
+ if (mhi_res->transaction_status == -ENOTCONN) {
+ devm_kfree(&mhi_dev->dev, mhi_res->buf_addr);
+ return;
+ }
+
rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr,
mhi_res->bytes_xferd);
if (rc == -EINVAL)
dev_err(qdev->dev, "invalid ipcrouter packet\n");
+
+ /* Done with the buffer, now recycle it for future use */
+ rc = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr,
+ mhi_dev->mhi_cntrl->buffer_len, MHI_EOT);
+ if (rc)
+ dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc);
}
/* From QRTR to MHI */
@@ -72,6 +84,29 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
return rc;
}
+static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev)
+{
+ u32 free_desc;
+ void *buf;
+ int ret;
+
+ free_desc = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
+ while (free_desc--) {
+ buf = devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl->buffer_len,
+ MHI_EOT);
+ if (ret) {
+ dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
const struct mhi_device_id *id)
{
@@ -87,20 +122,30 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
qdev->ep.xmit = qcom_mhi_qrtr_send;
dev_set_drvdata(&mhi_dev->dev, qdev);
- rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
- if (rc)
- return rc;
/* start channels */
- rc = mhi_prepare_for_transfer_autoqueue(mhi_dev);
- if (rc) {
- qrtr_endpoint_unregister(&qdev->ep);
+ rc = mhi_prepare_for_transfer(mhi_dev);
+ if (rc)
return rc;
- }
+
+ rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
+ if (rc)
+ goto err_unprepare;
+
+ rc = qcom_mhi_qrtr_queue_dl_buffers(mhi_dev);
+ if (rc)
+ goto err_unregister;
dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");
return 0;
+
+err_unregister:
+ qrtr_endpoint_unregister(&qdev->ep);
+err_unprepare:
+ mhi_unprepare_from_transfer(mhi_dev);
+
+ return rc;
}
static void qcom_mhi_qrtr_remove(struct mhi_device *mhi_dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0920/1887] fs/ntfs3: handle attr_set_size() errors when truncating files
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (918 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0919/1887] net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0921/1887] PCI: endpoint: Add missing NULL check for alloc_workqueue() Greg Kroah-Hartman
` (78 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Konstantin Komarov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ Upstream commit 576248a34b927e93b2fd3fff7df735ba73ad7d01 ]
If attr_set_size() fails while truncating down, the error is silently
ignored and the inode may be left in an inconsistent state.
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/file.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index b825862d74f95..81b51d5365f2c 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -390,8 +390,8 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
{
struct super_block *sb = inode->i_sb;
struct ntfs_inode *ni = ntfs_i(inode);
- int err, dirty = 0;
u64 new_valid;
+ int err;
if (!S_ISREG(inode->i_mode))
return 0;
@@ -407,7 +407,6 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
}
new_valid = ntfs_up_block(sb, min_t(u64, ni->i_valid, new_size));
-
truncate_setsize(inode, new_size);
ni_lock(ni);
@@ -421,20 +420,19 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
ni->i_valid = new_valid;
ni_unlock(ni);
+ if (unlikely(err))
+ return err;
ni->std_fa |= FILE_ATTRIBUTE_ARCHIVE;
inode->i_ctime = inode->i_mtime = current_time(inode);
if (!IS_DIRSYNC(inode)) {
- dirty = 1;
+ mark_inode_dirty(inode);
} else {
err = ntfs_sync_inode(inode);
if (err)
return err;
}
- if (dirty)
- mark_inode_dirty(inode);
-
/*ntfs_flush_inodes(inode->i_sb, inode, NULL);*/
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0921/1887] PCI: endpoint: Add missing NULL check for alloc_workqueue()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (919 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0920/1887] fs/ntfs3: handle attr_set_size() errors when truncating files Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0922/1887] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths Greg Kroah-Hartman
` (77 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Haotian Zhang, Manivannan Sadhasivam,
Bjorn Helgaas, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <vulab@iscas.ac.cn>
[ Upstream commit 03f336a869b3a3f119d3ae52ac9723739c7fb7b6 ]
alloc_workqueue() can return NULL on memory allocation failure. Without
proper error checking, this may lead to a NULL pointer dereference when
queue_work() is later called with the NULL workqueue pointer in
epf_ntb_epc_init().
Add a NULL check immediately after alloc_workqueue() and return -ENOMEM on
failure to prevent the driver from loading with an invalid workqueue
pointer.
Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
Fixes: 8b821cf76150 ("PCI: endpoint: Add EP function driver to provide NTB functionality")
Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20251110040446.2065-1-vulab@iscas.ac.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-ntb.c | 5 +++++
drivers/pci/endpoint/functions/pci-epf-vntb.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index e17dbcc9c8dbb..6abe474fd9405 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -2073,6 +2073,11 @@ static int __init epf_ntb_init(void)
kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |
WQ_HIGHPRI, 0);
+ if (!kpcintb_workqueue) {
+ pr_err("Failed to allocate kpcintb workqueue\n");
+ return -ENOMEM;
+ }
+
ret = pci_epf_register_driver(&epf_ntb_driver);
if (ret) {
destroy_workqueue(kpcintb_workqueue);
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 88ff306599091..15c707840cc20 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -1433,6 +1433,11 @@ static int __init epf_ntb_init(void)
kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |
WQ_HIGHPRI, 0);
+ if (!kpcintb_workqueue) {
+ pr_err("Failed to allocate kpcintb workqueue\n");
+ return -ENOMEM;
+ }
+
ret = pci_epf_register_driver(&epf_ntb_driver);
if (ret) {
destroy_workqueue(kpcintb_workqueue);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0922/1887] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (920 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0921/1887] PCI: endpoint: Add missing NULL check for alloc_workqueue() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0923/1887] drm/msm: Recover HW before retire hung submit Greg Kroah-Hartman
` (76 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Dan Carpenter,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
[ Upstream commit 41b8209376dffbd7b0b85c8bc4697d9166ac62ef ]
issue_beacon(), issue_probersp() and issue_asocrsp() obtain a management
xmit_frame together with its xmit_buf from the driver's fixed-size
management-TX pools via alloc_mgtxmitframe(). On the normal path the frame
is handed to dump_mgntframe(), which transfers ownership and eventually
returns both objects to their pools (the frame and, for beacons, the buf
in rtl8723bs_mgnt_xmit(); other bufs via the pending-xmitbuf/TX-completion
path).
Several error/edge paths return early after a successful
alloc_mgtxmitframe() but before dump_mgntframe(), so ownership is never
transferred and neither object is freed:
- issue_beacon(): beacon larger than 512 bytes
- issue_probersp(): cur_network->ie_length > MAX_IE_SZ
- issue_probersp(): kzalloc() of the SSID scratch buffer fails
- issue_asocrsp(): pkt_type is neither ASSOCRSP nor REASSOCRSP
Because alloc_mgtxmitframe() removes the frame and buf from their free
lists (list_del_init) without placing them on any pending list, an
orphaned pair is on no list and referenced by nobody, so it is only
reclaimed at driver teardown. Repeated hits progressively exhaust the
management-TX pools until alloc_mgtxmitframe() returns NULL and the
interface can no longer send beacons or probe/assoc responses.
Free the frame and buffer on these paths, matching the existing correct
error handling in issue_assocreq().
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Reviewed-by: Dan Carpenter <error27@gmail.com>
Link: https://patch.msgid.link/20260715111710.295052-1-congnt264@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 78c9425cd5f44..32fd3cd0a5f77 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -2261,8 +2261,11 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
spin_unlock_bh(&pmlmepriv->bcn_update_lock);
- if ((pattrib->pktlen + TXDESC_SIZE) > 512)
+ if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
return;
+ }
pattrib->last_txcmdsz = pattrib->pktlen;
@@ -2325,8 +2328,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
pframe += pattrib->hdrlen;
- if (cur_network->ie_length > MAX_IE_SZ)
+ if (cur_network->ie_length > MAX_IE_SZ) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
return;
+ }
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
pwps_ie = rtw_get_wps_ie(cur_network->ies+_FIXED_IE_LENGTH_, cur_network->ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
@@ -2373,8 +2379,11 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr);
buf = rtw_zmalloc(MAX_IE_SZ);
- if (!buf)
+ if (!buf) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
return;
+ }
ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, WLAN_EID_SSID, &ssid_ielen,
(pframe-ies)-_FIXED_IE_LENGTH_);
@@ -2767,10 +2776,13 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
- if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
+ if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) {
SetFrameSubType(pwlanhdr, pkt_type);
- else
+ } else {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
return;
+ }
pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
pattrib->pktlen += pattrib->hdrlen;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0923/1887] drm/msm: Recover HW before retire hung submit
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (921 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0922/1887] staging: rtl8723bs: fix xmit_frame/xmit_buf leaks on mgnt-frame error paths Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0924/1887] dst: fix races in rt6_uncached_list_del() and rt_del_uncached_list() Greg Kroah-Hartman
` (75 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jie Zhang, Akhil P Oommen,
Konrad Dybcio, Rob Clark, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Zhang <jie.zhang@oss.qualcomm.com>
[ Upstream commit b303e1d52811de7d1bcf793560754d4df68d4a1c ]
During recovery, it is not safe to retire the hung submit before we
recover the GPU. Retiring the submit triggers BO free and that can
result in GPU pagefaults since the GPU may be actively accessing those
BOs.
To fix this, retire the submits after gpu recovery is complete in
recover_worker().
Fixes: 1a370be9ac51 ("drm/msm: restart queued submits after hang")
Signed-off-by: Jie Zhang <jie.zhang@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/730655/
Message-ID: <20260605-assorted-fixes-june-v1-2-2caa04f7287c@oss.qualcomm.com>
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/msm_gpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 9385419a78dbf..f280c8f13dd49 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -422,11 +422,11 @@ static void recover_worker(struct kthread_work *work)
}
if (msm_gpu_active(gpu)) {
+ gpu->funcs->recover(gpu);
+
/* retire completed submits, plus the one that hung: */
retire_submits(gpu);
- gpu->funcs->recover(gpu);
-
/*
* Replay all remaining submits starting with highest priority
* ring
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0924/1887] dst: fix races in rt6_uncached_list_del() and rt_del_uncached_list()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (922 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0923/1887] drm/msm: Recover HW before retire hung submit Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0925/1887] pNFS: Fix a deadlock when returning a delegation during open() Greg Kroah-Hartman
` (74 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+179fc225724092b8b2b2,
Eric Dumazet, Martin KaFai Lau, David Ahern, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 9a6f0c4d5796ab89b5a28a890ce542344d58bd69 ]
syzbot was able to crash the kernel in rt6_uncached_list_flush_dev()
in an interesting way [1]
Crash happens in list_del_init()/INIT_LIST_HEAD() while writing
list->prev, while the prior write on list->next went well.
static inline void INIT_LIST_HEAD(struct list_head *list)
{
WRITE_ONCE(list->next, list); // This went well
WRITE_ONCE(list->prev, list); // Crash, @list has been freed.
}
Issue here is that rt6_uncached_list_del() did not attempt to lock
ul->lock, as list_empty(&rt->dst.rt_uncached) returned
true because the WRITE_ONCE(list->next, list) happened on the other CPU.
We might use list_del_init_careful() and list_empty_careful(),
or make sure rt6_uncached_list_del() always grabs the spinlock
whenever rt->dst.rt_uncached_list has been set.
A similar fix is neeed for IPv4.
[1]
BUG: KASAN: slab-use-after-free in INIT_LIST_HEAD include/linux/list.h:46 [inline]
BUG: KASAN: slab-use-after-free in list_del_init include/linux/list.h:296 [inline]
BUG: KASAN: slab-use-after-free in rt6_uncached_list_flush_dev net/ipv6/route.c:191 [inline]
BUG: KASAN: slab-use-after-free in rt6_disable_ip+0x633/0x730 net/ipv6/route.c:5020
Write of size 8 at addr ffff8880294cfa78 by task kworker/u8:14/3450
CPU: 0 UID: 0 PID: 3450 Comm: kworker/u8:14 Tainted: G L syzkaller #0 PREEMPT_{RT,(full)}
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025
Workqueue: netns cleanup_net
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xca/0x240 mm/kasan/report.c:482
kasan_report+0x118/0x150 mm/kasan/report.c:595
INIT_LIST_HEAD include/linux/list.h:46 [inline]
list_del_init include/linux/list.h:296 [inline]
rt6_uncached_list_flush_dev net/ipv6/route.c:191 [inline]
rt6_disable_ip+0x633/0x730 net/ipv6/route.c:5020
addrconf_ifdown+0x143/0x18a0 net/ipv6/addrconf.c:3853
addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
notifier_call_chain+0x19d/0x3a0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2268 [inline]
call_netdevice_notifiers net/core/dev.c:2282 [inline]
netif_close_many+0x29c/0x410 net/core/dev.c:1785
unregister_netdevice_many_notify+0xb50/0x2330 net/core/dev.c:12353
ops_exit_rtnl_list net/core/net_namespace.c:187 [inline]
ops_undo_list+0x3dc/0x990 net/core/net_namespace.c:248
cleanup_net+0x4de/0x7b0 net/core/net_namespace.c:696
process_one_work kernel/workqueue.c:3257 [inline]
process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3421
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246
</TASK>
Allocated by task 803:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
unpoison_slab_object mm/kasan/common.c:340 [inline]
__kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:366
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4953 [inline]
slab_alloc_node mm/slub.c:5263 [inline]
kmem_cache_alloc_noprof+0x18d/0x6c0 mm/slub.c:5270
dst_alloc+0x105/0x170 net/core/dst.c:89
ip6_dst_alloc net/ipv6/route.c:342 [inline]
icmp6_dst_alloc+0x75/0x460 net/ipv6/route.c:3333
mld_sendpack+0x683/0xe60 net/ipv6/mcast.c:1844
mld_send_cr net/ipv6/mcast.c:2154 [inline]
mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693
process_one_work kernel/workqueue.c:3257 [inline]
process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3421
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246
Freed by task 20:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x5c/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2540 [inline]
slab_free mm/slub.c:6670 [inline]
kmem_cache_free+0x18f/0x8d0 mm/slub.c:6781
dst_destroy+0x235/0x350 net/core/dst.c:121
rcu_do_batch kernel/rcu/tree.c:2605 [inline]
rcu_core kernel/rcu/tree.c:2857 [inline]
rcu_cpu_kthread+0xba5/0x1af0 kernel/rcu/tree.c:2945
smpboot_thread_fn+0x542/0xa60 kernel/smpboot.c:160
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246
Last potentially related work creation:
kasan_save_stack+0x3e/0x60 mm/kasan/common.c:57
kasan_record_aux_stack+0xbd/0xd0 mm/kasan/generic.c:556
__call_rcu_common kernel/rcu/tree.c:3119 [inline]
call_rcu+0xee/0x890 kernel/rcu/tree.c:3239
refdst_drop include/net/dst.h:266 [inline]
skb_dst_drop include/net/dst.h:278 [inline]
skb_release_head_state+0x71/0x360 net/core/skbuff.c:1156
skb_release_all net/core/skbuff.c:1180 [inline]
__kfree_skb net/core/skbuff.c:1196 [inline]
sk_skb_reason_drop+0xe9/0x170 net/core/skbuff.c:1234
kfree_skb_reason include/linux/skbuff.h:1322 [inline]
tcf_kfree_skb_list include/net/sch_generic.h:1127 [inline]
__dev_xmit_skb net/core/dev.c:4260 [inline]
__dev_queue_xmit+0x26aa/0x3210 net/core/dev.c:4785
NF_HOOK_COND include/linux/netfilter.h:307 [inline]
ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247
NF_HOOK+0x9e/0x380 include/linux/netfilter.h:318
mld_sendpack+0x8d4/0xe60 net/ipv6/mcast.c:1855
mld_send_cr net/ipv6/mcast.c:2154 [inline]
mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693
process_one_work kernel/workqueue.c:3257 [inline]
process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3421
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246
The buggy address belongs to the object at ffff8880294cfa00
which belongs to the cache ip6_dst_cache of size 232
The buggy address is located 120 bytes inside of
freed 232-byte region [ffff8880294cfa00, ffff8880294cfae8)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x294cf
memcg:ffff88803536b781
flags: 0x80000000000000(node=0|zone=1)
page_type: f5(slab)
raw: 0080000000000000 ffff88802ff1c8c0 ffffea0000bf2bc0 dead000000000006
raw: 0000000000000000 00000000800c000c 00000000f5000000 ffff88803536b781
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x52820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 9, tgid 9 (kworker/0:0), ts 91119585830, free_ts 91088628818
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x234/0x290 mm/page_alloc.c:1857
prep_new_page mm/page_alloc.c:1865 [inline]
get_page_from_freelist+0x28c0/0x2960 mm/page_alloc.c:3915
__alloc_frozen_pages_noprof+0x181/0x370 mm/page_alloc.c:5210
alloc_pages_mpol+0xd1/0x380 mm/mempolicy.c:2486
alloc_slab_page mm/slub.c:3075 [inline]
allocate_slab+0x86/0x3b0 mm/slub.c:3248
new_slab mm/slub.c:3302 [inline]
___slab_alloc+0xb10/0x13e0 mm/slub.c:4656
__slab_alloc+0xc6/0x1f0 mm/slub.c:4779
__slab_alloc_node mm/slub.c:4855 [inline]
slab_alloc_node mm/slub.c:5251 [inline]
kmem_cache_alloc_noprof+0x101/0x6c0 mm/slub.c:5270
dst_alloc+0x105/0x170 net/core/dst.c:89
ip6_dst_alloc net/ipv6/route.c:342 [inline]
icmp6_dst_alloc+0x75/0x460 net/ipv6/route.c:3333
mld_sendpack+0x683/0xe60 net/ipv6/mcast.c:1844
mld_send_cr net/ipv6/mcast.c:2154 [inline]
mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693
process_one_work kernel/workqueue.c:3257 [inline]
process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3421
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158
page last free pid 5859 tgid 5859 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1406 [inline]
__free_frozen_pages+0xfe1/0x1170 mm/page_alloc.c:2943
discard_slab mm/slub.c:3346 [inline]
__put_partials+0x149/0x170 mm/slub.c:3886
__slab_free+0x2af/0x330 mm/slub.c:5952
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x97/0x100 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x148/0x160 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x22/0x80 mm/kasan/common.c:350
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4953 [inline]
slab_alloc_node mm/slub.c:5263 [inline]
kmem_cache_alloc_noprof+0x18d/0x6c0 mm/slub.c:5270
getname_flags+0xb8/0x540 fs/namei.c:146
getname include/linux/fs.h:2498 [inline]
do_sys_openat2+0xbc/0x200 fs/open.c:1426
do_sys_open fs/open.c:1436 [inline]
__do_sys_openat fs/open.c:1452 [inline]
__se_sys_openat fs/open.c:1447 [inline]
__x64_sys_openat+0x138/0x170 fs/open.c:1447
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xec/0xf80 arch/x86/entry/syscall_64.c:94
Fixes: 8d0b94afdca8 ("ipv6: Keep track of DST_NOCACHE routes in case of iface down/unregister")
Fixes: 78df76a065ae ("ipv4: take rt_uncached_lock only if needed")
Reported-by: syzbot+179fc225724092b8b2b2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6964cdf2.050a0220.eaf7.009d.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Martin KaFai Lau <martin.lau@kernel.org>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260112103825.3810713-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/route.c | 7 +++++--
net/ipv6/route.c | 4 ++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bd0b29f3ff1d3..bd8ea5b8fa583 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1575,9 +1575,9 @@ void rt_add_uncached_list(struct rtable *rt)
void rt_del_uncached_list(struct rtable *rt)
{
- if (!list_empty(&rt->rt_uncached)) {
- struct uncached_list *ul = rt->rt_uncached_list;
+ struct uncached_list *ul = rt->rt_uncached_list;
+ if (ul) {
spin_lock_bh(&ul->lock);
list_del_init(&rt->rt_uncached);
spin_unlock_bh(&ul->lock);
@@ -1703,6 +1703,7 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
rt->rt_gw_family = 0;
rt->rt_gw4 = 0;
INIT_LIST_HEAD(&rt->rt_uncached);
+ rt->rt_uncached_list = NULL;
rt->dst.output = ip_output;
if (flags & RTCF_LOCAL)
@@ -1734,6 +1735,7 @@ struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt)
else if (rt->rt_gw_family == AF_INET6)
new_rt->rt_gw6 = rt->rt_gw6;
INIT_LIST_HEAD(&new_rt->rt_uncached);
+ new_rt->rt_uncached_list = NULL;
new_rt->dst.input = rt->dst.input;
new_rt->dst.output = rt->dst.output;
@@ -2925,6 +2927,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
rt->rt_gw6 = ort->rt_gw6;
INIT_LIST_HEAD(&rt->rt_uncached);
+ rt->rt_uncached_list = NULL;
}
dst_release(dst_orig);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 23d7a66eb0af5..1c61081a857ce 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -149,9 +149,9 @@ void rt6_uncached_list_add(struct rt6_info *rt)
void rt6_uncached_list_del(struct rt6_info *rt)
{
- if (!list_empty(&rt->rt6i_uncached)) {
- struct uncached_list *ul = rt->rt6i_uncached_list;
+ struct uncached_list *ul = rt->rt6i_uncached_list;
+ if (ul) {
spin_lock_bh(&ul->lock);
list_del_init(&rt->rt6i_uncached);
spin_unlock_bh(&ul->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0925/1887] pNFS: Fix a deadlock when returning a delegation during open()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (923 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0924/1887] dst: fix races in rt6_uncached_list_del() and rt_del_uncached_list() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0926/1887] rxrpc: Fix data-race warning and potential load/store tearing Greg Kroah-Hartman
` (73 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Coddington, Trond Myklebust,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <trond.myklebust@hammerspace.com>
[ Upstream commit 857bf9056291a16785ae3be1d291026b2437fc48 ]
Ben Coddington reports seeing a hang in the following stack trace:
0 [ffffd0b50e1774e0] __schedule at ffffffff9ca05415
1 [ffffd0b50e177548] schedule at ffffffff9ca05717
2 [ffffd0b50e177558] bit_wait at ffffffff9ca061e1
3 [ffffd0b50e177568] __wait_on_bit at ffffffff9ca05cfb
4 [ffffd0b50e1775c8] out_of_line_wait_on_bit at ffffffff9ca05ea5
5 [ffffd0b50e177618] pnfs_roc at ffffffffc154207b [nfsv4]
6 [ffffd0b50e1776b8] _nfs4_proc_delegreturn at ffffffffc1506586 [nfsv4]
7 [ffffd0b50e177788] nfs4_proc_delegreturn at ffffffffc1507480 [nfsv4]
8 [ffffd0b50e1777f8] nfs_do_return_delegation at ffffffffc1523e41 [nfsv4]
9 [ffffd0b50e177838] nfs_inode_set_delegation at ffffffffc1524a75 [nfsv4]
10 [ffffd0b50e177888] nfs4_process_delegation at ffffffffc14f41dd [nfsv4]
11 [ffffd0b50e1778a0] _nfs4_opendata_to_nfs4_state at ffffffffc1503edf [nfsv4]
12 [ffffd0b50e1778c0] _nfs4_open_and_get_state at ffffffffc1504e56 [nfsv4]
13 [ffffd0b50e177978] _nfs4_do_open at ffffffffc15051b8 [nfsv4]
14 [ffffd0b50e1779f8] nfs4_do_open at ffffffffc150559c [nfsv4]
15 [ffffd0b50e177a80] nfs4_atomic_open at ffffffffc15057fb [nfsv4]
16 [ffffd0b50e177ad0] nfs4_file_open at ffffffffc15219be [nfsv4]
17 [ffffd0b50e177b78] do_dentry_open at ffffffff9c09e6ea
18 [ffffd0b50e177ba8] vfs_open at ffffffff9c0a082e
19 [ffffd0b50e177bd0] dentry_open at ffffffff9c0a0935
The issue is that the delegreturn is being asked to wait for a layout
return that cannot complete because a state recovery was initiated. The
state recovery cannot complete until the open() finishes processing the
delegations it was given.
The solution is to propagate the existing flags that indicate a
non-blocking call to the function pnfs_roc(), so that it knows not to
wait in this situation.
Reported-by: Benjamin Coddington <bcodding@hammerspace.com>
Fixes: 29ade5db1293 ("pNFS: Wait on outstanding layoutreturns to complete in pnfs_roc()")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4proc.c | 6 ++---
fs/nfs/pnfs.c | 58 +++++++++++++++++++++++++++++++++--------------
fs/nfs/pnfs.h | 17 ++++++--------
3 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9f352f1a6eb1e..333ed7e8d4c68 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3798,8 +3798,8 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
calldata->res.seqid = calldata->arg.seqid;
calldata->res.server = server;
calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
- calldata->lr.roc = pnfs_roc(state->inode,
- &calldata->lr.arg, &calldata->lr.res, msg.rpc_cred);
+ calldata->lr.roc = pnfs_roc(state->inode, &calldata->lr.arg,
+ &calldata->lr.res, msg.rpc_cred, wait);
if (calldata->lr.roc) {
calldata->arg.lr_args = &calldata->lr.arg;
calldata->res.lr_res = &calldata->lr.res;
@@ -6748,7 +6748,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
data->inode = nfs_igrab_and_active(inode);
if (data->inode || issync) {
data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res,
- cred);
+ cred, issync);
if (data->lr.roc) {
data->args.lr_args = &data->lr.arg;
data->res.lr_res = &data->lr.res;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 99a93c63708df..26d509b6ebd10 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1427,10 +1427,9 @@ pnfs_commit_and_return_layout(struct inode *inode)
return ret;
}
-bool pnfs_roc(struct inode *ino,
- struct nfs4_layoutreturn_args *args,
- struct nfs4_layoutreturn_res *res,
- const struct cred *cred)
+bool pnfs_roc(struct inode *ino, struct nfs4_layoutreturn_args *args,
+ struct nfs4_layoutreturn_res *res, const struct cred *cred,
+ bool sync)
{
struct nfs_inode *nfsi = NFS_I(ino);
struct nfs_open_context *ctx;
@@ -1441,7 +1440,7 @@ bool pnfs_roc(struct inode *ino,
nfs4_stateid stateid;
enum pnfs_iomode iomode = 0;
bool layoutreturn = false, roc = false;
- bool skip_read = false;
+ bool skip_read;
if (!nfs_have_layout(ino))
return false;
@@ -1454,20 +1453,14 @@ bool pnfs_roc(struct inode *ino,
lo = NULL;
goto out_noroc;
}
- pnfs_get_layout_hdr(lo);
- if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) {
- spin_unlock(&ino->i_lock);
- rcu_read_unlock();
- wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN,
- TASK_UNINTERRUPTIBLE);
- pnfs_put_layout_hdr(lo);
- goto retry;
- }
/* no roc if we hold a delegation */
+ skip_read = false;
if (nfs4_check_delegation(ino, FMODE_READ)) {
- if (nfs4_check_delegation(ino, FMODE_WRITE))
+ if (nfs4_check_delegation(ino, FMODE_WRITE)) {
+ lo = NULL;
goto out_noroc;
+ }
skip_read = true;
}
@@ -1476,12 +1469,43 @@ bool pnfs_roc(struct inode *ino,
if (state == NULL)
continue;
/* Don't return layout if there is open file state */
- if (state->state & FMODE_WRITE)
+ if (state->state & FMODE_WRITE) {
+ lo = NULL;
goto out_noroc;
+ }
if (state->state & FMODE_READ)
skip_read = true;
}
+ if (skip_read) {
+ bool writes = false;
+
+ list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
+ if (lseg->pls_range.iomode != IOMODE_READ) {
+ writes = true;
+ break;
+ }
+ }
+ if (!writes) {
+ lo = NULL;
+ goto out_noroc;
+ }
+ }
+
+ pnfs_get_layout_hdr(lo);
+ if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) {
+ if (!sync) {
+ pnfs_set_plh_return_info(
+ lo, skip_read ? IOMODE_RW : IOMODE_ANY, 0);
+ goto out_noroc;
+ }
+ spin_unlock(&ino->i_lock);
+ rcu_read_unlock();
+ wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN,
+ TASK_UNINTERRUPTIBLE);
+ pnfs_put_layout_hdr(lo);
+ goto retry;
+ }
list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) {
if (skip_read && lseg->pls_range.iomode == IOMODE_READ)
@@ -1521,7 +1545,7 @@ bool pnfs_roc(struct inode *ino,
out_noroc:
spin_unlock(&ino->i_lock);
rcu_read_unlock();
- pnfs_layoutcommit_inode(ino, true);
+ pnfs_layoutcommit_inode(ino, sync);
if (roc) {
struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
if (ld->prepare_layoutreturn)
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index c95f8a26ee1b4..0cc6f9a295f2c 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -296,10 +296,9 @@ int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
u32 seq);
int pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
struct list_head *lseg_list);
-bool pnfs_roc(struct inode *ino,
- struct nfs4_layoutreturn_args *args,
- struct nfs4_layoutreturn_res *res,
- const struct cred *cred);
+bool pnfs_roc(struct inode *ino, struct nfs4_layoutreturn_args *args,
+ struct nfs4_layoutreturn_res *res, const struct cred *cred,
+ bool sync);
int pnfs_roc_done(struct rpc_task *task, struct nfs4_layoutreturn_args **argpp,
struct nfs4_layoutreturn_res **respp, int *ret);
void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
@@ -770,12 +769,10 @@ pnfs_layoutcommit_outstanding(struct inode *inode)
return false;
}
-
-static inline bool
-pnfs_roc(struct inode *ino,
- struct nfs4_layoutreturn_args *args,
- struct nfs4_layoutreturn_res *res,
- const struct cred *cred)
+static inline bool pnfs_roc(struct inode *ino,
+ struct nfs4_layoutreturn_args *args,
+ struct nfs4_layoutreturn_res *res,
+ const struct cred *cred, bool sync)
{
return false;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0926/1887] rxrpc: Fix data-race warning and potential load/store tearing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (924 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0925/1887] pNFS: Fix a deadlock when returning a delegation during open() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0927/1887] of: unittest: Fix memory leak in unittest_data_add() Greg Kroah-Hartman
` (72 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6182afad5045e6703b3d,
David Howells, Marc Dionne, Simon Horman, linux-afs, stable,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 5d5fe8bcd331f1e34e0943ec7c18432edfcf0e8b ]
Fix the following:
BUG: KCSAN: data-race in rxrpc_peer_keepalive_worker / rxrpc_send_data_packet
which is reporting an issue with the reads and writes to ->last_tx_at in:
conn->peer->last_tx_at = ktime_get_seconds();
and:
keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
The lockless accesses to these to values aren't actually a problem as the
read only needs an approximate time of last transmission for the purposes
of deciding whether or not the transmission of a keepalive packet is
warranted yet.
Also, as ->last_tx_at is a 64-bit value, tearing can occur on a 32-bit
arch.
Fix both of these by switching to an unsigned int for ->last_tx_at and only
storing the LSW of the time64_t. It can then be reconstructed at need
provided no more than 68 years has elapsed since the last transmission.
Fixes: ace45bec6d77 ("rxrpc: Fix firewall route keepalive")
Reported-by: syzbot+6182afad5045e6703b3d@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/695e7cfb.050a0220.1c677c.036b.GAE@google.com/
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/1107124.1768903985@warthog.procyon.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rxrpc/ar-internal.h | 9 ++++++++-
net/rxrpc/conn_event.c | 4 ++--
net/rxrpc/output.c | 10 +++++-----
net/rxrpc/peer_event.c | 17 ++++++++++++++++-
net/rxrpc/proc.c | 4 ++--
net/rxrpc/rxkad.c | 4 ++--
6 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 8499ceb7719c8..fbec55c7e6dc5 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -303,7 +303,7 @@ struct rxrpc_peer {
struct hlist_head error_targets; /* targets for net error distribution */
struct rb_root service_conns; /* Service connections */
struct list_head keepalive_link; /* Link in net->peer_keepalive[] */
- time64_t last_tx_at; /* Last time packet sent here */
+ unsigned int last_tx_at; /* Last time packet sent here (time64_t LSW) */
seqlock_t service_conn_lock;
spinlock_t lock; /* access lock */
unsigned int if_mtu; /* interface MTU for this peer */
@@ -986,6 +986,13 @@ void rxrpc_encap_err_rcv(struct sock *sk, struct sk_buff *skb, unsigned int udp_
void rxrpc_error_report(struct sock *);
void rxrpc_peer_keepalive_worker(struct work_struct *);
+/* Update the last transmission time on a peer for keepalive purposes. */
+static inline void rxrpc_peer_mark_tx(struct rxrpc_peer *peer)
+{
+ /* To avoid tearing on 32-bit systems, we only keep the LSW. */
+ WRITE_ONCE(peer->last_tx_at, ktime_get_seconds());
+}
+
/*
* peer_object.c
*/
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index 293922df2a891..8079094844c0e 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -142,7 +142,7 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn,
}
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, ioc, len);
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
if (ret < 0)
trace_rxrpc_tx_fail(chan->call_debug_id, serial, ret,
rxrpc_tx_point_call_final_resend);
@@ -262,7 +262,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
trace_rxrpc_tx_packet(conn->debug_id, &whdr, rxrpc_tx_point_conn_abort);
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
_leave(" = 0");
return 0;
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 3d9032fae9d91..6fb0c67ef8bb4 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -254,7 +254,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
rtt_slot = rxrpc_begin_rtt_probe(call, serial, rxrpc_rtt_tx_ping);
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
if (ret < 0)
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
rxrpc_tx_point_call_ack);
@@ -333,7 +333,7 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
ret = kernel_sendmsg(conn->params.local->socket,
&msg, iov, 1, sizeof(pkt));
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
if (ret < 0)
trace_rxrpc_tx_fail(call->debug_id, serial, ret,
rxrpc_tx_point_call_abort);
@@ -449,7 +449,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
* message and update the peer record
*/
ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
up_read(&conn->params.local->defrag_sem);
if (ret < 0) {
@@ -525,7 +525,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
IP_PMTUDISC_DONT);
ret = kernel_sendmsg(conn->params.local->socket, &msg,
iov, 2, len);
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
ip_sock_set_mtu_discover(conn->params.local->socket->sk,
IP_PMTUDISC_DO);
@@ -674,6 +674,6 @@ void rxrpc_send_keepalive(struct rxrpc_peer *peer)
trace_rxrpc_tx_packet(peer->debug_id, &whdr,
rxrpc_tx_point_version_keepalive);
- peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(peer);
_leave("");
}
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c
index 32561e9567fe3..77005c97dd904 100644
--- a/net/rxrpc/peer_event.c
+++ b/net/rxrpc/peer_event.c
@@ -515,6 +515,21 @@ static void rxrpc_distribute_error(struct rxrpc_peer *peer, int error,
}
}
+/*
+ * Reconstruct the last transmission time. The difference calculated should be
+ * valid provided no more than ~68 years elapsed since the last transmission.
+ */
+static time64_t rxrpc_peer_get_tx_mark(const struct rxrpc_peer *peer, time64_t base)
+{
+ s32 last_tx_at = READ_ONCE(peer->last_tx_at);
+ s32 base_lsw = base;
+ s32 diff = last_tx_at - base_lsw;
+
+ diff = clamp(diff, -RXRPC_KEEPALIVE_TIME, RXRPC_KEEPALIVE_TIME);
+
+ return diff + base;
+}
+
/*
* Perform keep-alive pings.
*/
@@ -541,7 +556,7 @@ static void rxrpc_peer_keepalive_dispatch(struct rxrpc_net *rxnet,
if (__rxrpc_use_local(peer->local)) {
spin_unlock_bh(&rxnet->peer_hash_lock);
- keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
+ keepalive_at = rxrpc_peer_get_tx_mark(peer, base) + RXRPC_KEEPALIVE_TIME;
slot = keepalive_at - base;
_debug("%02x peer %u t=%d {%pISp}",
cursor, peer->debug_id, slot, &peer->srx.transport);
diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index 47d36554ad311..ee07785860a01 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -234,13 +234,13 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
now = ktime_get_seconds();
seq_printf(seq,
"UDP %-47.47s %-47.47s %3u"
- " %3u %5u %6llus %8u %8u\n",
+ " %3u %5u %6ds %8u %8u\n",
lbuff,
rbuff,
refcount_read(&peer->ref),
peer->cong_cwnd,
peer->mtu,
- now - peer->last_tx_at,
+ (s32)now - (s32)READ_ONCE(peer->last_tx_at),
peer->srtt_us >> 3,
jiffies_to_usecs(peer->rto_j));
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 84a61fa18bc06..038c4f2e8cef8 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -780,7 +780,7 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
return -EAGAIN;
}
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
trace_rxrpc_tx_packet(conn->debug_id, &whdr,
rxrpc_tx_point_rxkad_challenge);
_leave(" = 0");
@@ -838,7 +838,7 @@ static int rxkad_send_response(struct rxrpc_connection *conn,
return -EAGAIN;
}
- conn->params.peer->last_tx_at = ktime_get_seconds();
+ rxrpc_peer_mark_tx(conn->params.peer);
_leave(" = 0");
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0927/1887] of: unittest: Fix memory leak in unittest_data_add()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (925 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0926/1887] rxrpc: Fix data-race warning and potential load/store tearing Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0928/1887] tracing: Add recursion protection in kernel stack trace recording Greg Kroah-Hartman
` (71 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rob Herring, Jianhao Xu, Zilin Guan,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <zilin@seu.edu.cn>
[ Upstream commit 235a1eb8d2dcc49a6cf0a5ee1aa85544a5d0054b ]
In unittest_data_add(), if of_resolve_phandles() fails, the allocated
unittest_data is not freed, leading to a memory leak.
Fix this by using scope-based cleanup helper __free(kfree) for automatic
resource cleanup. This ensures unittest_data is automatically freed when
it goes out of scope in error paths.
For the success path, use retain_and_null_ptr() to transfer ownership
of the memory to the device tree and prevent double freeing.
Fixes: 2eb46da2a760 ("of/selftest: Use the resolver to fixup phandles")
Suggested-by: Rob Herring <robh@kernel.org>
Co-developed-by: Jianhao Xu <jianhao.xu@seu.edu.cn>
Signed-off-by: Jianhao Xu <jianhao.xu@seu.edu.cn>
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Link: https://patch.msgid.link/20251231114915.234638-1-zilin@seu.edu.cn
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/of/unittest.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 598e0891533fd..2dc62174e1679 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1546,7 +1546,6 @@ static void attach_node_and_children(struct device_node *np)
*/
static int __init unittest_data_add(void)
{
- void *unittest_data;
void *unittest_data_align;
struct device_node *unittest_data_node = NULL, *np;
/*
@@ -1565,7 +1564,7 @@ static int __init unittest_data_add(void)
}
/* creating copy */
- unittest_data = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
+ void *unittest_data __free(kfree) = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
if (!unittest_data)
return -ENOMEM;
@@ -1575,12 +1574,10 @@ static int __init unittest_data_add(void)
ret = of_fdt_unflatten_tree(unittest_data_align, NULL, &unittest_data_node);
if (!ret) {
pr_warn("%s: unflatten testcases tree failed\n", __func__);
- kfree(unittest_data);
return -ENODATA;
}
if (!unittest_data_node) {
pr_warn("%s: testcases tree is empty\n", __func__);
- kfree(unittest_data);
return -ENODATA;
}
@@ -1602,6 +1599,7 @@ static int __init unittest_data_add(void)
__of_attach_node_sysfs(np);
of_aliases = of_find_node_by_path("/aliases");
of_chosen = of_find_node_by_path("/chosen");
+ no_free_ptr(unittest_data);
of_overlay_mutex_unlock();
return 0;
}
@@ -1622,6 +1620,7 @@ static int __init unittest_data_add(void)
EXPECT_END(KERN_INFO,
"Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
+ no_free_ptr(unittest_data);
of_overlay_mutex_unlock();
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0928/1887] tracing: Add recursion protection in kernel stack trace recording
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (926 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0927/1887] of: unittest: Fix memory leak in unittest_data_add() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0929/1887] bonding: fix use-after-free due to enslave fail after slave array update Greg Kroah-Hartman
` (70 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mathieu Desnoyers,
Joel Fernandes, Paul E. McKenney, Boqun Feng, Yao Kai,
Steven Rostedt (Google), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 5f1ef0dfcb5b7f4a91a9b0e0ba533efd9f7e2cdb ]
A bug was reported about an infinite recursion caused by tracing the rcu
events with the kernel stack trace trigger enabled. The stack trace code
called back into RCU which then called the stack trace again.
Expand the ftrace recursion protection to add a set of bits to protect
events from recursion. Each bit represents the context that the event is
in (normal, softirq, interrupt and NMI).
Have the stack trace code use the interrupt context to protect against
recursion.
Note, the bug showed an issue in both the RCU code as well as the tracing
stacktrace code. This only handles the tracing stack trace side of the
bug. The RCU fix will be handled separately.
Link: https://lore.kernel.org/all/20260102122807.7025fc87@gandalf.local.home/
Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Joel Fernandes <joel@joelfernandes.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Link: https://patch.msgid.link/20260105203141.515cd49f@gandalf.local.home
Reported-by: Yao Kai <yaokai34@huawei.com>
Tested-by: Yao Kai <yaokai34@huawei.com>
Fixes: 5f5fa7ea89dc ("rcu: Don't use negative nesting depth in __rcu_read_unlock()")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/trace_recursion.h | 9 +++++++++
kernel/trace/trace.c | 7 ++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h
index c303f7a114e91..2ac1853f056d5 100644
--- a/include/linux/trace_recursion.h
+++ b/include/linux/trace_recursion.h
@@ -34,6 +34,13 @@ enum {
TRACE_INTERNAL_SIRQ_BIT,
TRACE_INTERNAL_TRANSITION_BIT,
+ /* Internal event use recursion bits */
+ TRACE_INTERNAL_EVENT_BIT,
+ TRACE_INTERNAL_EVENT_NMI_BIT,
+ TRACE_INTERNAL_EVENT_IRQ_BIT,
+ TRACE_INTERNAL_EVENT_SIRQ_BIT,
+ TRACE_INTERNAL_EVENT_TRANSITION_BIT,
+
TRACE_BRANCH_BIT,
/*
* Abuse of the trace_recursion.
@@ -97,6 +104,8 @@ enum {
#define TRACE_LIST_START TRACE_INTERNAL_BIT
+#define TRACE_EVENT_START TRACE_INTERNAL_EVENT_BIT
+
#define TRACE_CONTEXT_MASK ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
/*
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 33770d2b3489e..5426bad36419a 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3043,6 +3043,11 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
struct ftrace_stack *fstack;
struct stack_entry *entry;
int stackidx;
+ int bit;
+
+ bit = trace_test_and_set_recursion(_THIS_IP_, _RET_IP_, TRACE_EVENT_START);
+ if (bit < 0)
+ return;
/*
* Add one, for this function and the call to save_stack_trace()
@@ -3099,7 +3104,7 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
barrier();
__this_cpu_dec(ftrace_stack_reserve);
preempt_enable_notrace();
-
+ trace_clear_recursion(bit);
}
static inline void ftrace_trace_stack(struct trace_array *tr,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0929/1887] bonding: fix use-after-free due to enslave fail after slave array update
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (927 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0928/1887] tracing: Add recursion protection in kernel stack trace recording Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0930/1887] spi: tegra210-quad: Protect curr_xfer check in IRQ handler Greg Kroah-Hartman
` (69 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Chen Zhen,
Jussi Maki, Daniel Borkmann, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <razor@blackwall.org>
[ Upstream commit e9acda52fd2ee0cdca332f996da7a95c5fd25294 ]
Fix a use-after-free which happens due to enslave failure after the new
slave has been added to the array. Since the new slave can be used for Tx
immediately, we can use it after it has been freed by the enslave error
cleanup path which frees the allocated slave memory. Slave update array is
supposed to be called last when further enslave failures are not expected.
Move it after xdp setup to avoid any problems.
It is very easy to reproduce the problem with a simple xdp_pass prog:
ip l add bond1 type bond mode balance-xor
ip l set bond1 up
ip l set dev bond1 xdp object xdp_pass.o sec xdp_pass
ip l add dumdum type dummy
Then run in parallel:
while :; do ip l set dumdum master bond1 1>/dev/null 2>&1; done;
mausezahn bond1 -a own -b rand -A rand -B 1.1.1.1 -c 0 -t tcp "dp=1-1023, flags=syn"
The crash happens almost immediately:
[ 605.602850] Oops: general protection fault, probably for non-canonical address 0xe0e6fc2460000137: 0000 [#1] SMP KASAN NOPTI
[ 605.602916] KASAN: maybe wild-memory-access in range [0x07380123000009b8-0x07380123000009bf]
[ 605.602946] CPU: 0 UID: 0 PID: 2445 Comm: mausezahn Kdump: loaded Tainted: G B 6.19.0-rc6+ #21 PREEMPT(voluntary)
[ 605.602979] Tainted: [B]=BAD_PAGE
[ 605.602998] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 605.603032] RIP: 0010:netdev_core_pick_tx+0xcd/0x210
[ 605.603063] Code: 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 3e 01 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b 6b 08 49 8d 7d 30 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 25 01 00 00 49 8b 45 30 4c 89 e2 48 89 ee 48 89
[ 605.603111] RSP: 0018:ffff88817b9af348 EFLAGS: 00010213
[ 605.603145] RAX: dffffc0000000000 RBX: ffff88817d28b420 RCX: 0000000000000000
[ 605.603172] RDX: 00e7002460000137 RSI: 0000000000000008 RDI: 07380123000009be
[ 605.603199] RBP: ffff88817b541a00 R08: 0000000000000001 R09: fffffbfff3ed8c0c
[ 605.603226] R10: ffffffff9f6c6067 R11: 0000000000000001 R12: 0000000000000000
[ 605.603253] R13: 073801230000098e R14: ffff88817d28b448 R15: ffff88817b541a84
[ 605.603286] FS: 00007f6570ef67c0(0000) GS:ffff888221dfa000(0000) knlGS:0000000000000000
[ 605.603319] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 605.603343] CR2: 00007f65712fae40 CR3: 000000011371b000 CR4: 0000000000350ef0
[ 605.603373] Call Trace:
[ 605.603392] <TASK>
[ 605.603410] __dev_queue_xmit+0x448/0x32a0
[ 605.603434] ? __pfx_vprintk_emit+0x10/0x10
[ 605.603461] ? __pfx_vprintk_emit+0x10/0x10
[ 605.603484] ? __pfx___dev_queue_xmit+0x10/0x10
[ 605.603507] ? bond_start_xmit+0xbfb/0xc20 [bonding]
[ 605.603546] ? _printk+0xcb/0x100
[ 605.603566] ? __pfx__printk+0x10/0x10
[ 605.603589] ? bond_start_xmit+0xbfb/0xc20 [bonding]
[ 605.603627] ? add_taint+0x5e/0x70
[ 605.603648] ? add_taint+0x2a/0x70
[ 605.603670] ? end_report.cold+0x51/0x75
[ 605.603693] ? bond_start_xmit+0xbfb/0xc20 [bonding]
[ 605.603731] bond_start_xmit+0x623/0xc20 [bonding]
Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
Reported-by: Chen Zhen <chenzhen126@huawei.com>
Closes: https://lore.kernel.org/netdev/fae17c21-4940-5605-85b2-1d5e17342358@huawei.com/
CC: Jussi Maki <joamaki@gmail.com>
CC: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://patch.msgid.link/20260123120659.571187-1-razor@blackwall.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_main.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5b8770118c4f0..c94be63284841 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2269,11 +2269,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
unblock_netpoll_tx();
}
- /* broadcast mode uses the all_slaves to loop through slaves. */
- if (bond_mode_can_use_xmit_hash(bond) ||
- BOND_MODE(bond) == BOND_MODE_BROADCAST)
- bond_update_slave_arr(bond, NULL);
-
if (!slave_dev->netdev_ops->ndo_bpf ||
!slave_dev->netdev_ops->ndo_xdp_xmit) {
if (bond->xdp_prog) {
@@ -2307,6 +2302,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
bpf_prog_inc(bond->xdp_prog);
}
+ /* broadcast mode uses the all_slaves to loop through slaves. */
+ if (bond_mode_can_use_xmit_hash(bond) ||
+ BOND_MODE(bond) == BOND_MODE_BROADCAST)
+ bond_update_slave_arr(bond, NULL);
+
slave_info(bond_dev, slave_dev, "Enslaving as %s interface with %s link\n",
bond_is_active_slave(new_slave) ? "an active" : "a backup",
new_slave->link != BOND_LINK_DOWN ? "an up" : "a down");
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0930/1887] spi: tegra210-quad: Protect curr_xfer check in IRQ handler
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (928 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0929/1887] bonding: fix use-after-free due to enslave fail after slave array update Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0931/1887] ALSA: usb-audio: Prevent excessive number of frames Greg Kroah-Hartman
` (68 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Jon Hunter,
Thierry Reding, Mark Brown, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit edf9088b6e1d6d88982db7eb5e736a0e4fbcc09e ]
Now that all other accesses to curr_xfer are done under the lock,
protect the curr_xfer NULL check in tegra_qspi_isr_thread() with the
spinlock. Without this protection, the following race can occur:
CPU0 (ISR thread) CPU1 (timeout path)
---------------- -------------------
if (!tqspi->curr_xfer)
// sees non-NULL
spin_lock()
tqspi->curr_xfer = NULL
spin_unlock()
handle_*_xfer()
spin_lock()
t = tqspi->curr_xfer // NULL!
... t->len ... // NULL dereference!
With this patch, all curr_xfer accesses are now properly synchronized.
Although all accesses to curr_xfer are done under the lock, in
tegra_qspi_isr_thread() it checks for NULL, releases the lock and
reacquires it later in handle_cpu_based_xfer()/handle_dma_based_xfer().
There is a potential for an update in between, which could cause a NULL
pointer dereference.
To handle this, add a NULL check inside the handlers after acquiring
the lock. This ensures that if the timeout path has already cleared
curr_xfer, the handler will safely return without dereferencing the
NULL pointer.
Fixes: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-6-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-tegra210-quad.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index 022cc0ebee77c..cb1b7f251eac2 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -1342,6 +1342,11 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi)
spin_lock_irqsave(&tqspi->lock, flags);
t = tqspi->curr_xfer;
+ if (!t) {
+ spin_unlock_irqrestore(&tqspi->lock, flags);
+ return IRQ_HANDLED;
+ }
+
if (tqspi->tx_status || tqspi->rx_status) {
tegra_qspi_handle_error(tqspi);
complete(&tqspi->xfer_completion);
@@ -1410,6 +1415,11 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
spin_lock_irqsave(&tqspi->lock, flags);
t = tqspi->curr_xfer;
+ if (!t) {
+ spin_unlock_irqrestore(&tqspi->lock, flags);
+ return IRQ_HANDLED;
+ }
+
if (err) {
tegra_qspi_dma_unmap_xfer(tqspi, t);
tegra_qspi_handle_error(tqspi);
@@ -1448,6 +1458,7 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi)
static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
{
struct tegra_qspi *tqspi = context_data;
+ unsigned long flags;
u32 status;
/*
@@ -1465,7 +1476,9 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
* If no transfer is in progress, check if this was a real interrupt
* that the timeout handler already processed, or a spurious one.
*/
+ spin_lock_irqsave(&tqspi->lock, flags);
if (!tqspi->curr_xfer) {
+ spin_unlock_irqrestore(&tqspi->lock, flags);
/* Spurious interrupt - transfer not ready */
if (!(status & QSPI_RDY))
return IRQ_NONE;
@@ -1482,7 +1495,14 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
tqspi->rx_status = tqspi->status_reg & (QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF);
tegra_qspi_mask_clear_irq(tqspi);
+ spin_unlock_irqrestore(&tqspi->lock, flags);
+ /*
+ * Lock is released here but handlers safely re-check curr_xfer under
+ * lock before dereferencing.
+ * DMA handler also needs to sleep in wait_for_completion_*(), which
+ * cannot be done while holding spinlock.
+ */
if (!tqspi->is_curr_dma_xfer)
return handle_cpu_based_xfer(tqspi);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0931/1887] ALSA: usb-audio: Prevent excessive number of frames
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (929 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0930/1887] spi: tegra210-quad: Protect curr_xfer check in IRQ handler Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0932/1887] drm/amd/pm: Disable MMIO access during SMU Mode 1 reset Greg Kroah-Hartman
` (67 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6db0415d6d5c635f72cb,
Edward Adam Davis, Takashi Iwai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit ef5749ef8b307bf8717945701b1b79d036af0a15 ]
In this case, the user constructed the parameters with maxpacksize 40
for rate 22050 / pps 1000, and packsize[0] 22 packsize[1] 23. The buffer
size for each data URB is maxpacksize * packets, which in this example
is 40 * 6 = 240; When the user performs a write operation to send audio
data into the ALSA PCM playback stream, the calculated number of frames
is packsize[0] * packets = 264, which exceeds the allocated URB buffer
size, triggering the out-of-bounds (OOB) issue reported by syzbot [1].
Added a check for the number of single data URB frames when calculating
the number of frames to prevent [1].
[1]
BUG: KASAN: slab-out-of-bounds in copy_to_urb+0x261/0x460 sound/usb/pcm.c:1487
Write of size 264 at addr ffff88804337e800 by task syz.0.17/5506
Call Trace:
copy_to_urb+0x261/0x460 sound/usb/pcm.c:1487
prepare_playback_urb+0x953/0x13d0 sound/usb/pcm.c:1611
prepare_outbound_urb+0x377/0xc50 sound/usb/endpoint.c:333
Reported-by: syzbot+6db0415d6d5c635f72cb@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6db0415d6d5c635f72cb
Tested-by: syzbot+6db0415d6d5c635f72cb@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Link: https://patch.msgid.link/tencent_9AECE6CD2C7A826D902D696C289724E8120A@qq.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/pcm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f2c798c4506b0..17e539b1fdb4c 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1461,7 +1461,8 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
for (i = 0; i < ctx->packets; i++) {
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
- if (counts < 0)
+ if (counts < 0 ||
+ (frames + counts) * stride > ctx->buffer_size)
break;
/* set up descriptor */
urb->iso_frame_desc[i].offset = frames * stride;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0932/1887] drm/amd/pm: Disable MMIO access during SMU Mode 1 reset
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (930 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0931/1887] ALSA: usb-audio: Prevent excessive number of frames Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0933/1887] btrfs: reject new transactions if the fs is fully read-only Greg Kroah-Hartman
` (66 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Perry Yuan, Yifan Zhang,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Perry Yuan <perry.yuan@amd.com>
[ Upstream commit 0de604d0357d0d22cbf03af1077d174b641707b6 ]
During Mode 1 reset, the ASIC undergoes a reset cycle and becomes
temporarily inaccessible via PCIe. Any attempt to access MMIO registers
during this window (e.g., from interrupt handlers or other driver threads)
can result in uncompleted PCIe transactions, leading to NMI panics or
system hangs.
To prevent this, set the `no_hw_access` flag to true immediately after
triggering the reset. This signals other driver components to skip
register accesses while the device is offline.
A memory barrier `smp_mb()` is added to ensure the flag update is
globally visible to all cores before the driver enters the sleep/wait
state.
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7edb503fe4b6d67f47d8bb0dfafb8e699bb0f8a4)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++++
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 7 ++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 8aaa437a06139..d1f7ebfff9907 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4907,6 +4907,10 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
if (ret)
dev_err(adev->dev, "GPU mode1 reset failed\n");
+ /* enable mmio access after mode 1 reset completed */
+ if (!ret)
+ adev->no_hw_access = false;
+
amdgpu_device_load_pci_state(adev->pdev);
/* wait for asic to come out of reset */
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index ae8854b90f379..cff7f2589d020 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -1894,8 +1894,13 @@ static int smu_v13_0_0_mode1_reset(struct smu_context *smu)
else
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
- if (!ret)
+ if (!ret) {
+ /* disable mmio access while doing mode 1 reset*/
+ smu->adev->no_hw_access = true;
+ /* ensure no_hw_access is globally visible before any MMIO */
+ smp_mb();
msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
+ }
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0933/1887] btrfs: reject new transactions if the fs is fully read-only
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (931 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0932/1887] drm/amd/pm: Disable MMIO access during SMU Mode 1 reset Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0934/1887] ksmbd: add chann_lock to protect ksmbd_chann_list xarray Greg Kroah-Hartman
` (65 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiaming Zhang, Boris Burkov,
Johannes Thumshirn, Qu Wenruo, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit 1972f44c189c8aacde308fa9284e474c1a5cbd9f ]
[BUG]
There is a bug report where a heavily fuzzed fs is mounted with all
rescue mount options, which leads to the following warnings during
unmount:
BTRFS: Transaction aborted (error -22)
Modules linked in:
CPU: 0 UID: 0 PID: 9758 Comm: repro.out Not tainted
6.19.0-rc5-00002-gb71e635feefc #7 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:find_free_extent_update_loop fs/btrfs/extent-tree.c:4208 [inline]
RIP: 0010:find_free_extent+0x52f0/0x5d20 fs/btrfs/extent-tree.c:4611
Call Trace:
<TASK>
btrfs_reserve_extent+0x2cd/0x790 fs/btrfs/extent-tree.c:4705
btrfs_alloc_tree_block+0x1e1/0x10e0 fs/btrfs/extent-tree.c:5157
btrfs_force_cow_block+0x578/0x2410 fs/btrfs/ctree.c:517
btrfs_cow_block+0x3c4/0xa80 fs/btrfs/ctree.c:708
btrfs_search_slot+0xcad/0x2b50 fs/btrfs/ctree.c:2130
btrfs_truncate_inode_items+0x45d/0x2350 fs/btrfs/inode-item.c:499
btrfs_evict_inode+0x923/0xe70 fs/btrfs/inode.c:5628
evict+0x5f4/0xae0 fs/inode.c:837
__dentry_kill+0x209/0x660 fs/dcache.c:670
finish_dput+0xc9/0x480 fs/dcache.c:879
shrink_dcache_for_umount+0xa0/0x170 fs/dcache.c:1661
generic_shutdown_super+0x67/0x2c0 fs/super.c:621
kill_anon_super+0x3b/0x70 fs/super.c:1289
btrfs_kill_super+0x41/0x50 fs/btrfs/super.c:2127
deactivate_locked_super+0xbc/0x130 fs/super.c:474
cleanup_mnt+0x425/0x4c0 fs/namespace.c:1318
task_work_run+0x1d4/0x260 kernel/task_work.c:233
exit_task_work include/linux/task_work.h:40 [inline]
do_exit+0x694/0x22f0 kernel/exit.c:971
do_group_exit+0x21c/0x2d0 kernel/exit.c:1112
__do_sys_exit_group kernel/exit.c:1123 [inline]
__se_sys_exit_group kernel/exit.c:1121 [inline]
__x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1121
x64_sys_call+0x2210/0x2210 arch/x86/include/generated/asm/syscalls_64.h:232
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xe8/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x44f639
Code: Unable to access opcode bytes at 0x44f60f.
RSP: 002b:00007ffc15c4e088 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 00000000004c32f0 RCX: 000000000044f639
RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001
RBP: 0000000000000001 R08: ffffffffffffffc0 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004c32f0
R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000001
</TASK>
Since rescue mount options will mark the full fs read-only, there should
be no new transaction triggered.
But during unmount we will evict all inodes, which can trigger a new
transaction, and triggers warnings on a heavily corrupted fs.
[CAUSE]
Btrfs allows new transaction even on a read-only fs, this is to allow
log replay happen even on read-only mounts, just like what ext4/xfs do.
However with rescue mount options, the fs is fully read-only and cannot
be remounted read-write, thus in that case we should also reject any new
transactions.
[FIX]
If we find the fs has rescue mount options, we should treat the fs as
error, so that no new transaction can be started.
Reported-by: Jiaming Zhang <r772577952@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/CANypQFYw8Nt8stgbhoycFojOoUmt+BoZ-z8WJOZVxcogDdwm=Q@mail.gmail.com/
Reviewed-by: Boris Burkov <boris@bur.io>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ctree.h | 6 ++++++
fs/btrfs/disk-io.c | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 90a6b36f8baf4..e115ba97dd44a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1626,6 +1626,12 @@ enum {
BTRFS_MOUNT_IGNOREDATACSUMS = (1UL << 30),
};
+/* These mount options require a full read-only fs, no new transaction is allowed. */
+#define BTRFS_MOUNT_FULL_RO_MASK \
+ (BTRFS_MOUNT_NOLOGREPLAY | \
+ BTRFS_MOUNT_IGNOREBADROOTS | \
+ BTRFS_MOUNT_IGNOREDATACSUMS)
+
#define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
#define BTRFS_DEFAULT_MAX_INLINE (2048)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 203ff9bbad431..dd804bfc3a497 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3417,6 +3417,15 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
return 0;
}
+static bool fs_is_full_ro(const struct btrfs_fs_info *fs_info)
+{
+ if (!sb_rdonly(fs_info->sb))
+ return false;
+ if (unlikely(fs_info->mount_opt & BTRFS_MOUNT_FULL_RO_MASK))
+ return true;
+ return false;
+}
+
int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices,
char *options)
{
@@ -3798,6 +3807,10 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
}
}
+ /* If the fs has any rescue options, no transaction is allowed. */
+ if (fs_is_full_ro(fs_info))
+ set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
+
fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true);
if (IS_ERR(fs_info->fs_root)) {
err = PTR_ERR(fs_info->fs_root);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0934/1887] ksmbd: add chann_lock to protect ksmbd_chann_list xarray
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (932 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0933/1887] btrfs: reject new transactions if the fs is fully read-only Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0935/1887] tcp: secure_seq: add back ports to TS offset Greg Kroah-Hartman
` (64 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Igor Stepansky, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 4f3a06cc57976cafa8c6f716646be6c79a99e485 ]
ksmbd_chann_list xarray lacks synchronization, allowing use-after-free in
multi-channel sessions (between lookup_chann_list() and ksmbd_chann_del).
Adds rw_semaphore chann_lock to struct ksmbd_session and protects
all xa_load/xa_store/xa_erase accesses.
Cc: stable@vger.kernel.org
Reported-by: Igor Stepansky <igor.stepansky@orca.security>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/mgmt/user_session.c | 5 +++++
fs/smb/server/mgmt/user_session.h | 1 +
fs/smb/server/smb2pdu.c | 12 +++++++++++-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index 605e17c7b2a17..33ae100fd07ed 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -32,12 +32,14 @@ static void free_channel_list(struct ksmbd_session *sess)
struct channel *chann;
unsigned long index;
+ down_write(&sess->chann_lock);
xa_for_each(&sess->ksmbd_chann_list, index, chann) {
xa_erase(&sess->ksmbd_chann_list, index);
kfree(chann);
}
xa_destroy(&sess->ksmbd_chann_list);
+ up_write(&sess->chann_lock);
}
static void __session_rpc_close(struct ksmbd_session *sess,
@@ -220,7 +222,9 @@ static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
{
struct channel *chann;
+ down_write(&sess->chann_lock);
chann = xa_erase(&sess->ksmbd_chann_list, (long)conn);
+ up_write(&sess->chann_lock);
if (!chann)
return -ENOENT;
@@ -422,6 +426,7 @@ static struct ksmbd_session *__session_create(int protocol)
rwlock_init(&sess->tree_conns_lock);
atomic_set(&sess->refcnt, 2);
init_rwsem(&sess->rpc_lock);
+ init_rwsem(&sess->chann_lock);
ret = __init_smb2_session(sess);
if (ret)
diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h
index 011362e975b00..90ae30ba402f4 100644
--- a/fs/smb/server/mgmt/user_session.h
+++ b/fs/smb/server/mgmt/user_session.h
@@ -49,6 +49,7 @@ struct ksmbd_session {
char sess_key[CIFS_KEY_SIZE];
struct hlist_node hlist;
+ struct rw_semaphore chann_lock;
struct xarray ksmbd_chann_list;
struct xarray tree_conns;
struct ida tree_conn_ida;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 16477ad9dde8d..b05a9488aaa4d 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -78,7 +78,13 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn)
{
- return xa_load(&sess->ksmbd_chann_list, (long)conn);
+ struct channel *chann;
+
+ down_read(&sess->chann_lock);
+ chann = xa_load(&sess->ksmbd_chann_list, (long)conn);
+ up_read(&sess->chann_lock);
+
+ return chann;
}
/**
@@ -1580,7 +1586,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,
return -ENOMEM;
chann->conn = conn;
+ down_write(&sess->chann_lock);
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ up_write(&sess->chann_lock);
}
}
@@ -1673,7 +1681,9 @@ static int krb5_authenticate(struct ksmbd_work *work,
return -ENOMEM;
chann->conn = conn;
+ down_write(&sess->chann_lock);
xa_store(&sess->ksmbd_chann_list, (long)conn, chann, GFP_KERNEL);
+ up_write(&sess->chann_lock);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0935/1887] tcp: secure_seq: add back ports to TS offset
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (933 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0934/1887] ksmbd: add chann_lock to protect ksmbd_chann_list xarray Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0936/1887] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() Greg Kroah-Hartman
` (63 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhouyan Deng, Eric Dumazet,
Kuniyuki Iwashima, Florian Westphal, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 165573e41f2f66ef98940cf65f838b2cb575d9d1 ]
This reverts 28ee1b746f49 ("secure_seq: downgrade to per-host timestamp offsets")
tcp_tw_recycle went away in 2017.
Zhouyan Deng reported off-path TCP source port leakage via
SYN cookie side-channel that can be fixed in multiple ways.
One of them is to bring back TCP ports in TS offset randomization.
As a bonus, we perform a single siphash() computation
to provide both an ISN and a TS offset.
Fixes: 28ee1b746f49 ("secure_seq: downgrade to per-host timestamp offsets")
Reported-by: Zhouyan Deng <dengzhouyan_nwpu@163.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Acked-by: Florian Westphal <fw@strlen.de>
Link: https://patch.msgid.link/20260302205527.1982836-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/secure_seq.h | 47 +++++++++++++++++++----
include/net/tcp.h | 6 ++-
net/core/secure_seq.c | 80 +++++++++++++++-------------------------
net/ipv4/syncookies.c | 10 +++--
net/ipv4/tcp_input.c | 8 +++-
net/ipv4/tcp_ipv4.c | 37 +++++++++----------
net/ipv6/syncookies.c | 11 ++++--
net/ipv6/tcp_ipv6.c | 37 +++++++++----------
8 files changed, 128 insertions(+), 108 deletions(-)
diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
index 21e7fa2a18138..899612c4bec37 100644
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -5,17 +5,50 @@
#include <linux/types.h>
struct net;
+extern struct net init_net;
+
+union tcp_seq_and_ts_off {
+ struct {
+ u32 seq;
+ u32 ts_off;
+ };
+ u64 hash64;
+};
u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
__be16 dport);
-u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
- __be16 sport, __be16 dport);
-u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr);
-u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
- __be16 sport, __be16 dport);
-u32 secure_tcpv6_ts_off(const struct net *net,
- const __be32 *saddr, const __be32 *daddr);
+union tcp_seq_and_ts_off
+secure_tcp_seq_and_ts_off(const struct net *net, __be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport);
+
+static inline u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport)
+{
+ union tcp_seq_and_ts_off ts;
+
+ ts = secure_tcp_seq_and_ts_off(&init_net, saddr, daddr,
+ sport, dport);
+
+ return ts.seq;
+}
+
+union tcp_seq_and_ts_off
+secure_tcpv6_seq_and_ts_off(const struct net *net, const __be32 *saddr,
+ const __be32 *daddr,
+ __be16 sport, __be16 dport);
+
+static inline u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
+ __be16 sport, __be16 dport)
+{
+ union tcp_seq_and_ts_off ts;
+
+ ts = secure_tcpv6_seq_and_ts_off(&init_net, saddr, daddr,
+ sport, dport);
+
+ return ts.seq;
+}
+
u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
__be16 sport, __be16 dport);
u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 245c522387315..51a17dadb7556 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -41,6 +41,7 @@
#include <net/dst.h>
#include <net/mptcp.h>
#include <net/xfrm.h>
+#include <net/secure_seq.h>
#include <linux/seq_file.h>
#include <linux/memcontrol.h>
@@ -2143,8 +2144,9 @@ struct tcp_request_sock_ops {
struct sk_buff *skb,
struct flowi *fl,
struct request_sock *req);
- u32 (*init_seq)(const struct sk_buff *skb);
- u32 (*init_ts_off)(const struct net *net, const struct sk_buff *skb);
+ union tcp_seq_and_ts_off (*init_seq_and_ts_off)(
+ const struct net *net,
+ const struct sk_buff *skb);
int (*send_synack)(const struct sock *sk, struct dst_entry *dst,
struct flowi *fl, struct request_sock *req,
struct tcp_fastopen_cookie *foc,
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index b0ff6153be623..740642aeaf765 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -20,7 +20,6 @@
#include <net/tcp.h>
static siphash_aligned_key_t net_secret;
-static siphash_aligned_key_t ts_secret;
#define EPHEMERAL_PORT_SHUFFLE_PERIOD (10 * HZ)
@@ -28,11 +27,6 @@ static __always_inline void net_secret_init(void)
{
net_get_random_once(&net_secret, sizeof(net_secret));
}
-
-static __always_inline void ts_secret_init(void)
-{
- net_get_random_once(&ts_secret, sizeof(ts_secret));
-}
#endif
#ifdef CONFIG_INET
@@ -53,28 +47,9 @@ static u32 seq_scale(u32 seq)
#endif
#if IS_ENABLED(CONFIG_IPV6)
-u32 secure_tcpv6_ts_off(const struct net *net,
- const __be32 *saddr, const __be32 *daddr)
-{
- const struct {
- struct in6_addr saddr;
- struct in6_addr daddr;
- } __aligned(SIPHASH_ALIGNMENT) combined = {
- .saddr = *(struct in6_addr *)saddr,
- .daddr = *(struct in6_addr *)daddr,
- };
-
- if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
- return 0;
-
- ts_secret_init();
- return siphash(&combined, offsetofend(typeof(combined), daddr),
- &ts_secret);
-}
-EXPORT_SYMBOL(secure_tcpv6_ts_off);
-
-u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
- __be16 sport, __be16 dport)
+union tcp_seq_and_ts_off
+secure_tcpv6_seq_and_ts_off(const struct net *net, const __be32 *saddr,
+ const __be32 *daddr, __be16 sport, __be16 dport)
{
const struct {
struct in6_addr saddr;
@@ -87,14 +62,20 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
.sport = sport,
.dport = dport
};
- u32 hash;
+ union tcp_seq_and_ts_off st;
net_secret_init();
- hash = siphash(&combined, offsetofend(typeof(combined), dport),
- &net_secret);
- return seq_scale(hash);
+
+ st.hash64 = siphash(&combined, offsetofend(typeof(combined), dport),
+ &net_secret);
+
+ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ st.ts_off = 0;
+
+ st.seq = seq_scale(st.seq);
+ return st;
}
-EXPORT_SYMBOL(secure_tcpv6_seq);
+EXPORT_SYMBOL(secure_tcpv6_seq_and_ts_off);
u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
__be16 dport)
@@ -118,33 +99,30 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
#endif
#ifdef CONFIG_INET
-u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr)
-{
- if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
- return 0;
-
- ts_secret_init();
- return siphash_2u32((__force u32)saddr, (__force u32)daddr,
- &ts_secret);
-}
-
/* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d),
* but fortunately, `sport' cannot be 0 in any circumstances. If this changes,
* it would be easy enough to have the former function use siphash_4u32, passing
* the arguments as separate u32.
*/
-u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
- __be16 sport, __be16 dport)
+union tcp_seq_and_ts_off
+secure_tcp_seq_and_ts_off(const struct net *net, __be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport)
{
- u32 hash;
+ u32 ports = (__force u32)sport << 16 | (__force u32)dport;
+ union tcp_seq_and_ts_off st;
net_secret_init();
- hash = siphash_3u32((__force u32)saddr, (__force u32)daddr,
- (__force u32)sport << 16 | (__force u32)dport,
- &net_secret);
- return seq_scale(hash);
+
+ st.hash64 = siphash_3u32((__force u32)saddr, (__force u32)daddr,
+ ports, &net_secret);
+
+ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ st.ts_off = 0;
+
+ st.seq = seq_scale(st.seq);
+ return st;
}
-EXPORT_SYMBOL_GPL(secure_tcp_seq);
+EXPORT_SYMBOL_GPL(secure_tcp_seq_and_ts_off);
u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
{
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index d7202f86566a4..4576e77139252 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -353,9 +353,13 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL);
if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) {
- tsoff = secure_tcp_ts_off(sock_net(sk),
- ip_hdr(skb)->daddr,
- ip_hdr(skb)->saddr);
+ union tcp_seq_and_ts_off st;
+
+ st = secure_tcp_seq_and_ts_off(sock_net(sk),
+ ip_hdr(skb)->daddr,
+ ip_hdr(skb)->saddr,
+ th->dest, th->source);
+ tsoff = st.ts_off;
tcp_opt.rcv_tsecr -= tsoff;
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 488b1926a2eb2..55e5325479c01 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -7033,6 +7033,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
struct tcp_sock *tp = tcp_sk(sk);
struct net *net = sock_net(sk);
struct sock *fastopen_sk = NULL;
+ union tcp_seq_and_ts_off st;
struct request_sock *req;
bool want_cookie = false;
struct dst_entry *dst;
@@ -7090,8 +7091,11 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
if (!dst)
goto drop_and_free;
+ if (tmp_opt.tstamp_ok || (!want_cookie && !isn))
+ st = af_ops->init_seq_and_ts_off(net, skb);
+
if (tmp_opt.tstamp_ok)
- tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb);
+ tcp_rsk(req)->ts_off = st.ts_off;
if (!want_cookie && !isn) {
int max_syn_backlog = READ_ONCE(net->ipv4.sysctl_max_syn_backlog);
@@ -7113,7 +7117,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
goto drop_and_release;
}
- isn = af_ops->init_seq(skb);
+ isn = st.seq;
}
tcp_ecn_create_request(req, skb, sk, dst);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 49135d9b27378..e68f84c08e1c1 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -98,17 +98,14 @@ static DEFINE_PER_CPU(struct sock *, ipv4_tcp_sk);
static DEFINE_MUTEX(tcp_exit_batch_mutex);
-static u32 tcp_v4_init_seq(const struct sk_buff *skb)
+static union tcp_seq_and_ts_off
+tcp_v4_init_seq_and_ts_off(const struct net *net, const struct sk_buff *skb)
{
- return secure_tcp_seq(ip_hdr(skb)->daddr,
- ip_hdr(skb)->saddr,
- tcp_hdr(skb)->dest,
- tcp_hdr(skb)->source);
-}
-
-static u32 tcp_v4_init_ts_off(const struct net *net, const struct sk_buff *skb)
-{
- return secure_tcp_ts_off(net, ip_hdr(skb)->daddr, ip_hdr(skb)->saddr);
+ return secure_tcp_seq_and_ts_off(net,
+ ip_hdr(skb)->daddr,
+ ip_hdr(skb)->saddr,
+ tcp_hdr(skb)->dest,
+ tcp_hdr(skb)->source);
}
int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
@@ -315,15 +312,16 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
rt = NULL;
if (likely(!tp->repair)) {
+ union tcp_seq_and_ts_off st;
+
+ st = secure_tcp_seq_and_ts_off(net,
+ inet->inet_saddr,
+ inet->inet_daddr,
+ inet->inet_sport,
+ usin->sin_port);
if (!tp->write_seq)
- WRITE_ONCE(tp->write_seq,
- secure_tcp_seq(inet->inet_saddr,
- inet->inet_daddr,
- inet->inet_sport,
- usin->sin_port));
- WRITE_ONCE(tp->tsoffset,
- secure_tcp_ts_off(net, inet->inet_saddr,
- inet->inet_daddr));
+ WRITE_ONCE(tp->write_seq, st.seq);
+ WRITE_ONCE(tp->tsoffset, st.ts_off);
}
atomic_set(&inet->inet_id, get_random_u16());
@@ -1481,8 +1479,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
.cookie_init_seq = cookie_v4_init_sequence,
#endif
.route_req = tcp_v4_route_req,
- .init_seq = tcp_v4_init_seq,
- .init_ts_off = tcp_v4_init_ts_off,
+ .init_seq_and_ts_off = tcp_v4_init_seq_and_ts_off,
.send_synack = tcp_v4_send_synack,
};
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 8698b49dfc8de..99c2ea8c7d768 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -161,9 +161,14 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL);
if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) {
- tsoff = secure_tcpv6_ts_off(sock_net(sk),
- ipv6_hdr(skb)->daddr.s6_addr32,
- ipv6_hdr(skb)->saddr.s6_addr32);
+ union tcp_seq_and_ts_off st;
+
+ st = secure_tcpv6_seq_and_ts_off(sock_net(sk),
+ ipv6_hdr(skb)->daddr.s6_addr32,
+ ipv6_hdr(skb)->saddr.s6_addr32,
+ tcp_hdr(skb)->dest,
+ tcp_hdr(skb)->source);
+ tsoff = st.ts_off;
tcp_opt.rcv_tsecr -= tsoff;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 9e199a2a43ef1..8503070683d17 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -112,18 +112,14 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
}
}
-static u32 tcp_v6_init_seq(const struct sk_buff *skb)
+static union tcp_seq_and_ts_off
+tcp_v6_init_seq_and_ts_off(const struct net *net, const struct sk_buff *skb)
{
- return secure_tcpv6_seq(ipv6_hdr(skb)->daddr.s6_addr32,
- ipv6_hdr(skb)->saddr.s6_addr32,
- tcp_hdr(skb)->dest,
- tcp_hdr(skb)->source);
-}
-
-static u32 tcp_v6_init_ts_off(const struct net *net, const struct sk_buff *skb)
-{
- return secure_tcpv6_ts_off(net, ipv6_hdr(skb)->daddr.s6_addr32,
- ipv6_hdr(skb)->saddr.s6_addr32);
+ return secure_tcpv6_seq_and_ts_off(net,
+ ipv6_hdr(skb)->daddr.s6_addr32,
+ ipv6_hdr(skb)->saddr.s6_addr32,
+ tcp_hdr(skb)->dest,
+ tcp_hdr(skb)->source);
}
static int tcp_v6_pre_connect(struct sock *sk, struct sockaddr *uaddr,
@@ -323,14 +319,16 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
sk_set_txhash(sk);
if (likely(!tp->repair)) {
+ union tcp_seq_and_ts_off st;
+
+ st = secure_tcpv6_seq_and_ts_off(net,
+ np->saddr.s6_addr32,
+ sk->sk_v6_daddr.s6_addr32,
+ inet->inet_sport,
+ inet->inet_dport);
if (!tp->write_seq)
- WRITE_ONCE(tp->write_seq,
- secure_tcpv6_seq(np->saddr.s6_addr32,
- sk->sk_v6_daddr.s6_addr32,
- inet->inet_sport,
- inet->inet_dport));
- tp->tsoffset = secure_tcpv6_ts_off(net, np->saddr.s6_addr32,
- sk->sk_v6_daddr.s6_addr32);
+ WRITE_ONCE(tp->write_seq, st.seq);
+ tp->tsoffset = st.ts_off;
}
if (tcp_fastopen_defer_connect(sk, &err))
@@ -837,8 +835,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
.cookie_init_seq = cookie_v6_init_sequence,
#endif
.route_req = tcp_v6_route_req,
- .init_seq = tcp_v6_init_seq,
- .init_ts_off = tcp_v6_init_ts_off,
+ .init_seq_and_ts_off = tcp_v6_init_seq_and_ts_off,
.send_synack = tcp_v6_send_synack,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0936/1887] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (934 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0935/1887] tcp: secure_seq: add back ports to TS offset Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0937/1887] nfc: nci: complete pending data exchange on device close Greg Kroah-Hartman
` (62 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Davidlohr Bueso, Alison Schofield,
Dave Jiang, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <dave@stgolabs.net>
[ Upstream commit 60b5d1f68338aff2c5af0113f04aefa7169c50c2 ]
cxl_payload_from_user_allowed() casts and dereferences the input
payload without first verifying its size. When a raw mailbox command
is sent with an undersized payload (ie: 1 byte for CXL_MBOX_OP_CLEAR_LOG,
which expects a 16-byte UUID), uuid_equal() reads past the allocated buffer,
triggering a KASAN splat:
BUG: KASAN: slab-out-of-bounds in memcmp+0x176/0x1d0 lib/string.c:683
Read of size 8 at addr ffff88810130f5c0 by task syz.1.62/2258
CPU: 2 UID: 0 PID: 2258 Comm: syz.1.62 Not tainted 6.19.0-dirty #3 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0xab/0xe0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xce/0x650 mm/kasan/report.c:482
kasan_report+0xce/0x100 mm/kasan/report.c:595
memcmp+0x176/0x1d0 lib/string.c:683
uuid_equal include/linux/uuid.h:73 [inline]
cxl_payload_from_user_allowed drivers/cxl/core/mbox.c:345 [inline]
cxl_mbox_cmd_ctor drivers/cxl/core/mbox.c:368 [inline]
cxl_validate_cmd_from_user drivers/cxl/core/mbox.c:522 [inline]
cxl_send_cmd+0x9c0/0xb50 drivers/cxl/core/mbox.c:643
__cxl_memdev_ioctl drivers/cxl/core/memdev.c:698 [inline]
cxl_memdev_ioctl+0x14f/0x190 drivers/cxl/core/memdev.c:713
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xa8/0x330 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fdaf331ba79
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fdaf1d77038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fdaf3585fa0 RCX: 00007fdaf331ba79
RDX: 00002000000001c0 RSI: 00000000c030ce02 RDI: 0000000000000003
RBP: 00007fdaf33749df R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fdaf3586038 R14: 00007fdaf3585fa0 R15: 00007ffced2af768
</TASK>
Add 'in_size' parameter to cxl_payload_from_user_allowed() and validate
the payload is large enough.
Fixes: 6179045ccc0c ("cxl/mbox: Block immediate mode in SET_PARTITION_INFO command")
Fixes: 206f9fa9d555 ("cxl/mbox: Add Clear Log mailbox command")
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260220001618.963490-2-dave@stgolabs.net
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/mbox.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 0c90f13870a43..3e89dc2b60d84 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -223,6 +223,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode)
* cxl_payload_from_user_allowed() - Check contents of in_payload.
* @opcode: The mailbox command opcode.
* @payload_in: Pointer to the input payload passed in from user space.
+ * @in_size: Size of @payload_in in bytes.
*
* Return:
* * true - payload_in passes check for @opcode.
@@ -237,12 +238,15 @@ static bool cxl_mem_raw_command_allowed(u16 opcode)
*
* The specific checks are determined by the opcode.
*/
-static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
+static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in,
+ size_t in_size)
{
switch (opcode) {
case CXL_MBOX_OP_SET_PARTITION_INFO: {
struct cxl_mbox_set_partition_info *pi = payload_in;
+ if (in_size < sizeof(*pi))
+ return false;
if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG)
return false;
break;
@@ -268,7 +272,8 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox,
if (IS_ERR(mbox->payload_in))
return PTR_ERR(mbox->payload_in);
- if (!cxl_payload_from_user_allowed(opcode, mbox->payload_in)) {
+ if (!cxl_payload_from_user_allowed(opcode, mbox->payload_in,
+ in_size)) {
dev_dbg(cxlds->dev, "%s: input payload not allowed\n",
cxl_mem_opcode_to_name(opcode));
kvfree(mbox->payload_in);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0937/1887] nfc: nci: complete pending data exchange on device close
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (935 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0936/1887] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0938/1887] PCI: dwc: ep: Flush MSI-X write before unmapping its ATU entry Greg Kroah-Hartman
` (61 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Joe Damato, Jakub Kicinski,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 66083581945bd5b8e99fe49b5aeb83d03f62d053 ]
In nci_close_device(), complete any pending data exchange before
closing. The data exchange callback (e.g.
rawsock_data_exchange_complete) holds a socket reference.
NIPA occasionally hits this leak:
unreferenced object 0xff1100000f435000 (size 2048):
comm "nci_dev", pid 3954, jiffies 4295441245
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
27 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 '..@............
backtrace (crc ec2b3c5):
__kmalloc_noprof+0x4db/0x730
sk_prot_alloc.isra.0+0xe4/0x1d0
sk_alloc+0x36/0x760
rawsock_create+0xd1/0x540
nfc_sock_create+0x11f/0x280
__sock_create+0x22d/0x630
__sys_socket+0x115/0x1d0
__x64_sys_socket+0x72/0xd0
do_syscall_64+0x117/0xfc0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Fixes: 38f04c6b1b68 ("NFC: protect nci_data_exchange transactions")
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260303162346.2071888-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/nci/core.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index bc5f7068e6db1..bfbe405a474eb 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -566,6 +566,10 @@ static int nci_close_device(struct nci_dev *ndev)
flush_workqueue(ndev->cmd_wq);
del_timer_sync(&ndev->cmd_timer);
del_timer_sync(&ndev->data_timer);
+ if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
+ nci_data_exchange_complete(ndev, NULL,
+ ndev->cur_conn_id,
+ -ENODEV);
mutex_unlock(&ndev->req_lock);
return 0;
}
@@ -596,6 +600,11 @@ static int nci_close_device(struct nci_dev *ndev)
flush_workqueue(ndev->cmd_wq);
del_timer_sync(&ndev->cmd_timer);
+ del_timer_sync(&ndev->data_timer);
+
+ if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
+ nci_data_exchange_complete(ndev, NULL, ndev->cur_conn_id,
+ -ENODEV);
/* Clear flags except NCI_UNREG */
ndev->flags &= BIT(NCI_UNREG);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0938/1887] PCI: dwc: ep: Flush MSI-X write before unmapping its ATU entry
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (936 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0937/1887] nfc: nci: complete pending data exchange on device close Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0939/1887] sched/deadline: Fix missing ENQUEUE_REPLENISH during PI de-boosting Greg Kroah-Hartman
` (60 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Niklas Cassel, Bjorn Helgaas,
Frank Li, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <cassel@kernel.org>
[ Upstream commit c22533c66ccae10511ad6a7afc34bb26c47577e3 ]
Endpoint drivers use dw_pcie_ep_raise_msix_irq() to raise an MSI-X
interrupt to the host using a writel(), which generates a PCI posted write
transaction. There's no completion for posted writes, so the writel() may
return before the PCI write completes. dw_pcie_ep_raise_msix_irq() also
unmaps the outbound ATU entry used for the PCI write, so the write races
with the unmap.
If the PCI write loses the race with the ATU unmap, the write may corrupt
host memory or cause IOMMU errors, e.g., these when running fio with a
larger queue depth against nvmet-pci-epf:
arm-smmu-v3 fc900000.iommu: 0x0000010000000010
arm-smmu-v3 fc900000.iommu: 0x0000020000000000
arm-smmu-v3 fc900000.iommu: 0x000000090000f040
arm-smmu-v3 fc900000.iommu: 0x0000000000000000
arm-smmu-v3 fc900000.iommu: event: F_TRANSLATION client: 0000:01:00.0 sid: 0x100 ssid: 0x0 iova: 0x90000f040 ipa: 0x0
arm-smmu-v3 fc900000.iommu: unpriv data write s1 "Input address caused fault" stag: 0x0
Flush the write by performing a readl() of the same address to ensure that
the write has reached the destination before the ATU entry is unmapped.
The same problem was solved for dw_pcie_ep_raise_msi_irq() in commit
8719c64e76bf ("PCI: dwc: ep: Cache MSI outbound iATU mapping"), but there
it was solved by dedicating an outbound iATU only for MSI. We can't do the
same for MSI-X because each vector can have a different msg_addr and the
msg_addr may be changed while the vector is masked.
Fixes: beb4641a787d ("PCI: dwc: Add MSI-X callbacks handler")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260211175540.105677-2-cassel@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 32a04ff86c5c5..7a68574b90d34 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -633,6 +633,9 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
writel(msg_data, ep->msi_mem + aligned_offset);
+ /* flush posted write before unmap */
+ readl(ep->msi_mem + aligned_offset);
+
dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0939/1887] sched/deadline: Fix missing ENQUEUE_REPLENISH during PI de-boosting
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (937 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0938/1887] PCI: dwc: ep: Flush MSI-X write before unmapping its ATU entry Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0940/1887] blktrace: fix __this_cpu_read/write in preemptible context Greg Kroah-Hartman
` (59 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bruno Goncalves, Juri Lelli,
Peter Zijlstra (Intel), Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juri Lelli <juri.lelli@redhat.com>
[ Upstream commit d658686a1331db3bb108ca079d76deb3208ed949 ]
Running stress-ng --schedpolicy 0 on an RT kernel on a big machine
might lead to the following WARNINGs (edited).
sched: DL de-boosted task PID 22725: REPLENISH flag missing
WARNING: CPU: 93 PID: 0 at kernel/sched/deadline.c:239 dequeue_task_dl+0x15c/0x1f8
... (running_bw underflow)
Call trace:
dequeue_task_dl+0x15c/0x1f8 (P)
dequeue_task+0x80/0x168
deactivate_task+0x24/0x50
push_dl_task+0x264/0x2e0
dl_task_timer+0x1b0/0x228
__hrtimer_run_queues+0x188/0x378
hrtimer_interrupt+0xfc/0x260
...
The problem is that when a SCHED_DEADLINE task (lock holder) is
changed to a lower priority class via sched_setscheduler(), it may
fail to properly inherit the parameters of potential DEADLINE donors
if it didn't already inherit them in the past (shorter deadline than
donor's at that time). This might lead to bandwidth accounting
corruption, as enqueue_task_dl() won't recognize the lock holder as
boosted.
The scenario occurs when:
1. A DEADLINE task (donor) blocks on a PI mutex held by another
DEADLINE task (holder), but the holder doesn't inherit parameters
(e.g., it already has a shorter deadline)
2. sched_setscheduler() changes the holder from DEADLINE to a lower
class while still holding the mutex
3. The holder should now inherit DEADLINE parameters from the donor
and be enqueued with ENQUEUE_REPLENISH, but this doesn't happen
Fix the issue by introducing __setscheduler_dl_pi(), which detects when
a DEADLINE (proper or boosted) task gets setscheduled to a lower
priority class. In case, the function makes the task inherit DEADLINE
parameters of the donoer (pi_se) and sets ENQUEUE_REPLENISH flag to
ensure proper bandwidth accounting during the next enqueue operation.
Fixes: 2279f540ea7d ("sched/deadline: Fix priority inheritance with multiple scheduling classes")
Reported-by: Bruno Goncalves <bgoncalv@redhat.com>
Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260302-upstream-fix-deadline-piboost-b4-v3-1-6ba32184a9e0@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/core.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index fa9008e5d8bd6..7494e05bbdc81 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7368,6 +7368,33 @@ static struct task_struct *find_process_by_pid(pid_t pid)
*/
#define SETPARAM_POLICY -1
+#ifdef CONFIG_RT_MUTEXES
+static inline void __setscheduler_dl_pi(int newprio, int policy,
+ struct task_struct *p, int *queue_flags)
+{
+ /*
+ * In case a DEADLINE task (either proper or boosted) gets
+ * setscheduled to a lower priority class, check if it neeeds to
+ * inherit parameters from a potential pi_task. In that case make
+ * sure replenishment happens with the next enqueue.
+ */
+
+ if (dl_prio(newprio) && !dl_policy(policy)) {
+ struct task_struct *pi_task = rt_mutex_get_top_task(p);
+
+ if (pi_task) {
+ p->dl.pi_se = pi_task->dl.pi_se;
+ *queue_flags |= ENQUEUE_REPLENISH;
+ }
+ }
+}
+#else /* !CONFIG_RT_MUTEXES */
+static inline void __setscheduler_dl_pi(int newprio, int policy,
+ struct task_struct *p, int *queue_flags)
+{
+}
+#endif /* !CONFIG_RT_MUTEXES */
+
static void __setscheduler_params(struct task_struct *p,
const struct sched_attr *attr)
{
@@ -7669,6 +7696,7 @@ static int __sched_setscheduler(struct task_struct *p,
if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
__setscheduler_params(p, attr);
__setscheduler_prio(p, newprio);
+ __setscheduler_dl_pi(newprio, policy, p, &queue_flags);
}
__setscheduler_uclamp(p, attr);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0940/1887] blktrace: fix __this_cpu_read/write in preemptible context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (938 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0939/1887] sched/deadline: Fix missing ENQUEUE_REPLENISH during PI de-boosting Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0941/1887] bpf, arm64: Force 8-byte alignment for JIT buffer to prevent atomic tearing Greg Kroah-Hartman
` (58 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shinichiro Kawasaki, Steven Rostedt,
Chaitanya Kulkarni, Jens Axboe, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaitanya Kulkarni <kch@nvidia.com>
[ Upstream commit da46b5dfef48658d03347cda21532bcdbb521e67 ]
tracing_record_cmdline() internally uses __this_cpu_read() and
__this_cpu_write() on the per-CPU variable trace_cmdline_save, and
trace_save_cmdline() explicitly asserts preemption is disabled via
lockdep_assert_preemption_disabled(). These operations are only safe
when preemption is off, as they were designed to be called from the
scheduler context (probe_wakeup_sched_switch() / probe_wakeup()).
__blk_add_trace() was calling tracing_record_cmdline(current) early in
the blk_tracer path, before ring buffer reservation, from process
context where preemption is fully enabled. This triggers the following
using blktests/blktrace/002:
blktrace/002 (blktrace ftrace corruption with sysfs trace) [failed]
runtime 0.367s ... 0.437s
something found in dmesg:
[ 81.211018] run blktests blktrace/002 at 2026-02-25 22:24:33
[ 81.239580] null_blk: disk nullb1 created
[ 81.357294] BUG: using __this_cpu_read() in preemptible [00000000] code: dd/2516
[ 81.362842] caller is tracing_record_cmdline+0x10/0x40
[ 81.362872] CPU: 16 UID: 0 PID: 2516 Comm: dd Tainted: G N 7.0.0-rc1lblk+ #84 PREEMPT(full)
[ 81.362877] Tainted: [N]=TEST
[ 81.362878] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
[ 81.362881] Call Trace:
[ 81.362884] <TASK>
[ 81.362886] dump_stack_lvl+0x8d/0xb0
...
(See '/mnt/sda/blktests/results/nodev/blktrace/002.dmesg' for the entire message)
[ 81.211018] run blktests blktrace/002 at 2026-02-25 22:24:33
[ 81.239580] null_blk: disk nullb1 created
[ 81.357294] BUG: using __this_cpu_read() in preemptible [00000000] code: dd/2516
[ 81.362842] caller is tracing_record_cmdline+0x10/0x40
[ 81.362872] CPU: 16 UID: 0 PID: 2516 Comm: dd Tainted: G N 7.0.0-rc1lblk+ #84 PREEMPT(full)
[ 81.362877] Tainted: [N]=TEST
[ 81.362878] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
[ 81.362881] Call Trace:
[ 81.362884] <TASK>
[ 81.362886] dump_stack_lvl+0x8d/0xb0
[ 81.362895] check_preemption_disabled+0xce/0xe0
[ 81.362902] tracing_record_cmdline+0x10/0x40
[ 81.362923] __blk_add_trace+0x307/0x5d0
[ 81.362934] ? lock_acquire+0xe0/0x300
[ 81.362940] ? iov_iter_extract_pages+0x101/0xa30
[ 81.362959] blk_add_trace_bio+0x106/0x1e0
[ 81.362968] submit_bio_noacct_nocheck+0x24b/0x3a0
[ 81.362979] ? lockdep_init_map_type+0x58/0x260
[ 81.362988] submit_bio_wait+0x56/0x90
[ 81.363009] __blkdev_direct_IO_simple+0x16c/0x250
[ 81.363026] ? __pfx_submit_bio_wait_endio+0x10/0x10
[ 81.363038] ? rcu_read_lock_any_held+0x73/0xa0
[ 81.363051] blkdev_read_iter+0xc1/0x140
[ 81.363059] vfs_read+0x20b/0x330
[ 81.363083] ksys_read+0x67/0xe0
[ 81.363090] do_syscall_64+0xbf/0xf00
[ 81.363102] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 81.363106] RIP: 0033:0x7f281906029d
[ 81.363111] Code: 31 c0 e9 c6 fe ff ff 50 48 8d 3d 66 63 0a 00 e8 59 ff 01 00 66 0f 1f 84 00 00 00 00 00 80 3d 41 33 0e 00 00 74 17 31 c0 0f 05 <48> 3d 00 f0 ff ff 77 5b c3 66 2e 0f 1f 84 00 00 00 00 00 48 83 ec
[ 81.363113] RSP: 002b:00007ffca127dd48 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[ 81.363120] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f281906029d
[ 81.363122] RDX: 0000000000001000 RSI: 0000559f8bfae000 RDI: 0000000000000000
[ 81.363123] RBP: 0000000000001000 R08: 0000002863a10a81 R09: 00007f281915f000
[ 81.363124] R10: 00007f2818f77b60 R11: 0000000000000246 R12: 0000559f8bfae000
[ 81.363126] R13: 0000000000000000 R14: 0000000000000000 R15: 000000000000000a
[ 81.363142] </TASK>
The same BUG fires from blk_add_trace_plug(), blk_add_trace_unplug(),
and blk_add_trace_rq() paths as well.
The purpose of tracing_record_cmdline() is to cache the task->comm for
a given PID so that the trace can later resolve it. It is only
meaningful when a trace event is actually being recorded. Ring buffer
reservation via ring_buffer_lock_reserve() disables preemption, and
preemption remains disabled until the event is committed :-
__blk_add_trace()
__trace_buffer_lock_reserve()
__trace_buffer_lock_reserve()
ring_buffer_lock_reserve()
preempt_disable_notrace(); <---
With this fix blktests for blktrace pass:
blktests (master) # ./check blktrace
blktrace/001 (blktrace zone management command tracing) [passed]
runtime 3.650s ... 3.647s
blktrace/002 (blktrace ftrace corruption with sysfs trace) [passed]
runtime 0.411s ... 0.384s
Fixes: 7ffbd48d5cab ("tracing: Cache comms only after an event occurred")
Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/blktrace.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index a5b35bcfb0602..5f76d59489fbe 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -251,8 +251,6 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
cpu = raw_smp_processor_id();
if (blk_tracer) {
- tracing_record_cmdline(current);
-
buffer = blk_tr->array_buffer.buffer;
trace_ctx = tracing_gen_ctx_flags(0);
event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
@@ -260,6 +258,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
trace_ctx);
if (!event)
return;
+ tracing_record_cmdline(current);
t = ring_buffer_event_data(event);
goto record_it;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0941/1887] bpf, arm64: Force 8-byte alignment for JIT buffer to prevent atomic tearing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (939 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0940/1887] blktrace: fix __this_cpu_read/write in preemptible context Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0942/1887] net/rds: Fix circular locking dependency in rds_tcp_tune Greg Kroah-Hartman
` (57 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fuad Tabba, Will Deacon,
Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <tabba@google.com>
[ Upstream commit ef06fd16d48704eac868441d98d4ef083d8f3d07 ]
struct bpf_plt contains a u64 target field. Currently, the BPF JIT
allocator requests an alignment of 4 bytes (sizeof(u32)) for the JIT
buffer.
Because the base address of the JIT buffer can be 4-byte aligned (e.g.,
ending in 0x4 or 0xc), the relative padding logic in build_plt() fails
to ensure that target lands on an 8-byte boundary.
This leads to two issues:
1. UBSAN reports misaligned-access warnings when dereferencing the
structure.
2. More critically, target is updated concurrently via WRITE_ONCE() in
bpf_arch_text_poke() while the JIT'd code executes ldr. On arm64,
64-bit loads/stores are only guaranteed to be single-copy atomic if
they are 64-bit aligned. A misaligned target risks a torn read,
causing the JIT to jump to a corrupted address.
Fix this by increasing the allocation alignment requirement to 8 bytes
(sizeof(u64)) in bpf_jit_binary_pack_alloc(). This anchors the base of
the JIT buffer to an 8-byte boundary, allowing the relative padding math
in build_plt() to correctly align the target field.
Fixes: b2ad54e1533e ("bpf, arm64: Implement bpf_arch_text_poke() for arm64")
Signed-off-by: Fuad Tabba <tabba@google.com>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20260226075525.233321-1-tabba@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/net/bpf_jit_comp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e66218aed831d..1a8627ab4f2cc 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1589,7 +1589,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align);
image_size = extable_offset + extable_size;
header = bpf_jit_binary_alloc(image_size, &image_ptr,
- sizeof(u32), jit_fill_hole);
+ sizeof(u64), jit_fill_hole);
if (header == NULL) {
prog = orig_prog;
goto out_off;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0942/1887] net/rds: Fix circular locking dependency in rds_tcp_tune
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (940 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0941/1887] bpf, arm64: Force 8-byte alignment for JIT buffer to prevent atomic tearing Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0943/1887] btrfs: log new dentries when logging parent dir of a conflicting inode Greg Kroah-Hartman
` (56 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2e2cf5331207053b8106,
Allison Henderson, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 6a877ececd6daa002a9a0002cd0fbca6592a9244 ]
syzbot reported a circular locking dependency in rds_tcp_tune() where
sk_net_refcnt_upgrade() is called while holding the socket lock:
======================================================
WARNING: possible circular locking dependency detected
======================================================
kworker/u10:8/15040 is trying to acquire lock:
ffffffff8e9aaf80 (fs_reclaim){+.+.}-{0:0},
at: __kmalloc_cache_noprof+0x4b/0x6f0
but task is already holding lock:
ffff88805a3c1ce0 (k-sk_lock-AF_INET6){+.+.}-{0:0},
at: rds_tcp_tune+0xd7/0x930
The issue occurs because sk_net_refcnt_upgrade() performs memory
allocation (via get_net_track() -> ref_tracker_alloc()) while the
socket lock is held, creating a circular dependency with fs_reclaim.
Fix this by moving sk_net_refcnt_upgrade() outside the socket lock
critical section. This is safe because the fields modified by the
sk_net_refcnt_upgrade() call (sk_net_refcnt, ns_tracker) are not
accessed by any concurrent code path at this point.
v2:
- Corrected fixes tag
- check patch line wrap nits
- ai commentary nits
Reported-by: syzbot+2e2cf5331207053b8106@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2e2cf5331207053b8106
Fixes: 3a58f13a881e ("net: rds: acquire refcount on TCP sockets")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260227202336.167757-1-achender@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/tcp.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 020baff6ad514..5b4af800dcdc5 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -569,19 +569,25 @@ bool rds_tcp_tune(struct socket *sock)
struct rds_tcp_net *rtn;
tcp_sock_set_nodelay(sock->sk);
- lock_sock(sk);
/* TCP timer functions might access net namespace even after
* a process which created this net namespace terminated.
*/
if (!sk->sk_net_refcnt) {
- if (!maybe_get_net(net)) {
- release_sock(sk);
+ if (!maybe_get_net(net))
return false;
- }
+ /*
+ * The sk_net_refcnt upgrade must be done before lock_sock()
+ * because netns_tracker_alloc() does a GFP_KERNEL allocation,
+ * which can trigger fs_reclaim and create a circular lock
+ * dependency with the socket lock. The fields it modifies
+ * (sk_net_refcnt, ns_tracker) are not accessed by any
+ * concurrent code path at this point.
+ */
sk->sk_net_refcnt = 1;
netns_tracker_alloc(net, &sk->ns_tracker, GFP_KERNEL);
sock_inuse_add(net, 1);
}
+ lock_sock(sk);
rtn = net_generic(net, rds_tcp_netid);
if (rtn->sndbuf_size > 0) {
sk->sk_sndbuf = rtn->sndbuf_size;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0943/1887] btrfs: log new dentries when logging parent dir of a conflicting inode
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (941 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0942/1887] net/rds: Fix circular locking dependency in rds_tcp_tune Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0944/1887] serial: core: fix infinite loop in handle_tx() for PORT_UNKNOWN Greg Kroah-Hartman
` (55 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vyacheslav Kovalevsky, Boris Burkov,
Filipe Manana, David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 9573a365ff9ff45da9222d3fe63695ce562beb24 ]
If we log the parent directory of a conflicting inode, we are not logging
the new dentries of the directory, so when we finish we have the parent
directory's inode marked as logged but we did not log its new dentries.
As a consequence if the parent directory is explicitly fsynced later and
it does not have any new changes since we logged it, the fsync is a no-op
and after a power failure the new dentries are missing.
Example scenario:
$ mkdir foo
$ sync
$rmdir foo
$ mkdir dir1
$ mkdir dir2
# A file with the same name and parent as the directory we just deleted
# and was persisted in a past transaction. So the deleted directory's
# inode is a conflicting inode of this new file's inode.
$ touch foo
$ ln foo dir2/link
# The fsync on dir2 will log the parent directory (".") because the
# conflicting inode (deleted directory) does not exists anymore, but it
# it does not log its new dentries (dir1).
$ xfs_io -c "fsync" dir2
# This fsync on the parent directory is no-op, since the previous fsync
# logged it (but without logging its new dentries).
$ xfs_io -c "fsync" .
<power failure>
# After log replay dir1 is missing.
Fix this by ensuring we log new dir dentries whenever we log the parent
directory of a no longer existing conflicting inode.
A test case for fstests will follow soon.
Reported-by: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/182055fa-e9ce-4089-9f5f-4b8a23e8dd91@gmail.com/
Fixes: a3baaf0d786e ("Btrfs: fix fsync after succession of renames and unlink/rmdir")
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/tree-log.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index ceb2a9556fe7b..e361a608f3ae9 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -5793,6 +5793,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
struct btrfs_log_ctx *ctx)
{
struct btrfs_fs_info *fs_info = root->fs_info;
+ const bool orig_log_new_dentries = ctx->log_new_dentries;
int ret = 0;
/*
@@ -5854,8 +5855,12 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
* dir index key range logged for the directory. So we
* must make sure the deletion is recorded.
*/
+ ctx->log_new_dentries = false;
ret = btrfs_log_inode(trans, BTRFS_I(inode),
LOG_INODE_ALL, ctx);
+ if (!ret && ctx->log_new_dentries)
+ ret = log_new_dir_dentries(trans, BTRFS_I(inode), ctx);
+
btrfs_add_delayed_iput(inode);
if (ret)
break;
@@ -5890,6 +5895,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
break;
}
+ ctx->log_new_dentries = orig_log_new_dentries;
ctx->logging_conflict_inodes = false;
if (ret)
free_conflicting_inodes(ctx);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0944/1887] serial: core: fix infinite loop in handle_tx() for PORT_UNKNOWN
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (942 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0943/1887] btrfs: log new dentries when logging parent dir of a conflicting inode Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0945/1887] ksmbd: use volume UUID in FS_OBJECT_ID_INFORMATION Greg Kroah-Hartman
` (54 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, stable, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@shopee.com>
[ Upstream commit 455ce986fa356ff43a43c0d363ba95fa152f21d5 ]
uart_write_room() and uart_write() behave inconsistently when
xmit_buf is NULL (which happens for PORT_UNKNOWN ports that were
never properly initialized):
- uart_write_room() returns kfifo_avail() which can be > 0
- uart_write() checks xmit_buf and returns 0 if NULL
This inconsistency causes an infinite loop in drivers that rely on
tty_write_room() to determine if they can write:
while (tty_write_room(tty) > 0) {
written = tty->ops->write(...);
// written is always 0, loop never exits
}
For example, caif_serial's handle_tx() enters an infinite loop when
used with PORT_UNKNOWN serial ports, causing system hangs.
Fix by making uart_write_room() also check xmit_buf and return 0 if
it's NULL, consistent with uart_write().
Reproducer: https://gist.github.com/mrpre/d9a694cc0e19828ee3bc3b37983fde13
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
Cc: stable <stable@kernel.org>
Link: https://patch.msgid.link/20260204074327.226165-1-jiayuan.chen@linux.dev
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/serial_core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index dafbd24b91484..4b035292a3840 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -610,7 +610,10 @@ static unsigned int uart_write_room(struct tty_struct *tty)
unsigned int ret;
port = uart_port_lock(state, flags);
- ret = uart_circ_chars_free(&state->xmit);
+ if (!state->xmit.buf)
+ ret = 0;
+ else
+ ret = uart_circ_chars_free(&state->xmit);
uart_port_unlock(port, flags);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0945/1887] ksmbd: use volume UUID in FS_OBJECT_ID_INFORMATION
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (943 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0944/1887] serial: core: fix infinite loop in handle_tx() for PORT_UNKNOWN Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0946/1887] ksmbd: fix OOB write in QUERY_INFO for compound requests Greg Kroah-Hartman
` (53 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 3a64125730cabc34fccfbc230c2667c2e14f7308 ]
Use sb->s_uuid for a proper volume identifier as the primary choice.
For filesystems that do not provide a UUID, fall back to stfs.f_fsid
obtained from vfs_statfs().
Cc: stable@vger.kernel.org
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b05a9488aaa4d..21f90efc6783c 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5119,7 +5119,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp)
{
- struct ksmbd_session *sess = work->sess;
struct ksmbd_conn *conn = work->conn;
struct ksmbd_share_config *share = work->tcon->share_conf;
int fsinfoclass = 0;
@@ -5249,10 +5248,13 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info = (struct object_id_info *)(rsp->Buffer);
- if (!user_guest(sess->user))
- memcpy(info->objid, user_passkey(sess->user), 16);
- else
- memset(info->objid, 0, 16);
+ if (!uuid_is_null(&path.mnt->mnt_sb->s_uuid))
+ memcpy(info->objid, path.mnt->mnt_sb->s_uuid.b,
+ sizeof(path.mnt->mnt_sb->s_uuid));
+ else {
+ memset(info->objid, 0, sizeof(info->objid));
+ memcpy(info->objid, &stfs.f_fsid, sizeof(stfs.f_fsid));
+ }
info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC);
info->extended_info.version = cpu_to_le32(1);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0946/1887] ksmbd: fix OOB write in QUERY_INFO for compound requests
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (944 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0945/1887] ksmbd: use volume UUID in FS_OBJECT_ID_INFORMATION Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0947/1887] drm/amdgpu: Remove usage of the deprecated ida_simple_xx() API Greg Kroah-Hartman
` (52 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Asim Viladi Oglu Manizada,
Namjae Jeon, Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asim Viladi Oglu Manizada <manizada@pm.me>
[ Upstream commit fda9522ed6afaec45cabc198d8492270c394c7bc ]
When a compound request such as READ + QUERY_INFO(Security) is received,
and the first command (READ) consumes most of the response buffer,
ksmbd could write beyond the allocated buffer while building a security
descriptor.
The root cause was that smb2_get_info_sec() checked buffer space using
ppntsd_size from xattr, while build_sec_desc() often synthesized a
significantly larger descriptor from POSIX ACLs.
This patch introduces smb_acl_sec_desc_scratch_len() to accurately
compute the final descriptor size beforehand, performs proper buffer
checking with smb2_calc_max_out_buf_len(), and uses exact-sized
allocation + iov pinning.
Cc: stable@vger.kernel.org
Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 121 +++++++++++++++++++++++++++++-----------
fs/smb/server/smbacl.c | 43 ++++++++++++++
fs/smb/server/smbacl.h | 2 +
3 files changed, 134 insertions(+), 32 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 21f90efc6783c..487aff42b912c 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3191,20 +3191,24 @@ int smb2_open(struct ksmbd_work *work)
KSMBD_SHARE_FLAG_ACL_XATTR)) {
struct smb_fattr fattr;
struct smb_ntsd *pntsd;
- int pntsd_size, ace_num = 0;
+ int pntsd_size;
+ size_t scratch_len;
ksmbd_acls_fattr(&fattr, user_ns, inode);
- if (fattr.cf_acls)
- ace_num = fattr.cf_acls->a_count;
- if (fattr.cf_dacls)
- ace_num += fattr.cf_dacls->a_count;
-
- pntsd = kmalloc(sizeof(struct smb_ntsd) +
- sizeof(struct smb_sid) * 3 +
- sizeof(struct smb_acl) +
- sizeof(struct smb_ace) * ace_num * 2,
- GFP_KERNEL);
+ scratch_len = smb_acl_sec_desc_scratch_len(&fattr,
+ NULL, 0,
+ OWNER_SECINFO | GROUP_SECINFO |
+ DACL_SECINFO);
+ if (!scratch_len || scratch_len == SIZE_MAX) {
+ rc = -EFBIG;
+ posix_acl_release(fattr.cf_acls);
+ posix_acl_release(fattr.cf_dacls);
+ goto err_out;
+ }
+
+ pntsd = kvzalloc(scratch_len, GFP_KERNEL);
if (!pntsd) {
+ rc = -ENOMEM;
posix_acl_release(fattr.cf_acls);
posix_acl_release(fattr.cf_dacls);
goto err_out;
@@ -3219,7 +3223,7 @@ int smb2_open(struct ksmbd_work *work)
posix_acl_release(fattr.cf_acls);
posix_acl_release(fattr.cf_dacls);
if (rc) {
- kfree(pntsd);
+ kvfree(pntsd);
goto err_out;
}
@@ -3229,7 +3233,7 @@ int smb2_open(struct ksmbd_work *work)
pntsd,
pntsd_size,
false);
- kfree(pntsd);
+ kvfree(pntsd);
if (rc)
pr_err("failed to store ntacl in xattr : %d\n",
rc);
@@ -5011,8 +5015,9 @@ static int smb2_get_info_file(struct ksmbd_work *work,
if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_PIPE)) {
/* smb2 info file called for pipe */
- return smb2_get_info_file_pipe(work->sess, req, rsp,
+ rc = smb2_get_info_file_pipe(work->sess, req, rsp,
work->response_buf);
+ goto iov_pin_out;
}
if (work->next_smb2_rcv_hdr_off) {
@@ -5112,6 +5117,12 @@ static int smb2_get_info_file(struct ksmbd_work *work,
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
rsp, work->response_buf);
ksmbd_fd_put(work, fp);
+
+iov_pin_out:
+ if (!rc)
+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
+ offsetof(struct smb2_query_info_rsp, Buffer) +
+ le32_to_cpu(rsp->OutputBufferLength));
return rc;
}
@@ -5333,6 +5344,11 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
rsp, work->response_buf);
path_put(&path);
+
+ if (!rc)
+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
+ offsetof(struct smb2_query_info_rsp, Buffer) +
+ le32_to_cpu(rsp->OutputBufferLength));
return rc;
}
@@ -5342,13 +5358,14 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
{
struct ksmbd_file *fp;
struct user_namespace *user_ns;
- struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL;
+ struct smb_ntsd *pntsd = NULL, *ppntsd = NULL;
struct smb_fattr fattr = {{0}};
struct inode *inode;
__u32 secdesclen = 0;
unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
int addition_info = le32_to_cpu(req->AdditionalInformation);
- int rc = 0, ppntsd_size = 0;
+ int rc = 0, ppntsd_size = 0, max_len;
+ size_t scratch_len = 0;
if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
PROTECTED_DACL_SECINFO |
@@ -5356,6 +5373,11 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
addition_info);
+ pntsd = kzalloc(ALIGN(sizeof(struct smb_ntsd), 8),
+ GFP_KERNEL);
+ if (!pntsd)
+ return -ENOMEM;
+
pntsd->revision = cpu_to_le16(1);
pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED);
pntsd->osidoffset = 0;
@@ -5364,9 +5386,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
pntsd->dacloffset = 0;
secdesclen = sizeof(struct smb_ntsd);
- rsp->OutputBufferLength = cpu_to_le32(secdesclen);
-
- return 0;
+ goto iov_pin;
}
if (work->next_smb2_rcv_hdr_off) {
@@ -5398,18 +5418,58 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
&ppntsd);
/* Check if sd buffer size exceeds response buffer size */
- if (smb2_resp_buf_len(work, 8) > ppntsd_size)
- rc = build_sec_desc(user_ns, pntsd, ppntsd, ppntsd_size,
- addition_info, &secdesclen, &fattr);
+ max_len = smb2_calc_max_out_buf_len(work,
+ offsetof(struct smb2_query_info_rsp, Buffer),
+ le32_to_cpu(req->OutputBufferLength));
+ if (max_len < 0) {
+ rc = -EINVAL;
+ goto release_acl;
+ }
+
+ scratch_len = smb_acl_sec_desc_scratch_len(&fattr, ppntsd,
+ ppntsd_size, addition_info);
+ if (!scratch_len || scratch_len == SIZE_MAX) {
+ rc = -EFBIG;
+ goto release_acl;
+ }
+
+ pntsd = kvzalloc(scratch_len, GFP_KERNEL);
+ if (!pntsd) {
+ rc = -ENOMEM;
+ goto release_acl;
+ }
+
+ rc = build_sec_desc(user_ns, pntsd, ppntsd, ppntsd_size,
+ addition_info, &secdesclen, &fattr);
+
+release_acl:
posix_acl_release(fattr.cf_acls);
posix_acl_release(fattr.cf_dacls);
kfree(ppntsd);
ksmbd_fd_put(work, fp);
+
+ if (!rc && ALIGN(secdesclen, 8) > scratch_len)
+ rc = -EFBIG;
if (rc)
- return rc;
+ goto err_out;
+iov_pin:
rsp->OutputBufferLength = cpu_to_le32(secdesclen);
- return 0;
+ rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ rsp, work->response_buf);
+ if (rc)
+ goto err_out;
+
+ rc = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
+ offsetof(struct smb2_query_info_rsp, Buffer),
+ pntsd, secdesclen);
+err_out:
+ if (rc) {
+ rsp->OutputBufferLength = 0;
+ kvfree(pntsd);
+ }
+
+ return rc;
}
/**
@@ -5433,6 +5493,9 @@ int smb2_query_info(struct ksmbd_work *work)
goto err_out;
}
+ rsp->StructureSize = cpu_to_le16(9);
+ rsp->OutputBufferOffset = cpu_to_le16(72);
+
switch (req->InfoType) {
case SMB2_O_INFO_FILE:
ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
@@ -5453,14 +5516,6 @@ int smb2_query_info(struct ksmbd_work *work)
}
ksmbd_revert_fsids(work);
- if (!rc) {
- rsp->StructureSize = cpu_to_le16(9);
- rsp->OutputBufferOffset = cpu_to_le16(72);
- rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
- offsetof(struct smb2_query_info_rsp, Buffer) +
- le32_to_cpu(rsp->OutputBufferLength));
- }
-
err_out:
if (rc < 0) {
if (rc == -EACCES)
@@ -5471,6 +5526,8 @@ int smb2_query_info(struct ksmbd_work *work)
rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
else if (rc == -ENOMEM)
rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
+ else if (rc == -EINVAL && rsp->hdr.Status == 0)
+ rsp->hdr.Status = STATUS_INVALID_PARAMETER;
else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0)
rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
smb2_set_err_rsp(work);
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index 5cb020fc01050..d09cd2ddd1adb 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -961,6 +961,49 @@ int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
return 0;
}
+size_t smb_acl_sec_desc_scratch_len(struct smb_fattr *fattr,
+ struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info)
+{
+ size_t len = sizeof(struct smb_ntsd);
+ size_t tmp;
+
+ if (addition_info & OWNER_SECINFO)
+ len += sizeof(struct smb_sid);
+ if (addition_info & GROUP_SECINFO)
+ len += sizeof(struct smb_sid);
+ if (!(addition_info & DACL_SECINFO))
+ return len;
+
+ len += sizeof(struct smb_acl);
+ if (ppntsd && ppntsd_size > 0) {
+ unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
+
+ if (dacl_offset < ppntsd_size &&
+ check_add_overflow(len, ppntsd_size - dacl_offset, &len))
+ return 0;
+ }
+
+ if (fattr->cf_acls) {
+ if (check_mul_overflow((size_t)fattr->cf_acls->a_count,
+ 2 * sizeof(struct smb_ace), &tmp) ||
+ check_add_overflow(len, tmp, &len))
+ return 0;
+ } else {
+ /* default/minimum DACL */
+ if (check_add_overflow(len, 5 * sizeof(struct smb_ace), &len))
+ return 0;
+ }
+
+ if (fattr->cf_dacls) {
+ if (check_mul_overflow((size_t)fattr->cf_dacls->a_count,
+ sizeof(struct smb_ace), &tmp) ||
+ check_add_overflow(len, tmp, &len))
+ return 0;
+ }
+
+ return len;
+}
+
/* Convert permission bits from mode to equivalent CIFS ACL */
int build_sec_desc(struct user_namespace *user_ns,
struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
diff --git a/fs/smb/server/smbacl.h b/fs/smb/server/smbacl.h
index 9651a25518881..81eff590fdda0 100644
--- a/fs/smb/server/smbacl.h
+++ b/fs/smb/server/smbacl.h
@@ -210,6 +210,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
bool type_check, bool get_write);
void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid);
void ksmbd_init_domain(u32 *sub_auth);
+size_t smb_acl_sec_desc_scratch_len(struct smb_fattr *fattr,
+ struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info);
static inline uid_t posix_acl_uid_translate(struct user_namespace *mnt_userns,
struct posix_acl_entry *pace)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0947/1887] drm/amdgpu: Remove usage of the deprecated ida_simple_xx() API
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (945 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0946/1887] ksmbd: fix OOB write in QUERY_INFO for compound requests Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0948/1887] drm/amdgpu: prevent immediate PASID reuse case Greg Kroah-Hartman
` (51 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christophe JAILLET,
Christian König, Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
[ Upstream commit 8a1f7fddabe112f463c2fd5d1e41c9c87d0a9957 ]
ida_alloc() and ida_free() should be preferred to the deprecated
ida_simple_get() and ida_simple_remove().
Note that the upper limit of ida_simple_get() is exclusive, but the one of
ida_alloc_range() is inclusive. So a -1 has been added when needed.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 14b81abe7bdc ("drm/amdgpu: prevent immediate PASID reuse case")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index 03d115d2b5edd..43557748d1139 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -62,9 +62,8 @@ int amdgpu_pasid_alloc(unsigned int bits)
int pasid = -EINVAL;
for (bits = min(bits, 31U); bits > 0; bits--) {
- pasid = ida_simple_get(&amdgpu_pasid_ida,
- 1U << (bits - 1), 1U << bits,
- GFP_KERNEL);
+ pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1),
+ (1U << bits) - 1, GFP_KERNEL);
if (pasid != -ENOSPC)
break;
}
@@ -82,7 +81,7 @@ int amdgpu_pasid_alloc(unsigned int bits)
void amdgpu_pasid_free(u32 pasid)
{
trace_amdgpu_pasid_freed(pasid);
- ida_simple_remove(&amdgpu_pasid_ida, pasid);
+ ida_free(&amdgpu_pasid_ida, pasid);
}
static void amdgpu_pasid_free_cb(struct dma_fence *fence,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0948/1887] drm/amdgpu: prevent immediate PASID reuse case
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (946 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0947/1887] drm/amdgpu: Remove usage of the deprecated ida_simple_xx() API Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0949/1887] hwmon: (pmbus/core) Protect regulator operations with mutex Greg Kroah-Hartman
` (50 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Huang, Christian König,
Alex Deucher, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Huang <jinhuieric.huang@amd.com>
[ Upstream commit 14b81abe7bdc25f8097906fc2f91276ffedb2d26 ]
PASID resue could cause interrupt issue when process
immediately runs into hw state left by previous
process exited with the same PASID, it's possible that
page faults are still pending in the IH ring buffer when
the process exits and frees up its PASID. To prevent the
case, it uses idr cyclic allocator same as kernel pid's.
Signed-off-by: Eric Huang <jinhuieric.huang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 8f1de51f49be692de137c8525106e0fce2d1912d)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 45 ++++++++++++++++++-------
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h | 1 +
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 +
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index 43557748d1139..5b248c4df12d5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -35,10 +35,13 @@
* PASIDs are global address space identifiers that can be shared
* between the GPU, an IOMMU and the driver. VMs on different devices
* may use the same PASID if they share the same address
- * space. Therefore PASIDs are allocated using a global IDA. VMs are
- * looked up from the PASID per amdgpu_device.
+ * space. Therefore PASIDs are allocated using IDR cyclic allocator
+ * (similar to kernel PID allocation) which naturally delays reuse.
+ * VMs are looked up from the PASID per amdgpu_device.
*/
-static DEFINE_IDA(amdgpu_pasid_ida);
+
+static DEFINE_IDR(amdgpu_pasid_idr);
+static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock);
/* Helper to free pasid from a fence callback */
struct amdgpu_pasid_cb {
@@ -50,8 +53,8 @@ struct amdgpu_pasid_cb {
* amdgpu_pasid_alloc - Allocate a PASID
* @bits: Maximum width of the PASID in bits, must be at least 1
*
- * Allocates a PASID of the given width while keeping smaller PASIDs
- * available if possible.
+ * Uses kernel's IDR cyclic allocator (same as PID allocation).
+ * Allocates sequentially with automatic wrap-around.
*
* Returns a positive integer on success. Returns %-EINVAL if bits==0.
* Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
@@ -59,14 +62,15 @@ struct amdgpu_pasid_cb {
*/
int amdgpu_pasid_alloc(unsigned int bits)
{
- int pasid = -EINVAL;
+ int pasid;
- for (bits = min(bits, 31U); bits > 0; bits--) {
- pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1),
- (1U << bits) - 1, GFP_KERNEL);
- if (pasid != -ENOSPC)
- break;
- }
+ if (bits == 0)
+ return -EINVAL;
+
+ spin_lock(&amdgpu_pasid_idr_lock);
+ pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
+ 1U << bits, GFP_KERNEL);
+ spin_unlock(&amdgpu_pasid_idr_lock);
if (pasid >= 0)
trace_amdgpu_pasid_allocated(pasid);
@@ -81,7 +85,10 @@ int amdgpu_pasid_alloc(unsigned int bits)
void amdgpu_pasid_free(u32 pasid)
{
trace_amdgpu_pasid_freed(pasid);
- ida_free(&amdgpu_pasid_ida, pasid);
+
+ spin_lock(&amdgpu_pasid_idr_lock);
+ idr_remove(&amdgpu_pasid_idr, pasid);
+ spin_unlock(&amdgpu_pasid_idr_lock);
}
static void amdgpu_pasid_free_cb(struct dma_fence *fence,
@@ -581,3 +588,15 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
}
}
}
+
+/**
+ * amdgpu_pasid_mgr_cleanup - cleanup PASID manager
+ *
+ * Cleanup the IDR allocator.
+ */
+void amdgpu_pasid_mgr_cleanup(void)
+{
+ spin_lock(&amdgpu_pasid_idr_lock);
+ idr_destroy(&amdgpu_pasid_idr);
+ spin_unlock(&amdgpu_pasid_idr_lock);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
index 06c8a0034fa52..235e7561741a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
@@ -74,6 +74,7 @@ int amdgpu_pasid_alloc(unsigned int bits);
void amdgpu_pasid_free(u32 pasid);
void amdgpu_pasid_free_delayed(struct dma_resv *resv,
u32 pasid);
+void amdgpu_pasid_mgr_cleanup(void);
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
struct amdgpu_vmid *id);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 84e5fe9949f18..3f2b0f192ef41 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2484,6 +2484,7 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
xa_destroy(&adev->vm_manager.pasids);
amdgpu_vmid_mgr_fini(adev);
+ amdgpu_pasid_mgr_cleanup();
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0949/1887] hwmon: (pmbus/core) Protect regulator operations with mutex
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (947 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0948/1887] drm/amdgpu: prevent immediate PASID reuse case Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0950/1887] team: fix header_ops type confusion with non-Ethernet ports Greg Kroah-Hartman
` (49 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sanman Pradhan, Guenter Roeck,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 754bd2b4a084b90b5e7b630e1f423061a9b9b761 ]
The regulator operations pmbus_regulator_get_voltage(),
pmbus_regulator_set_voltage(), and pmbus_regulator_list_voltage()
access PMBus registers and shared data but were not protected by
the update_lock mutex. This could lead to race conditions.
However, adding mutex protection directly to these functions causes
a deadlock because pmbus_regulator_notify() (which calls
regulator_notifier_call_chain()) is often called with the mutex
already held (e.g., from pmbus_fault_handler()). If a regulator
callback then calls one of the now-protected voltage functions,
it will attempt to acquire the same mutex.
Rework pmbus_regulator_notify() to utilize a worker function to
send notifications outside of the mutex protection. Events are
stored as atomics in a per-page bitmask and processed by the worker.
Initialize the worker and its associated data during regulator
registration, and ensure it is cancelled on device removal using
devm_add_action_or_reset().
While at it, remove the unnecessary include of linux/of.h.
Cc: Sanman Pradhan <psanman@juniper.net>
Fixes: ddbb4db4ced1b ("hwmon: (pmbus) Add regulator support")
Reviewed-by: Sanman Pradhan <psanman@juniper.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pmbus/pmbus_core.c | 60 +++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 11c95fc3305a1..44e4d47372a6f 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -19,7 +19,6 @@
#include <linux/pmbus.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
-#include <linux/of.h>
#include <linux/thermal.h>
#include "pmbus.h"
@@ -2926,12 +2925,19 @@ static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
.class = PSC_VOLTAGE_OUT,
.convert = true,
};
+ int ret;
+ mutex_lock(&data->update_lock);
s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_READ_VOUT);
- if (s.data < 0)
- return s.data;
+ if (s.data < 0) {
+ ret = s.data;
+ goto unlock;
+ }
- return (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */
+ ret = (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */
+unlock:
+ mutex_unlock(&data->update_lock);
+ return ret;
}
static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
@@ -2948,16 +2954,22 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
};
int val = DIV_ROUND_CLOSEST(min_uv, 1000); /* convert to mV */
int low, high;
+ int ret;
*selector = 0;
+ mutex_lock(&data->update_lock);
low = pmbus_regulator_get_low_margin(client, s.page);
- if (low < 0)
- return low;
+ if (low < 0) {
+ ret = low;
+ goto unlock;
+ }
high = pmbus_regulator_get_high_margin(client, s.page);
- if (high < 0)
- return high;
+ if (high < 0) {
+ ret = high;
+ goto unlock;
+ }
/* Make sure we are within margins */
if (low > val)
@@ -2967,7 +2979,10 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
val = pmbus_data2reg(data, &s, val);
- return _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val);
+ ret = _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val);
+unlock:
+ mutex_unlock(&data->update_lock);
+ return ret;
}
static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
@@ -2975,7 +2990,9 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
{
struct device *dev = rdev_get_dev(rdev);
struct i2c_client *client = to_i2c_client(dev->parent);
+ struct pmbus_data *data = i2c_get_clientdata(client);
int val, low, high;
+ int ret;
if (selector >= rdev->desc->n_voltages ||
selector < rdev->desc->linear_min_sel)
@@ -2985,18 +3002,29 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
val = DIV_ROUND_CLOSEST(rdev->desc->min_uV +
(rdev->desc->uV_step * selector), 1000); /* convert to mV */
+ mutex_lock(&data->update_lock);
+
low = pmbus_regulator_get_low_margin(client, rdev_get_id(rdev));
- if (low < 0)
- return low;
+ if (low < 0) {
+ ret = low;
+ goto unlock;
+ }
high = pmbus_regulator_get_high_margin(client, rdev_get_id(rdev));
- if (high < 0)
- return high;
+ if (high < 0) {
+ ret = high;
+ goto unlock;
+ }
- if (val >= low && val <= high)
- return val * 1000; /* unit is uV */
+ if (val >= low && val <= high) {
+ ret = val * 1000; /* unit is uV */
+ goto unlock;
+ }
- return 0;
+ ret = 0;
+unlock:
+ mutex_unlock(&data->update_lock);
+ return ret;
}
const struct regulator_ops pmbus_regulator_ops = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0950/1887] team: fix header_ops type confusion with non-Ethernet ports
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (948 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0949/1887] hwmon: (pmbus/core) Protect regulator operations with mutex Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0951/1887] iavf: fix out-of-bounds writes in iavf_get_ethtool_stats() Greg Kroah-Hartman
` (48 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+3d8bc31c45e11450f24c,
Jiayuan Chen, Jiayuan Chen, Paolo Abeni, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@shopee.com>
[ Upstream commit 425000dbf17373a4ab8be9428f5dc055ef870a56 ]
Similar to commit 950803f72547 ("bonding: fix type confusion in
bond_setup_by_slave()") team has the same class of header_ops type
confusion.
For non-Ethernet ports, team_setup_by_port() copies port_dev->header_ops
directly. When the team device later calls dev_hard_header() or
dev_parse_header(), these callbacks can run with the team net_device
instead of the real lower device, so netdev_priv(dev) is interpreted as
the wrong private type and can crash.
The syzbot report shows a crash in bond_header_create(), but the root
cause is in team: the topology is gre -> bond -> team, and team calls
the inherited header_ops with its own net_device instead of the lower
device, so bond_header_create() receives a team device and interprets
netdev_priv() as bonding private data, causing a type confusion crash.
Fix this by introducing team header_ops wrappers for create/parse,
selecting a team port under RCU, and calling the lower device callbacks
with port->dev, so each callback always sees the correct net_device
context.
Also pass the selected lower device to the lower parse callback, so
recursion is bounded in stacked non-Ethernet topologies and parse
callbacks always run with the correct device context.
Fixes: 1d76efe1577b ("team: add support for non-ethernet devices")
Reported-by: syzbot+3d8bc31c45e11450f24c@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69b46af7.050a0220.36eb34.000e.GAE@google.com/T/
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
Link: https://patch.msgid.link/20260320072139.134249-2-jiayuan.chen@linux.dev
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 73 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 874a8b78803c4..386c989641a3e 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2158,6 +2158,76 @@ static const struct ethtool_ops team_ethtool_ops = {
* rt netlink interface
***********************/
+/* For tx path we need a linkup && enabled port and for parse any port
+ * suffices.
+ */
+static struct team_port *team_header_port_get_rcu(struct team *team,
+ bool txable)
+{
+ struct team_port *port;
+
+ list_for_each_entry_rcu(port, &team->port_list, list) {
+ if (!txable || team_port_txable(port))
+ return port;
+ }
+
+ return NULL;
+}
+
+static int team_header_create(struct sk_buff *skb, struct net_device *team_dev,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned int len)
+{
+ struct team *team = netdev_priv(team_dev);
+ const struct header_ops *port_ops;
+ struct team_port *port;
+ int ret = 0;
+
+ rcu_read_lock();
+ port = team_header_port_get_rcu(team, true);
+ if (port) {
+ port_ops = READ_ONCE(port->dev->header_ops);
+ if (port_ops && port_ops->create)
+ ret = port_ops->create(skb, port->dev,
+ type, daddr, saddr, len);
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+static int team_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+ const struct net_device *dev = skb->dev;
+ const struct header_ops *port_ops;
+ struct team_port *port;
+ int ret = 0;
+
+ rcu_read_lock();
+ for (;;) {
+ if (!(dev->priv_flags & IFF_TEAM))
+ break;
+ port = team_header_port_get_rcu(netdev_priv(dev), false);
+ if (!port)
+ break;
+ port_ops = READ_ONCE(port->dev->header_ops);
+ if (!port_ops || !port_ops->parse)
+ break;
+ if (port_ops->parse == team_header_parse) {
+ dev = port->dev;
+ continue;
+ }
+ ret = port_ops->parse(skb, haddr);
+ break;
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+static const struct header_ops team_header_ops = {
+ .create = team_header_create,
+ .parse = team_header_parse,
+};
+
static void team_setup_by_port(struct net_device *dev,
struct net_device *port_dev)
{
@@ -2166,7 +2236,8 @@ static void team_setup_by_port(struct net_device *dev,
if (port_dev->type == ARPHRD_ETHER)
dev->header_ops = team->header_ops_cache;
else
- dev->header_ops = port_dev->header_ops;
+ dev->header_ops = port_dev->header_ops ?
+ &team_header_ops : NULL;
dev->type = port_dev->type;
dev->hard_header_len = port_dev->hard_header_len;
dev->needed_headroom = port_dev->needed_headroom;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0951/1887] iavf: fix out-of-bounds writes in iavf_get_ethtool_stats()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (949 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0950/1887] team: fix header_ops type confusion with non-Ethernet ports Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0952/1887] nvmet: move async event work off nvmet-wq Greg Kroah-Hartman
` (47 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kohei Enju, Simon Horman,
Przemek Kitszel, Paul Menzel, Rafal Romanowski, Tony Nguyen,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kohei Enju <kohei@enjuk.jp>
[ Upstream commit fecacfc95f195b99c71c579a472120d0b4ed65fa ]
iavf incorrectly uses real_num_tx_queues for ETH_SS_STATS. Since the
value could change in runtime, we should use num_tx_queues instead.
Moreover iavf_get_ethtool_stats() uses num_active_queues while
iavf_get_sset_count() and iavf_get_stat_strings() use
real_num_tx_queues, which triggers out-of-bounds writes when we do
"ethtool -L" and "ethtool -S" simultaneously [1].
For example when we change channels from 1 to 8, Thread 3 could be
scheduled before Thread 2, and out-of-bounds writes could be triggered
in Thread 3:
Thread 1 (ethtool -L) Thread 2 (work) Thread 3 (ethtool -S)
iavf_set_channels()
...
iavf_alloc_queues()
-> num_active_queues = 8
iavf_schedule_finish_config()
iavf_get_sset_count()
real_num_tx_queues: 1
-> buffer for 1 queue
iavf_get_ethtool_stats()
num_active_queues: 8
-> out-of-bounds!
iavf_finish_config()
-> real_num_tx_queues = 8
Use immutable num_tx_queues in all related functions to avoid the issue.
[1]
BUG: KASAN: vmalloc-out-of-bounds in iavf_add_one_ethtool_stat+0x200/0x270
Write of size 8 at addr ffffc900031c9080 by task ethtool/5800
CPU: 1 UID: 0 PID: 5800 Comm: ethtool Not tainted 6.19.0-enjuk-08403-g8137e3db7f1c #241 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xb0
print_report+0x170/0x4f3
kasan_report+0xe1/0x180
iavf_add_one_ethtool_stat+0x200/0x270
iavf_get_ethtool_stats+0x14c/0x2e0
__dev_ethtool+0x3d0c/0x5830
dev_ethtool+0x12d/0x270
dev_ioctl+0x53c/0xe30
sock_do_ioctl+0x1a9/0x270
sock_ioctl+0x3d4/0x5e0
__x64_sys_ioctl+0x137/0x1c0
do_syscall_64+0xf3/0x690
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f7da0e6e36d
...
</TASK>
The buggy address belongs to a 1-page vmalloc region starting at 0xffffc900031c9000 allocated at __dev_ethtool+0x3cc9/0x5830
The buggy address belongs to the physical page: page: refcount:1 mapcount:0 mapping:0000000000000000
index:0xffff88813a013de0 pfn:0x13a013
flags: 0x200000000000000(node=0|zone=2)
raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000
raw: ffff88813a013de0 0000000000000000 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffffc900031c8f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
ffffc900031c9000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffffc900031c9080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
^
ffffc900031c9100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
ffffc900031c9180: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
Fixes: 64430f70ba6f ("iavf: Fix displaying queue statistics shown by ethtool")
Signed-off-by: Kohei Enju <kohei@enjuk.jp>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/intel/iavf/iavf_ethtool.c | 31 +++++++++----------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index f4ac2b164b3e9..630d93e0512d8 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -333,14 +333,13 @@ static int iavf_get_sset_count(struct net_device *netdev, int sset)
{
/* Report the maximum number queues, even if not every queue is
* currently configured. Since allocation of queues is in pairs,
- * use netdev->real_num_tx_queues * 2. The real_num_tx_queues is set
- * at device creation and never changes.
+ * use netdev->num_tx_queues * 2. The num_tx_queues is set at
+ * device creation and never changes.
*/
if (sset == ETH_SS_STATS)
return IAVF_STATS_LEN +
- (IAVF_QUEUE_STATS_LEN * 2 *
- netdev->real_num_tx_queues);
+ (IAVF_QUEUE_STATS_LEN * 2 * netdev->num_tx_queues);
else if (sset == ETH_SS_PRIV_FLAGS)
return IAVF_PRIV_FLAGS_STR_LEN;
else
@@ -367,19 +366,19 @@ static void iavf_get_ethtool_stats(struct net_device *netdev,
iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats);
rcu_read_lock();
- /* As num_active_queues describe both tx and rx queues, we can use
- * it to iterate over rings' stats.
+ /* Use num_tx_queues to report stats for the maximum number of queues.
+ * Queues beyond num_active_queues will report zero.
*/
- for (i = 0; i < adapter->num_active_queues; i++) {
- struct iavf_ring *ring;
+ for (i = 0; i < netdev->num_tx_queues; i++) {
+ struct iavf_ring *tx_ring = NULL, *rx_ring = NULL;
- /* Tx rings stats */
- ring = &adapter->tx_rings[i];
- iavf_add_queue_stats(&data, ring);
+ if (i < adapter->num_active_queues) {
+ tx_ring = &adapter->tx_rings[i];
+ rx_ring = &adapter->rx_rings[i];
+ }
- /* Rx rings stats */
- ring = &adapter->rx_rings[i];
- iavf_add_queue_stats(&data, ring);
+ iavf_add_queue_stats(&data, tx_ring);
+ iavf_add_queue_stats(&data, rx_ring);
}
rcu_read_unlock();
}
@@ -416,9 +415,9 @@ static void iavf_get_stat_strings(struct net_device *netdev, u8 *data)
iavf_add_stat_strings(&data, iavf_gstrings_stats);
/* Queues are always allocated in pairs, so we just use
- * real_num_tx_queues for both Tx and Rx queues.
+ * num_tx_queues for both Tx and Rx queues.
*/
- for (i = 0; i < netdev->real_num_tx_queues; i++) {
+ for (i = 0; i < netdev->num_tx_queues; i++) {
iavf_add_stat_strings(&data, iavf_gstrings_queue_stats,
"tx", i);
iavf_add_stat_strings(&data, iavf_gstrings_queue_stats,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0952/1887] nvmet: move async event work off nvmet-wq
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (950 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0951/1887] iavf: fix out-of-bounds writes in iavf_get_ethtool_stats() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0953/1887] spi: spi-dw-dma: fix print error log when wait finish transaction Greg Kroah-Hartman
` (46 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig,
Chaitanya Kulkarni, Keith Busch, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaitanya Kulkarni <kch@nvidia.com>
[ Upstream commit 2922e3507f6d5caa7f1d07f145e186fc6f317a4e ]
For target nvmet_ctrl_free() flushes ctrl->async_event_work.
If nvmet_ctrl_free() runs on nvmet-wq, the flush re-enters workqueue
completion for the same worker:-
A. Async event work queued on nvmet-wq (prior to disconnect):
nvmet_execute_async_event()
queue_work(nvmet_wq, &ctrl->async_event_work)
nvmet_add_async_event()
queue_work(nvmet_wq, &ctrl->async_event_work)
B. Full pre-work chain (RDMA CM path):
nvmet_rdma_cm_handler()
nvmet_rdma_queue_disconnect()
__nvmet_rdma_queue_disconnect()
queue_work(nvmet_wq, &queue->release_work)
process_one_work()
lock((wq_completion)nvmet-wq) <--------- 1st
nvmet_rdma_release_queue_work()
C. Recursive path (same worker):
nvmet_rdma_release_queue_work()
nvmet_rdma_free_queue()
nvmet_sq_destroy()
nvmet_ctrl_put()
nvmet_ctrl_free()
flush_work(&ctrl->async_event_work)
__flush_work()
touch_wq_lockdep_map()
lock((wq_completion)nvmet-wq) <--------- 2nd
Lockdep splat:
============================================
WARNING: possible recursive locking detected
6.19.0-rc3nvme+ #14 Tainted: G N
--------------------------------------------
kworker/u192:42/44933 is trying to acquire lock:
ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x26/0x90
but task is already holding lock:
ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660
3 locks held by kworker/u192:42/44933:
#0: ffff888118a00948 ((wq_completion)nvmet-wq){+.+.}-{0:0}, at: process_one_work+0x53e/0x660
#1: ffffc9000e6cbe28 ((work_completion)(&queue->release_work)){+.+.}-{0:0}, at: process_one_work+0x1c5/0x660
#2: ffffffff82d4db60 (rcu_read_lock){....}-{1:3}, at: __flush_work+0x62/0x530
Workqueue: nvmet-wq nvmet_rdma_release_queue_work [nvmet_rdma]
Call Trace:
__flush_work+0x268/0x530
nvmet_ctrl_free+0x140/0x310 [nvmet]
nvmet_cq_put+0x74/0x90 [nvmet]
nvmet_rdma_free_queue+0x23/0xe0 [nvmet_rdma]
nvmet_rdma_release_queue_work+0x19/0x50 [nvmet_rdma]
process_one_work+0x206/0x660
worker_thread+0x184/0x320
kthread+0x10c/0x240
ret_from_fork+0x319/0x390
Move async event work to a dedicated nvmet-aen-wq to avoid reentrant
flush on nvmet-wq.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/admin-cmd.c | 2 +-
drivers/nvme/target/core.c | 14 ++++++++++++--
drivers/nvme/target/nvmet.h | 1 +
drivers/nvme/target/rdma.c | 1 +
4 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 74445bead85fc..5e88f2f5ae8ba 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -988,7 +988,7 @@ void nvmet_execute_async_event(struct nvmet_req *req)
ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req;
mutex_unlock(&ctrl->lock);
- queue_work(nvmet_wq, &ctrl->async_event_work);
+ queue_work(nvmet_aen_wq, &ctrl->async_event_work);
}
void nvmet_execute_keep_alive(struct nvmet_req *req)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index e1bfab6c21e0f..f9939a6076c26 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -23,6 +23,8 @@ static DEFINE_IDA(cntlid_ida);
struct workqueue_struct *nvmet_wq;
EXPORT_SYMBOL_GPL(nvmet_wq);
+struct workqueue_struct *nvmet_aen_wq;
+EXPORT_SYMBOL_GPL(nvmet_aen_wq);
/*
* This read/write semaphore is used to synchronize access to configuration
@@ -209,7 +211,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
list_add_tail(&aen->entry, &ctrl->async_events);
mutex_unlock(&ctrl->lock);
- queue_work(nvmet_wq, &ctrl->async_event_work);
+ queue_work(nvmet_aen_wq, &ctrl->async_event_work);
}
static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
@@ -1670,9 +1672,14 @@ static int __init nvmet_init(void)
if (!nvmet_wq)
goto out_free_buffered_work_queue;
+ nvmet_aen_wq = alloc_workqueue("nvmet-aen-wq",
+ WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
+ if (!nvmet_aen_wq)
+ goto out_free_nvmet_work_queue;
+
error = nvmet_init_discovery();
if (error)
- goto out_free_nvmet_work_queue;
+ goto out_free_nvmet_aen_work_queue;
error = nvmet_init_configfs();
if (error)
@@ -1681,6 +1688,8 @@ static int __init nvmet_init(void)
out_exit_discovery:
nvmet_exit_discovery();
+out_free_nvmet_aen_work_queue:
+ destroy_workqueue(nvmet_aen_wq);
out_free_nvmet_work_queue:
destroy_workqueue(nvmet_wq);
out_free_buffered_work_queue:
@@ -1697,6 +1706,7 @@ static void __exit nvmet_exit(void)
nvmet_exit_configfs();
nvmet_exit_discovery();
ida_destroy(&cntlid_ida);
+ destroy_workqueue(nvmet_aen_wq);
destroy_workqueue(nvmet_wq);
destroy_workqueue(buffered_io_wq);
destroy_workqueue(zbd_wq);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 90c63971402a4..5194e1bb0cca7 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -397,6 +397,7 @@ extern struct kmem_cache *nvmet_bvec_cache;
extern struct workqueue_struct *buffered_io_wq;
extern struct workqueue_struct *zbd_wq;
extern struct workqueue_struct *nvmet_wq;
+extern struct workqueue_struct *nvmet_aen_wq;
static inline void nvmet_set_result(struct nvmet_req *req, u32 result)
{
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 0dfe264968ff1..380c0aea840df 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -2098,6 +2098,7 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data
mutex_unlock(&nvmet_rdma_queue_mutex);
flush_workqueue(nvmet_wq);
+ flush_workqueue(nvmet_aen_wq);
}
static struct ib_client nvmet_rdma_ib_client = {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0953/1887] spi: spi-dw-dma: fix print error log when wait finish transaction
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (951 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0952/1887] nvmet: move async event work off nvmet-wq Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0954/1887] s390/mm: Add missing secure storage access fixups for donated memory Greg Kroah-Hartman
` (45 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladimir Yakovlev, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Yakovlev <vovchkir@gmail.com>
[ Upstream commit 3b46d61890632c8f8b117147b6923bff4b42ccb7 ]
If an error occurs, the device may not have a current message. In this
case, the system will crash.
In this case, it's better to use dev from the struct ctlr (struct spi_controller*).
Signed-off-by: Vladimir Yakovlev <vovchkir@gmail.com>
Link: https://patch.msgid.link/20260302222017.992228-2-vovchkir@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-dw-dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
index a795df52c5fe7..6ace5ff7675b1 100644
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -231,7 +231,7 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
msecs_to_jiffies(ms));
if (ms == 0) {
- dev_err(&dws->master->cur_msg->spi->dev,
+ dev_err(&dws->master->dev,
"DMA transaction timed out\n");
return -ETIMEDOUT;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0954/1887] s390/mm: Add missing secure storage access fixups for donated memory
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (952 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0953/1887] spi: spi-dw-dma: fix print error log when wait finish transaction Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0955/1887] KVM: SEV: Use long-term pin when registering encrypted memory regions Greg Kroah-Hartman
` (44 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Claudio Imbrenda,
Christian Borntraeger, Janosch Frank, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Janosch Frank <frankja@linux.ibm.com>
[ Upstream commit b00be77302d7ec4ad0367bb236494fce7172b730 ]
There are special cases where secure storage access exceptions happen
in a kernel context for pages that don't have the PG_arch_1 bit
set. That bit is set for non-exported guest secure storage (memory)
but is absent on storage donated to the Ultravisor since the kernel
isn't allowed to export donated pages.
Prior to this patch we would try to export the page by calling
arch_make_folio_accessible() which would instantly return since the
arch bit is absent signifying that the page was already exported and
no further action is necessary. This leads to secure storage access
exception loops which can never be resolved.
With this patch we unconditionally try to export and if that fails we
fixup.
Fixes: 084ea4d611a3 ("s390/mm: add (non)secure page access exceptions handlers")
Reported-by: Heiko Carstens <hca@linux.ibm.com>
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/mm/fault.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index be6122b0e6d15..dc0aa423e142e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -855,10 +855,17 @@ void do_secure_storage_access(struct pt_regs *regs)
page = phys_to_page(addr);
if (unlikely(!try_get_page(page)))
break;
- rc = arch_make_page_accessible(page);
+ rc = uv_convert_from_secure(page_to_phys(page));
+ if (!rc)
+ clear_bit(PG_arch_1, &page->flags);
put_page(page);
+ /*
+ * There are some valid fixup types for kernel
+ * accesses to donated secure memory. zeropad is one
+ * of them.
+ */
if (rc)
- BUG();
+ return do_no_context(regs, 0);
break;
default:
do_fault_error(regs, VM_FAULT_BADMAP);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0955/1887] KVM: SEV: Use long-term pin when registering encrypted memory regions
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (953 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0954/1887] s390/mm: Add missing secure storage access fixups for donated memory Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0956/1887] KVM: SEV: Protect *all* of sev_mem_enc_register_region() with kvm->lock Greg Kroah-Hartman
` (43 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ge Yang, Tom Lendacky,
David Hildenbrand, Sean Christopherson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ge Yang <yangge1116@126.com>
[ Upstream commit 7e066cb9b71a22c3e5ef233de63ff14525baf6f0 ]
When registering an encrypted memory region for SEV-MEM/SEV-ES guests,
pin the pages with FOLL_TERM so that the pages are migrated out of
MIGRATE_CMA/ZONE_MOVABLE. Failure to do so violates the CMA/MOVABLE
mechanisms and can result in fragmentation due to unmovable pages, e.g.
can make CMA allocations fail.
Signed-off-by: Ge Yang <yangge1116@126.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: David Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/r/1739241423-14326-1-git-send-email-yangge1116@126.com
[sean: massage changelog, make @flags an unsigned int]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Stable-dep-of: b6408b6cec5d ("KVM: SEV: Protect *all* of sev_mem_enc_register_region() with kvm->lock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/sev.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 53b37f3d770bc..302ebbb4878f5 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -393,7 +393,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
unsigned long ulen, unsigned long *n,
- int write)
+ unsigned int flags)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
unsigned long npages, size;
@@ -437,7 +437,7 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
return ERR_PTR(-ENOMEM);
/* Pin the user virtual address. */
- npinned = pin_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages);
+ npinned = pin_user_pages_fast(uaddr, npages, flags, pages);
if (npinned != npages) {
pr_err("SEV: Failure locking %lu pages.\n", npages);
ret = -ENOMEM;
@@ -525,7 +525,7 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
vaddr_end = vaddr + size;
/* Lock the user memory. */
- inpages = sev_pin_memory(kvm, vaddr, size, &npages, 1);
+ inpages = sev_pin_memory(kvm, vaddr, size, &npages, FOLL_WRITE);
if (IS_ERR(inpages))
return PTR_ERR(inpages);
@@ -958,7 +958,7 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
if (IS_ERR(src_p))
return PTR_ERR(src_p);
- dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, 1);
+ dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, FOLL_WRITE);
if (IS_ERR(dst_p)) {
sev_unpin_memory(kvm, src_p, n);
return PTR_ERR(dst_p);
@@ -1025,7 +1025,7 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params)))
return -EFAULT;
- pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, 1);
+ pages = sev_pin_memory(kvm, params.guest_uaddr, params.guest_len, &n, FOLL_WRITE);
if (IS_ERR(pages))
return PTR_ERR(pages);
@@ -1507,7 +1507,7 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
/* Pin guest memory */
guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
- PAGE_SIZE, &n, 1);
+ PAGE_SIZE, &n, FOLL_WRITE);
if (IS_ERR(guest_page)) {
ret = PTR_ERR(guest_page);
goto e_free_trans;
@@ -1971,7 +1971,8 @@ int sev_mem_enc_register_region(struct kvm *kvm,
return -ENOMEM;
mutex_lock(&kvm->lock);
- region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages, 1);
+ region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages,
+ FOLL_WRITE | FOLL_LONGTERM);
if (IS_ERR(region->pages)) {
ret = PTR_ERR(region->pages);
mutex_unlock(&kvm->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0956/1887] KVM: SEV: Protect *all* of sev_mem_enc_register_region() with kvm->lock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (954 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0955/1887] KVM: SEV: Use long-term pin when registering encrypted memory regions Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0957/1887] usb: gadget: f_hid: dont call cdev_init while cdev in use Greg Kroah-Hartman
` (42 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Potapenko,
Sean Christopherson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit b6408b6cec5df76a165575777800ef2aba12b109 ]
Take and hold kvm->lock for before checking sev_guest() in
sev_mem_enc_register_region(), as sev_guest() isn't stable unless kvm->lock
is held (or KVM can guarantee KVM_SEV_INIT{2} has completed and can't
rollack state). If KVM_SEV_INIT{2} fails, KVM can end up trying to add to
a not-yet-initialized sev->regions_list, e.g. triggering a #GP
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 110 UID: 0 PID: 72717 Comm: syz.15.11462 Tainted: G U W O 6.16.0-smp-DEV #1 NONE
Tainted: [U]=USER, [W]=WARN, [O]=OOT_MODULE
Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 12.52.0-0 10/28/2024
RIP: 0010:sev_mem_enc_register_region+0x3f0/0x4f0 ../include/linux/list.h:83
Code: <41> 80 3c 04 00 74 08 4c 89 ff e8 f1 c7 a2 00 49 39 ed 0f 84 c6 00
RSP: 0018:ffff88838647fbb8 EFLAGS: 00010256
RAX: dffffc0000000000 RBX: 1ffff92015cf1e0b RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000001000 RDI: ffff888367870000
RBP: ffffc900ae78f050 R08: ffffea000d9e0007 R09: 1ffffd4001b3c000
R10: dffffc0000000000 R11: fffff94001b3c001 R12: 0000000000000000
R13: ffff8982ab0bde00 R14: ffffc900ae78f058 R15: 0000000000000000
FS: 00007f34e9dc66c0(0000) GS:ffff89ee64d33000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fe180adef98 CR3: 000000047210e000 CR4: 0000000000350ef0
Call Trace:
<TASK>
kvm_arch_vm_ioctl+0xa72/0x1240 ../arch/x86/kvm/x86.c:7371
kvm_vm_ioctl+0x649/0x990 ../virt/kvm/kvm_main.c:5363
__se_sys_ioctl+0x101/0x170 ../fs/ioctl.c:51
do_syscall_x64 ../arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x6f/0x1f0 ../arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f34e9f7e9a9
Code: <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f34e9dc6038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f34ea1a6080 RCX: 00007f34e9f7e9a9
RDX: 0000200000000280 RSI: 000000008010aebb RDI: 0000000000000007
RBP: 00007f34ea000d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 00007f34ea1a6080 R15: 00007ffce77197a8
</TASK>
with a syzlang reproducer that looks like:
syz_kvm_add_vcpu$x86(0x0, &(0x7f0000000040)={0x0, &(0x7f0000000180)=ANY=[], 0x70}) (async)
syz_kvm_add_vcpu$x86(0x0, &(0x7f0000000080)={0x0, &(0x7f0000000180)=ANY=[@ANYBLOB="..."], 0x4f}) (async)
r0 = openat$kvm(0xffffffffffffff9c, &(0x7f0000000200), 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, 0xae01, 0x0)
r2 = openat$kvm(0xffffffffffffff9c, &(0x7f0000000240), 0x0, 0x0)
r3 = ioctl$KVM_CREATE_VM(r2, 0xae01, 0x0)
ioctl$KVM_SET_CLOCK(r3, 0xc008aeba, &(0x7f0000000040)={0x1, 0x8, 0x0, 0x5625e9b0}) (async)
ioctl$KVM_SET_PIT2(r3, 0x8010aebb, &(0x7f0000000280)={[...], 0x5}) (async)
ioctl$KVM_SET_PIT2(r1, 0x4070aea0, 0x0) (async)
r4 = ioctl$KVM_CREATE_VM(0xffffffffffffffff, 0xae01, 0x0)
openat$kvm(0xffffffffffffff9c, 0x0, 0x0, 0x0) (async)
ioctl$KVM_SET_USER_MEMORY_REGION(r4, 0x4020ae46, &(0x7f0000000400)={0x0, 0x0, 0x0, 0x2000, &(0x7f0000001000/0x2000)=nil}) (async)
r5 = ioctl$KVM_CREATE_VCPU(r4, 0xae41, 0x2)
close(r0) (async)
openat$kvm(0xffffffffffffff9c, &(0x7f0000000000), 0x8000, 0x0) (async)
ioctl$KVM_SET_GUEST_DEBUG(r5, 0x4048ae9b, &(0x7f0000000300)={0x4376ea830d46549b, 0x0, [0x46, 0x0, 0x0, 0x0, 0x0, 0x1000]}) (async)
ioctl$KVM_RUN(r5, 0xae80, 0x0)
Opportunistically use guard() to avoid having to define a new error label
and goto usage.
Fixes: 1e80fdc09d12 ("KVM: SVM: Pin guest memory when SEV is active")
Cc: stable@vger.kernel.org
Reported-by: Alexander Potapenko <glider@google.com>
Tested-by: Alexander Potapenko <glider@google.com>
Link: https://patch.msgid.link/20260310234829.2608037-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/sev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 302ebbb4878f5..ad23c5f47efb5 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -1956,6 +1956,8 @@ int sev_mem_enc_register_region(struct kvm *kvm,
struct enc_region *region;
int ret = 0;
+ guard(mutex)(&kvm->lock);
+
if (!sev_guest(kvm))
return -ENOTTY;
@@ -1970,12 +1972,10 @@ int sev_mem_enc_register_region(struct kvm *kvm,
if (!region)
return -ENOMEM;
- mutex_lock(&kvm->lock);
region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages,
FOLL_WRITE | FOLL_LONGTERM);
if (IS_ERR(region->pages)) {
ret = PTR_ERR(region->pages);
- mutex_unlock(&kvm->lock);
goto e_free;
}
@@ -1993,8 +1993,6 @@ int sev_mem_enc_register_region(struct kvm *kvm,
region->size = range->size;
list_add_tail(®ion->list, &sev->regions_list);
- mutex_unlock(&kvm->lock);
-
return ret;
e_free:
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0957/1887] usb: gadget: f_hid: dont call cdev_init while cdev in use
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (955 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0956/1887] KVM: SEV: Protect *all* of sev_mem_enc_register_region() with kvm->lock Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0958/1887] pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled Greg Kroah-Hartman
` (41 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Michael Zimmermann,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Zimmermann <sigmaepsilon92@gmail.com>
[ Upstream commit 81ebd43cc0d6d106ce7b6ccbf7b5e40ca7f5503d ]
When calling unbind, then bind again, cdev_init reinitialized the cdev,
even though there may still be references to it. That's the case when
the /dev/hidg* device is still opened. This obviously unsafe behavior
like oopes.
This fixes this by using cdev_alloc to put the cdev on the heap. That
way, we can simply allocate a new one in hidg_bind.
Closes: https://lore.kernel.org/linux-usb/CAN9vWDKZn0Ts5JyV2_xcAmbnBEi0znMLg_USMFrShRryXrgWGQ@mail.gmail.com/T/#m2cb0dba3633b67b2a679c98499508267d1508881
Cc: stable <stable@kernel.org>
Signed-off-by: Michael Zimmermann <sigmaepsilon92@gmail.com>
Link: https://patch.msgid.link/20260327192209.59945-1-sigmaepsilon92@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_hid.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index a3e79121d9eb0..6d12e30f820d0 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -72,7 +72,7 @@ struct f_hidg {
struct usb_request *req;
struct device dev;
- struct cdev cdev;
+ struct cdev *cdev;
struct usb_function func;
struct usb_ep *in_ep;
@@ -554,8 +554,9 @@ static int f_hidg_release(struct inode *inode, struct file *fd)
static int f_hidg_open(struct inode *inode, struct file *fd)
{
+ struct kobject *parent = inode->i_cdev->kobj.parent;
struct f_hidg *hidg =
- container_of(inode->i_cdev, struct f_hidg, cdev);
+ container_of(parent, struct f_hidg, dev.kobj);
fd->private_data = hidg;
@@ -1000,8 +1001,14 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
hidg->req = NULL;
/* create char device */
- cdev_init(&hidg->cdev, &f_hidg_fops);
- status = cdev_device_add(&hidg->cdev, &hidg->dev);
+ hidg->cdev = cdev_alloc();
+ if (!hidg->cdev) {
+ status = -ENOMEM;
+ goto fail_free_descs;
+ }
+ hidg->cdev->ops = &f_hidg_fops;
+
+ status = cdev_device_add(hidg->cdev, &hidg->dev);
if (status)
goto fail_free_descs;
@@ -1246,7 +1253,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_hidg *hidg = func_to_hidg(f);
- cdev_device_del(&hidg->cdev, &hidg->dev);
+ cdev_device_del(hidg->cdev, &hidg->dev);
usb_free_all_descriptors(f);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0958/1887] pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (956 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0957/1887] usb: gadget: f_hid: dont call cdev_init while cdev in use Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0959/1887] xfrm: hold dev ref until after transport_finish NF_HOOK Greg Kroah-Hartman
` (40 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jacky Bai, Ulf Hansson, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacky Bai <ping.bai@nxp.com>
[ Upstream commit e91d5f94acf68618ea3ad9c92ac28614e791ae7d ]
Keep the NOC_HDCP clock always enabled to fix the potential hang
caused by the NoC ADB400 port power down handshake.
Fixes: 77b0ddb42add ("soc: imx: add i.MX8MP HDMI blk ctrl HDCP/HRV_MWR")
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/imx/imx8mp-blk-ctrl.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c
index 65848f6b8f352..5357711b2584c 100644
--- a/drivers/soc/imx/imx8mp-blk-ctrl.c
+++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
@@ -250,9 +250,6 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12));
regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3));
break;
- case IMX8MP_HDMIBLK_PD_HDCP:
- regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
- break;
case IMX8MP_HDMIBLK_PD_HRV:
regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
@@ -306,9 +303,6 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc,
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7));
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24));
break;
- case IMX8MP_HDMIBLK_PD_HDCP:
- regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
- break;
case IMX8MP_HDMIBLK_PD_HRV:
regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
@@ -337,7 +331,7 @@ static int imx8mp_hdmi_power_notifier(struct notifier_block *nb,
regmap_write(bc->regmap, HDMI_RTX_CLK_CTL0, 0x0);
regmap_write(bc->regmap, HDMI_RTX_CLK_CTL1, 0x0);
regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0,
- BIT(0) | BIT(1) | BIT(10));
+ BIT(0) | BIT(1) | BIT(10) | BIT(11));
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(0));
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0959/1887] xfrm: hold dev ref until after transport_finish NF_HOOK
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (957 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0958/1887] pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0960/1887] net/sched: sch_netem: fix out-of-bounds access in packet corruption Greg Kroah-Hartman
` (39 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Florian Westphal, Qi Tang,
Steffen Klassert, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Tang <tpluszz77@gmail.com>
[ Upstream commit 1c428b03840094410c5fb6a5db30640486bbbfcb ]
After async crypto completes, xfrm_input_resume() calls dev_put()
immediately on re-entry before the skb reaches transport_finish.
The skb->dev pointer is then used inside NF_HOOK and its okfn,
which can race with device teardown.
Remove the dev_put from the async resumption entry and instead
drop the reference after the NF_HOOK call in transport_finish,
using a saved device pointer since NF_HOOK may consume the skb.
This covers NF_DROP, NF_QUEUE and NF_STOLEN paths that skip
the okfn.
For non-transport exits (decaps, gro, drop) and secondary
async return points, release the reference inline when
async is set.
Suggested-by: Florian Westphal <fw@strlen.de>
Fixes: acf568ee859f ("xfrm: Reinject transport-mode packets through tasklet")
Cc: stable@vger.kernel.org
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/xfrm4_input.c | 5 ++++-
net/ipv6/xfrm6_input.c | 5 ++++-
net/xfrm/xfrm_input.c | 15 ++++++++++++---
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index f6e90ba50b639..d05e8ff9c37bf 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -48,6 +48,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
{
struct xfrm_offload *xo = xfrm_offload(skb);
struct iphdr *iph = ip_hdr(skb);
+ struct net_device *dev = skb->dev;
iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
@@ -71,8 +72,10 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
}
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
- dev_net(skb->dev), NULL, skb, skb->dev, NULL,
+ dev_net(dev), NULL, skb, dev, NULL,
xfrm4_rcv_encap_finish);
+ if (async)
+ dev_put(dev);
return 0;
}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 00d2a1b8b679e..cd96299dfe2f7 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -41,6 +41,7 @@ static int xfrm6_transport_finish2(struct net *net, struct sock *sk,
int xfrm6_transport_finish(struct sk_buff *skb, int async)
{
struct xfrm_offload *xo = xfrm_offload(skb);
+ struct net_device *dev = skb->dev;
int nhlen = skb->data - skb_network_header(skb);
skb_network_header(skb)[IP6CB(skb)->nhoff] =
@@ -66,8 +67,10 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
}
NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
- dev_net(skb->dev), NULL, skb, skb->dev, NULL,
+ dev_net(dev), NULL, skb, dev, NULL,
xfrm6_transport_finish2);
+ if (async)
+ dev_put(dev);
return 0;
}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index de2e8b16b217a..b39bb4662d4b2 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -634,11 +634,14 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
else
nexthdr = x->type->input(x, skb);
- if (nexthdr == -EINPROGRESS)
+ if (nexthdr == -EINPROGRESS) {
+ if (async)
+ dev_put(skb->dev);
return 0;
-resume:
- dev_put(skb->dev);
+ }
+ dev_put(skb->dev);
+resume:
spin_lock(&x->lock);
if (nexthdr < 0) {
if (nexthdr == -EBADMSG) {
@@ -704,6 +707,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
sp->olen = 0;
if (skb_valid_dst(skb))
skb_dst_drop(skb);
+ if (async)
+ dev_put(skb->dev);
gro_cells_receive(&gro_cells, skb);
return 0;
} else {
@@ -723,6 +728,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
sp->olen = 0;
if (skb_valid_dst(skb))
skb_dst_drop(skb);
+ if (async)
+ dev_put(skb->dev);
gro_cells_receive(&gro_cells, skb);
return err;
}
@@ -733,6 +740,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
drop_unlock:
spin_unlock(&x->lock);
drop:
+ if (async)
+ dev_put(skb->dev);
xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
kfree_skb(skb);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0960/1887] net/sched: sch_netem: fix out-of-bounds access in packet corruption
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (958 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0959/1887] xfrm: hold dev ref until after transport_finish NF_HOOK Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0961/1887] crypto: af_alg - limit RX SG extraction by receive buffer budget Greg Kroah-Hartman
` (38 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yifan Wu, Juefei Pu, Yuan Tan,
Xin Liu, Yuhang Zheng, Yucheng Lu, Stephen Hemminger,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yucheng Lu <kanolyc@gmail.com>
[ Upstream commit d64cb81dcbd54927515a7f65e5e24affdc73c14b ]
In netem_enqueue(), the packet corruption logic uses
get_random_u32_below(skb_headlen(skb)) to select an index for
modifying skb->data. When an AF_PACKET TX_RING sends fully non-linear
packets over an IPIP tunnel, skb_headlen(skb) evaluates to 0.
Passing 0 to get_random_u32_below() takes the variable-ceil slow path
which returns an unconstrained 32-bit random integer. Using this
unconstrained value as an offset into skb->data results in an
out-of-bounds memory access.
Fix this by verifying skb_headlen(skb) is non-zero before attempting
to corrupt the linear data area. Fully non-linear packets will silently
bypass the corruption logic.
Fixes: c865e5d99e25 ("[PKT_SCHED] netem: packet corruption option")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Signed-off-by: Yuan Tan <tanyuan98@outlook.com>
Signed-off-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Yuhang Zheng <z1652074432@gmail.com>
Signed-off-by: Yucheng Lu <kanolyc@gmail.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
Link: https://patch.msgid.link/45435c0935df877853a81e6d06205ac738ec65fa.1774941614.git.kanolyc@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_netem.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 2c47bd8dba647..5d6e928ab7506 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -508,8 +508,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
goto finish_segs;
}
- skb->data[prandom_u32_max(skb_headlen(skb))] ^=
- 1<<prandom_u32_max(8);
+ if (skb_headlen(skb))
+ skb->data[prandom_u32_max(skb_headlen(skb))] ^=
+ 1 << prandom_u32_max(8);
}
if (unlikely(sch->q.qlen >= sch->limit)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0961/1887] crypto: af_alg - limit RX SG extraction by receive buffer budget
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (959 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0960/1887] net/sched: sch_netem: fix out-of-bounds access in packet corruption Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0962/1887] ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl() Greg Kroah-Hartman
` (37 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yifan Wu, Juefei Pu, Yuan Tan,
Xin Liu, Douya Le, Ren Wei, Herbert Xu, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douya Le <ldy3087146292@gmail.com>
[ Upstream commit 8eceab19eba9dcbfd2a0daec72e1bf48aa100170 ]
Make af_alg_get_rsgl() limit each RX scatterlist extraction to the
remaining receive buffer budget.
af_alg_get_rsgl() currently uses af_alg_readable() only as a gate
before extracting data into the RX scatterlist. Limit each extraction
to the remaining af_alg_rcvbuf(sk) budget so that receive-side
accounting matches the amount of data attached to the request.
If skcipher cannot obtain enough RX space for at least one chunk while
more data remains to be processed, reject the recvmsg call instead of
rounding the request length down to zero.
Fixes: e870456d8e7c8d57c059ea479b5aadbb55ff4c3a ("crypto: algif_skcipher - overhaul memory management")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
crypto/af_alg.c | 2 ++
crypto/algif_skcipher.c | 8 +++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 80a8d3a4a3cf7..3cfdd7f1479e9 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -1126,6 +1126,8 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
seglen = min_t(size_t, (maxsize - len),
msg_data_left(msg));
+ /* Never pin more pages than the remaining RX accounting budget. */
+ seglen = min_t(size_t, seglen, af_alg_rcvbuf(sk));
if (list_empty(&areq->rsgl_list)) {
rsgl = &areq->first_rsgl;
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 6a1a71284fe82..0fe62be7470f2 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -82,8 +82,14 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
* If more buffers are to be expected to be processed, process only
* full block size buffers.
*/
- if (ctx->more || len < ctx->used)
+ if (ctx->more || len < ctx->used) {
+ if (len < bs) {
+ err = -EINVAL;
+ goto free;
+ }
+
len -= len % bs;
+ }
/*
* Create a per request TX SGL for this request which tracks the
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0962/1887] ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (960 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0961/1887] crypto: af_alg - limit RX SG extraction by receive buffer budget Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:50 ` [PATCH 6.1 0963/1887] ksmbd: validate response sizes in ipc_validate_msg() Greg Kroah-Hartman
` (36 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit 3e4e2ea2a781018ed5d75f969e3e5606beb66e48 ]
smb_inherit_dacl() trusts the on-disk num_aces value from the parent
directory's DACL xattr and uses it to size a heap allocation:
aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, ...);
num_aces is a u16 read from le16_to_cpu(parent_pdacl->num_aces)
without checking that it is consistent with the declared pdacl_size.
An authenticated client whose parent directory's security.NTACL is
tampered (e.g. via offline xattr corruption or a concurrent path that
bypasses parse_dacl()) can present num_aces = 65535 with minimal
actual ACE data. This causes a ~8 MB allocation (not kzalloc, so
uninitialized) that the subsequent loop only partially populates, and
may also overflow the three-way size_t multiply on 32-bit kernels.
Additionally, the ACE walk loop uses the weaker
offsetof(struct smb_ace, access_req) minimum size check rather than
the minimum valid on-wire ACE size, and does not reject ACEs whose
declared size is below the minimum.
Reproduced on UML + KASAN + LOCKDEP against the real ksmbd code path.
A legitimate mount.cifs client creates a parent directory over SMB
(ksmbd writes a valid security.NTACL xattr), then the NTACL blob on
the backing filesystem is rewritten to set num_aces = 0xFFFF while
keeping the posix_acl_hash bytes intact so ksmbd_vfs_get_sd_xattr()'s
hash check still passes. A subsequent SMB2 CREATE of a child under
that parent drives smb2_open() into smb_inherit_dacl() (share has
"vfs objects = acl_xattr" set), which fails the page allocator:
WARNING: mm/page_alloc.c:5226 at __alloc_frozen_pages_noprof+0x46c/0x9c0
Workqueue: ksmbd-io handle_ksmbd_work
__alloc_frozen_pages_noprof+0x46c/0x9c0
___kmalloc_large_node+0x68/0x130
__kmalloc_large_node_noprof+0x24/0x70
__kmalloc_noprof+0x4c9/0x690
smb_inherit_dacl+0x394/0x2430
smb2_open+0x595d/0xabe0
handle_ksmbd_work+0x3d3/0x1140
With the patch applied the added guard rejects the tampered value
with -EINVAL before any large allocation runs, smb2_open() falls back
to smb2_create_sd_buffer(), and the child is created with a default
SD. No warning, no splat.
Fix by:
1. Validating num_aces against pdacl_size using the same formula
applied in parse_dacl().
2. Replacing the raw kmalloc(sizeof * num_aces * 2) with
kmalloc_array(num_aces * 2, sizeof(...)) for overflow-safe
allocation.
3. Tightening the per-ACE loop guard to require the minimum valid
ACE size (offsetof(smb_ace, sid) + CIFS_SID_BASE_SIZE) and
rejecting under-sized ACEs, matching the hardening in
smb_check_perm_dacl() and parse_dacl().
v1 -> v2:
- Replace the synthetic test-module splat in the changelog with a
real-path UML + KASAN reproduction driven through mount.cifs and
SMB2 CREATE; Namjae flagged the kcifs3_test_inherit_dacl_old name
in v1 since it does not exist in ksmbd.
- Drop the commit-hash citation from the code comment per Namjae's
review; keep the parse_dacl() pointer.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index d09cd2ddd1adb..fb48a504435d6 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1150,7 +1150,24 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
goto free_parent_pntsd;
}
- aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
+ aces_size = pdacl_size - sizeof(struct smb_acl);
+
+ /*
+ * Validate num_aces against the DACL payload before allocating.
+ * Each ACE must be at least as large as its fixed-size header
+ * (up to the SID base), so num_aces cannot exceed the payload
+ * divided by the minimum ACE size. This mirrors the existing
+ * check in parse_dacl().
+ */
+ if (num_aces > aces_size / (offsetof(struct smb_ace, sid) +
+ offsetof(struct smb_sid, sub_auth) +
+ sizeof(__le16))) {
+ rc = -EINVAL;
+ goto free_parent_pntsd;
+ }
+
+ aces_base = kmalloc_array(num_aces * 2, sizeof(struct smb_ace),
+ GFP_KERNEL);
if (!aces_base) {
rc = -ENOMEM;
goto free_parent_pntsd;
@@ -1159,7 +1176,6 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
aces = (struct smb_ace *)aces_base;
parent_aces = (struct smb_ace *)((char *)parent_pdacl +
sizeof(struct smb_acl));
- aces_size = acl_len - sizeof(struct smb_acl);
if (pntsd_type & DACL_AUTO_INHERITED)
inherited_flags = INHERITED_ACE;
@@ -1167,11 +1183,14 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
for (i = 0; i < num_aces; i++) {
int pace_size;
- if (offsetof(struct smb_ace, access_req) > aces_size)
+ if (aces_size < offsetof(struct smb_ace, sid) +
+ CIFS_SID_BASE_SIZE)
break;
pace_size = le16_to_cpu(parent_aces->size);
- if (pace_size > aces_size)
+ if (pace_size > aces_size ||
+ pace_size < offsetof(struct smb_ace, sid) +
+ CIFS_SID_BASE_SIZE)
break;
aces_size -= pace_size;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0963/1887] ksmbd: validate response sizes in ipc_validate_msg()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (961 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0962/1887] ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl() Greg Kroah-Hartman
@ 2026-10-28 16:50 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0964/1887] usb: gadget: f_rndis: Fix net_device lifecycle with device_move Greg Kroah-Hartman
` (35 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Namjae Jeon,
Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit d6a6aa81eac2c9bff66dc6e191179cb69a14426b ]
ipc_validate_msg() computes the expected message size for each
response type by adding (or multiplying) attacker-controlled fields
from the daemon response to a fixed struct size in unsigned int
arithmetic. Three cases can overflow:
KSMBD_EVENT_RPC_REQUEST:
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
KSMBD_EVENT_SHARE_CONFIG_REQUEST:
msg_sz = sizeof(struct ksmbd_share_config_response) +
resp->payload_sz;
KSMBD_EVENT_LOGIN_REQUEST_EXT:
msg_sz = sizeof(struct ksmbd_login_response_ext) +
resp->ngroups * sizeof(gid_t);
resp->payload_sz is __u32 and resp->ngroups is __s32. Each addition
can wrap in unsigned int; the multiplication by sizeof(gid_t) mixes
signed and size_t, so a negative ngroups is converted to SIZE_MAX
before the multiply. A wrapped value of msg_sz that happens to
equal entry->msg_sz bypasses the size check on the next line, and
downstream consumers (smb2pdu.c:6742 memcpy using rpc_resp->payload_sz,
kmemdup in ksmbd_alloc_user using resp_ext->ngroups) then trust the
unverified length.
Use check_add_overflow() on the RPC_REQUEST and SHARE_CONFIG_REQUEST
paths to detect integer overflow without constraining functional
payload size; userspace ksmbd-tools grows NDR responses in 4096-byte
chunks for calls like NetShareEnumAll, so a hard transport cap is
unworkable on the response side. For LOGIN_REQUEST_EXT, reject
resp->ngroups outside the signed [0, NGROUPS_MAX] range up front and
report the error from ipc_validate_msg() so it fires at the IPC
boundary; with that bound the subsequent multiplication and addition
stay well below UINT_MAX. The now-redundant ngroups check and
pr_err in ksmbd_alloc_user() are removed.
This is the response-side analogue of aab98e2dbd64 ("ksmbd: fix
integer overflows on 32 bit systems"), which hardened the request
side.
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Fixes: a77e0e02af1c ("ksmbd: add support for supplementary groups")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_ipc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c
index 89fae5e1886ae..63d0e8bf39aa5 100644
--- a/fs/smb/server/transport_ipc.c
+++ b/fs/smb/server/transport_ipc.c
@@ -13,6 +13,7 @@
#include <net/genetlink.h>
#include <linux/socket.h>
#include <linux/workqueue.h>
+#include <linux/overflow.h>
#include "vfs_cache.h"
#include "transport_ipc.h"
@@ -478,7 +479,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
struct ksmbd_rpc_command *resp = entry->response;
- msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
+ if (check_add_overflow(sizeof(struct ksmbd_rpc_command),
+ resp->payload_sz, &msg_sz))
+ return -EINVAL;
} else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
struct ksmbd_spnego_authen_response *resp = entry->response;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0964/1887] usb: gadget: f_rndis: Fix net_device lifecycle with device_move
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (962 preceding siblings ...)
2026-10-28 16:50 ` [PATCH 6.1 0963/1887] ksmbd: validate response sizes in ipc_validate_msg() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0965/1887] usb: gadget: f_subset: " Greg Kroah-Hartman
` (34 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kuen-Han Tsai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <khtsai@google.com>
[ Upstream commit e367599529dc42578545a7f85fde517b35b3cda7 ]
The net_device is allocated during function instance creation and
registered during the bind phase with the gadget device as its sysfs
parent. When the function unbinds, the parent device is destroyed, but
the net_device survives, resulting in dangling sysfs symlinks:
console:/ # ls -l /sys/class/net/usb0
lrwxrwxrwx ... /sys/class/net/usb0 ->
/sys/devices/platform/.../gadget.0/net/usb0
console:/ # ls -l /sys/devices/platform/.../gadget.0/net/usb0
ls: .../gadget.0/net/usb0: No such file or directory
Use device_move() to reparent the net_device between the gadget device
tree and /sys/devices/virtual across bind and unbind cycles. During the
final unbind, calling device_move(NULL) moves the net_device to the
virtual device tree before the gadget device is destroyed. On rebinding,
device_move() reparents the device back under the new gadget, ensuring
proper sysfs topology and power management ordering.
To maintain compatibility with legacy composite drivers (e.g., multi.c),
the borrowed_net flag is used to indicate whether the network device is
shared and pre-registered during the legacy driver's bind phase.
Fixes: f466c6353819 ("usb: gadget: f_rndis: convert to new function interface with backward compatibility")
Cc: stable@vger.kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://patch.msgid.link/20260320-usb-net-lifecycle-v1-7-4886b578161b@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_rndis.c | 42 ++++++++++++++++-----------
drivers/usb/gadget/function/u_rndis.h | 31 +++++++++++++++-----
2 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index 57c2246d0a4aa..8cdb2f4088950 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -679,6 +679,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
struct f_rndis_opts *rndis_opts;
struct usb_os_desc_table *os_desc_table __free(kfree) = NULL;
+ struct net_device *net __free(detach_gadget) = NULL;
struct usb_request *request __free(free_usb_request) = NULL;
if (!can_support_rndis(c))
@@ -696,21 +697,18 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
rndis_iad_descriptor.bFunctionClass = rndis_opts->class;
rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass;
rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol;
- }
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to rndis_opts->bound access
- */
- if (!rndis_opts->bound) {
- gether_set_gadget(rndis_opts->net, cdev->gadget);
- status = gether_register_netdev(rndis_opts->net);
- if (status)
- return status;
- rndis_opts->bound = true;
+ if (rndis_opts->bind_count == 0 && !rndis_opts->borrowed_net) {
+ if (!device_is_registered(&rndis_opts->net->dev)) {
+ gether_set_gadget(rndis_opts->net, cdev->gadget);
+ status = gether_register_netdev(rndis_opts->net);
+ } else
+ status = gether_attach_gadget(rndis_opts->net, cdev->gadget);
+
+ if (status)
+ return status;
+ net = rndis_opts->net;
+ }
}
us = usb_gstrings_attach(cdev, rndis_strings,
@@ -809,6 +807,9 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
}
rndis->notify_req = no_free_ptr(request);
+ rndis_opts->bind_count++;
+ no_free_ptr(net);
+
/* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
* until we're activated via set_alt().
@@ -827,11 +828,11 @@ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net)
struct f_rndis_opts *opts;
opts = container_of(f, struct f_rndis_opts, func_inst);
- if (opts->bound)
+ if (device_is_registered(&opts->net->dev))
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
- opts->borrowed_net = opts->bound = true;
+ opts->borrowed_net = true;
opts->net = net;
}
EXPORT_SYMBOL_GPL(rndis_borrow_net);
@@ -889,7 +890,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
opts = container_of(f, struct f_rndis_opts, func_inst);
if (!opts->borrowed_net) {
- if (opts->bound)
+ if (device_is_registered(&opts->net->dev))
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
@@ -958,6 +959,9 @@ static void rndis_free(struct usb_function *f)
static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_rndis *rndis = func_to_rndis(f);
+ struct f_rndis_opts *rndis_opts;
+
+ rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst);
kfree(f->os_desc_table);
f->os_desc_n = 0;
@@ -965,6 +969,10 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(rndis->notify_req->buf);
usb_ep_free_request(rndis->notify, rndis->notify_req);
+
+ rndis_opts->bind_count--;
+ if (rndis_opts->bind_count == 0 && !rndis_opts->borrowed_net)
+ gether_detach_gadget(rndis_opts->net);
}
static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h
index a8c409b2f52f9..4e64619714dc2 100644
--- a/drivers/usb/gadget/function/u_rndis.h
+++ b/drivers/usb/gadget/function/u_rndis.h
@@ -15,12 +15,34 @@
#include <linux/usb/composite.h>
+/**
+ * struct f_rndis_opts - RNDIS function options
+ * @func_inst: USB function instance.
+ * @vendor_id: Vendor ID.
+ * @manufacturer: Manufacturer string.
+ * @net: The net_device associated with the RNDIS function.
+ * @bind_count: Tracks the number of configurations the RNDIS function is
+ * bound to, preventing double-registration of the @net device.
+ * @borrowed_net: True if the net_device is shared and pre-registered during
+ * the legacy composite driver's bind phase (e.g., multi.c).
+ * If false, the RNDIS function will register the net_device
+ * during its own bind phase.
+ * @rndis_interf_group: ConfigFS group for RNDIS interface.
+ * @rndis_os_desc: USB OS descriptor for RNDIS.
+ * @rndis_ext_compat_id: Extended compatibility ID.
+ * @class: USB class.
+ * @subclass: USB subclass.
+ * @protocol: USB protocol.
+ * @lock: Protects the data from concurrent access by configfs read/write
+ * and create symlink/remove symlink operations.
+ * @refcnt: Reference counter for the function instance.
+ */
struct f_rndis_opts {
struct usb_function_instance func_inst;
u32 vendor_id;
const char *manufacturer;
struct net_device *net;
- bool bound;
+ int bind_count;
bool borrowed_net;
struct config_group *rndis_interf_group;
@@ -30,13 +52,6 @@ struct f_rndis_opts {
u8 class;
u8 subclass;
u8 protocol;
-
- /*
- * Read/write access to configfs attributes is handled by configfs.
- *
- * This is to protect the data from concurrent access by read/write
- * and create symlink/remove symlink.
- */
struct mutex lock;
int refcnt;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0965/1887] usb: gadget: f_subset: Fix net_device lifecycle with device_move
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (963 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0964/1887] usb: gadget: f_rndis: Fix net_device lifecycle with device_move Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0966/1887] usb: gadget: f_eem: " Greg Kroah-Hartman
` (33 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kuen-Han Tsai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <khtsai@google.com>
[ Upstream commit 06524cd1c9011bee141a87e43ab878641ed3652b ]
The net_device is allocated during function instance creation and
registered during the bind phase with the gadget device as its sysfs
parent. When the function unbinds, the parent device is destroyed, but
the net_device survives, resulting in dangling sysfs symlinks:
console:/ # ls -l /sys/class/net/usb0
lrwxrwxrwx ... /sys/class/net/usb0 ->
/sys/devices/platform/.../gadget.0/net/usb0
console:/ # ls -l /sys/devices/platform/.../gadget.0/net/usb0
ls: .../gadget.0/net/usb0: No such file or directory
Use device_move() to reparent the net_device between the gadget device
tree and /sys/devices/virtual across bind and unbind cycles. During the
final unbind, calling device_move(NULL) moves the net_device to the
virtual device tree before the gadget device is destroyed. On rebinding,
device_move() reparents the device back under the new gadget, ensuring
proper sysfs topology and power management ordering.
To maintain compatibility with legacy composite drivers (e.g., multi.c),
the bound flag is used to indicate whether the network device is shared
and pre-registered during the legacy driver's bind phase.
Fixes: 8cedba7c73af ("usb: gadget: f_subset: convert to new function interface with backward compatibility")
Cc: stable@vger.kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://patch.msgid.link/20260320-usb-net-lifecycle-v1-6-4886b578161b@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_subset.c | 57 +++++++++++++-------------
drivers/usb/gadget/function/u_gether.h | 22 ++++++----
2 files changed, 44 insertions(+), 35 deletions(-)
diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c
index 447e94c83c7b8..bd8e0996d6a8c 100644
--- a/drivers/usb/gadget/function/f_subset.c
+++ b/drivers/usb/gadget/function/f_subset.c
@@ -299,25 +299,22 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_ep *ep;
struct f_gether_opts *gether_opts;
+ struct net_device *net __free(detach_gadget) = NULL;
gether_opts = container_of(f->fi, struct f_gether_opts, func_inst);
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to gether_opts->bound access
- */
- if (!gether_opts->bound) {
- mutex_lock(&gether_opts->lock);
- gether_set_gadget(gether_opts->net, cdev->gadget);
- status = gether_register_netdev(gether_opts->net);
- mutex_unlock(&gether_opts->lock);
- if (status)
- return status;
- gether_opts->bound = true;
- }
+ scoped_guard(mutex, &gether_opts->lock)
+ if (gether_opts->bind_count == 0 && !gether_opts->bound) {
+ if (!device_is_registered(&gether_opts->net->dev)) {
+ gether_set_gadget(gether_opts->net, cdev->gadget);
+ status = gether_register_netdev(gether_opts->net);
+ } else
+ status = gether_attach_gadget(gether_opts->net, cdev->gadget);
+
+ if (status)
+ return status;
+ net = gether_opts->net;
+ }
us = usb_gstrings_attach(cdev, geth_strings,
ARRAY_SIZE(geth_string_defs));
@@ -330,20 +327,18 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
/* allocate instance-specific interface IDs */
status = usb_interface_id(c, f);
if (status < 0)
- goto fail;
+ return status;
subset_data_intf.bInterfaceNumber = status;
- status = -ENODEV;
-
/* allocate instance-specific endpoints */
ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc);
if (!ep)
- goto fail;
+ return -ENODEV;
geth->port.in_ep = ep;
ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
if (!ep)
- goto fail;
+ return -ENODEV;
geth->port.out_ep = ep;
/* support all relevant hardware speeds... we expect that when
@@ -361,23 +356,21 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function,
ss_eth_function, ss_eth_function);
if (status)
- goto fail;
+ return status;
/* NOTE: all that is done without knowing or caring about
* the network link ... which is unavailable to this code
* until we're activated via set_alt().
*/
+ gether_opts->bind_count++;
+ no_free_ptr(net);
+
DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
geth->port.in_ep->name, geth->port.out_ep->name);
return 0;
-
-fail:
- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
-
- return status;
}
static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item)
@@ -420,7 +413,7 @@ static void geth_free_inst(struct usb_function_instance *f)
struct f_gether_opts *opts;
opts = container_of(f, struct f_gether_opts, func_inst);
- if (opts->bound)
+ if (device_is_registered(&opts->net->dev))
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
@@ -464,8 +457,16 @@ static void geth_free(struct usb_function *f)
static void geth_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ struct f_gether_opts *opts;
+
+ opts = container_of(f->fi, struct f_gether_opts, func_inst);
+
geth_string_defs[0].id = 0;
usb_free_all_descriptors(f);
+
+ opts->bind_count--;
+ if (opts->bind_count == 0 && !opts->bound)
+ gether_detach_gadget(opts->net);
}
static struct usb_function *geth_alloc(struct usb_function_instance *fi)
diff --git a/drivers/usb/gadget/function/u_gether.h b/drivers/usb/gadget/function/u_gether.h
index 2f7a373ed4496..e7b6b51f69c12 100644
--- a/drivers/usb/gadget/function/u_gether.h
+++ b/drivers/usb/gadget/function/u_gether.h
@@ -15,17 +15,25 @@
#include <linux/usb/composite.h>
+/**
+ * struct f_gether_opts - subset function options
+ * @func_inst: USB function instance.
+ * @net: The net_device associated with the subset function.
+ * @bound: True if the net_device is shared and pre-registered during the
+ * legacy composite driver's bind phase (e.g., multi.c). If false,
+ * the subset function will register the net_device during its own
+ * bind phase.
+ * @bind_count: Tracks the number of configurations the subset function is
+ * bound to, preventing double-registration of the @net device.
+ * @lock: Protects the data from concurrent access by configfs read/write
+ * and create symlink/remove symlink operations.
+ * @refcnt: Reference counter for the function instance.
+ */
struct f_gether_opts {
struct usb_function_instance func_inst;
struct net_device *net;
bool bound;
-
- /*
- * Read/write access to configfs attributes is handled by configfs.
- *
- * This is to protect the data from concurrent access by read/write
- * and create symlink/remove symlink.
- */
+ int bind_count;
struct mutex lock;
int refcnt;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0966/1887] usb: gadget: f_eem: Fix net_device lifecycle with device_move
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (964 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0965/1887] usb: gadget: f_subset: " Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0967/1887] usb: gadget: f_ecm: " Greg Kroah-Hartman
` (32 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kuen-Han Tsai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <khtsai@google.com>
[ Upstream commit d9270c9a8118c1535409db926ac1e2545dc97b81 ]
The net_device is allocated during function instance creation and
registered during the bind phase with the gadget device as its sysfs
parent. When the function unbinds, the parent device is destroyed, but
the net_device survives, resulting in dangling sysfs symlinks:
console:/ # ls -l /sys/class/net/usb0
lrwxrwxrwx ... /sys/class/net/usb0 ->
/sys/devices/platform/.../gadget.0/net/usb0
console:/ # ls -l /sys/devices/platform/.../gadget.0/net/usb0
ls: .../gadget.0/net/usb0: No such file or directory
Use device_move() to reparent the net_device between the gadget device
tree and /sys/devices/virtual across bind and unbind cycles. During the
final unbind, calling device_move(NULL) moves the net_device to the
virtual device tree before the gadget device is destroyed. On rebinding,
device_move() reparents the device back under the new gadget, ensuring
proper sysfs topology and power management ordering.
To maintain compatibility with legacy composite drivers (e.g., multi.c),
the bound flag is used to indicate whether the network device is shared
and pre-registered during the legacy driver's bind phase.
Fixes: b29002a15794 ("usb: gadget: f_eem: convert to new function interface with backward compatibility")
Cc: stable@vger.kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://patch.msgid.link/20260320-usb-net-lifecycle-v1-5-4886b578161b@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_eem.c | 59 +++++++++++++++--------------
drivers/usb/gadget/function/u_eem.h | 21 +++++++---
2 files changed, 46 insertions(+), 34 deletions(-)
diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c
index a308163fc8bcc..803fe047c512c 100644
--- a/drivers/usb/gadget/function/f_eem.c
+++ b/drivers/usb/gadget/function/f_eem.c
@@ -7,6 +7,7 @@
* Copyright (C) 2009 EF Johnson Technologies
*/
+#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
@@ -251,24 +252,22 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_ep *ep;
struct f_eem_opts *eem_opts;
+ struct net_device *net __free(detach_gadget) = NULL;
eem_opts = container_of(f->fi, struct f_eem_opts, func_inst);
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to eem_opts->bound access
- */
- if (!eem_opts->bound) {
- mutex_lock(&eem_opts->lock);
- gether_set_gadget(eem_opts->net, cdev->gadget);
- status = gether_register_netdev(eem_opts->net);
- mutex_unlock(&eem_opts->lock);
- if (status)
- return status;
- eem_opts->bound = true;
- }
+
+ scoped_guard(mutex, &eem_opts->lock)
+ if (eem_opts->bind_count == 0 && !eem_opts->bound) {
+ if (!device_is_registered(&eem_opts->net->dev)) {
+ gether_set_gadget(eem_opts->net, cdev->gadget);
+ status = gether_register_netdev(eem_opts->net);
+ } else
+ status = gether_attach_gadget(eem_opts->net, cdev->gadget);
+
+ if (status)
+ return status;
+ net = eem_opts->net;
+ }
us = usb_gstrings_attach(cdev, eem_strings,
ARRAY_SIZE(eem_string_defs));
@@ -279,21 +278,19 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
/* allocate instance-specific interface IDs */
status = usb_interface_id(c, f);
if (status < 0)
- goto fail;
+ return status;
eem->ctrl_id = status;
eem_intf.bInterfaceNumber = status;
- status = -ENODEV;
-
/* allocate instance-specific endpoints */
ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_in_desc);
if (!ep)
- goto fail;
+ return -ENODEV;
eem->port.in_ep = ep;
ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
if (!ep)
- goto fail;
+ return -ENODEV;
eem->port.out_ep = ep;
/* support all relevant hardware speeds... we expect that when
@@ -309,18 +306,16 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function,
eem_ss_function, eem_ss_function);
if (status)
- goto fail;
+ return status;
+
+ eem_opts->bind_count++;
+ no_free_ptr(net);
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
eem->port.in_ep->name, eem->port.out_ep->name);
return 0;
-
-fail:
- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
-
- return status;
}
static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
@@ -599,7 +594,7 @@ static void eem_free_inst(struct usb_function_instance *f)
struct f_eem_opts *opts;
opts = container_of(f, struct f_eem_opts, func_inst);
- if (opts->bound)
+ if (device_is_registered(&opts->net->dev))
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
@@ -642,9 +637,17 @@ static void eem_free(struct usb_function *f)
static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
{
+ struct f_eem_opts *opts;
+
DBG(c->cdev, "eem unbind\n");
+ opts = container_of(f->fi, struct f_eem_opts, func_inst);
+
usb_free_all_descriptors(f);
+
+ opts->bind_count--;
+ if (opts->bind_count == 0 && !opts->bound)
+ gether_detach_gadget(opts->net);
}
static struct usb_function *eem_alloc(struct usb_function_instance *fi)
diff --git a/drivers/usb/gadget/function/u_eem.h b/drivers/usb/gadget/function/u_eem.h
index 3bd85dfcd71c8..78ef558152197 100644
--- a/drivers/usb/gadget/function/u_eem.h
+++ b/drivers/usb/gadget/function/u_eem.h
@@ -15,17 +15,26 @@
#include <linux/usb/composite.h>
+/**
+ * struct f_eem_opts - EEM function options
+ * @func_inst: USB function instance.
+ * @net: The net_device associated with the EEM function.
+ * @bound: True if the net_device is shared and pre-registered during the
+ * legacy composite driver's bind phase (e.g., multi.c). If false,
+ * the EEM function will register the net_device during its own
+ * bind phase.
+ * @bind_count: Tracks the number of configurations the EEM function is
+ * bound to, preventing double-registration of the @net device.
+ * @lock: Protects the data from concurrent access by configfs read/write
+ * and create symlink/remove symlink operations.
+ * @refcnt: Reference counter for the function instance.
+ */
struct f_eem_opts {
struct usb_function_instance func_inst;
struct net_device *net;
bool bound;
+ int bind_count;
- /*
- * Read/write access to configfs attributes is handled by configfs.
- *
- * This is to protect the data from concurrent access by read/write
- * and create symlink/remove symlink.
- */
struct mutex lock;
int refcnt;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0967/1887] usb: gadget: f_ecm: Fix net_device lifecycle with device_move
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (965 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0966/1887] usb: gadget: f_eem: " Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0968/1887] drm/i915/dsi: Dont do DSC horizontal timing adjustments in command mode Greg Kroah-Hartman
` (31 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kuen-Han Tsai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <khtsai@google.com>
[ Upstream commit b2cc4fae67a51f60d81d6af2678696accb07c656 ]
The net_device is allocated during function instance creation and
registered during the bind phase with the gadget device as its sysfs
parent. When the function unbinds, the parent device is destroyed, but
the net_device survives, resulting in dangling sysfs symlinks:
console:/ # ls -l /sys/class/net/usb0
lrwxrwxrwx ... /sys/class/net/usb0 ->
/sys/devices/platform/.../gadget.0/net/usb0
console:/ # ls -l /sys/devices/platform/.../gadget.0/net/usb0
ls: .../gadget.0/net/usb0: No such file or directory
Use device_move() to reparent the net_device between the gadget device
tree and /sys/devices/virtual across bind and unbind cycles. During the
final unbind, calling device_move(NULL) moves the net_device to the
virtual device tree before the gadget device is destroyed. On rebinding,
device_move() reparents the device back under the new gadget, ensuring
proper sysfs topology and power management ordering.
To maintain compatibility with legacy composite drivers (e.g., multi.c),
the bound flag is used to indicate whether the network device is shared
and pre-registered during the legacy driver's bind phase.
Fixes: fee562a6450b ("usb: gadget: f_ecm: convert to new function interface with backward compatibility")
Cc: stable@vger.kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://patch.msgid.link/20260320-usb-net-lifecycle-v1-4-4886b578161b@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_ecm.c | 41 +++++++++++++++++------------
drivers/usb/gadget/function/u_ecm.h | 21 ++++++++++-----
2 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c
index 35ec50685b499..4ea8787734f97 100644
--- a/drivers/usb/gadget/function/f_ecm.c
+++ b/drivers/usb/gadget/function/f_ecm.c
@@ -692,6 +692,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_ep *ep;
struct f_ecm_opts *ecm_opts;
+ struct net_device *net __free(detach_gadget) = NULL;
struct usb_request *request __free(free_usb_request) = NULL;
if (!can_support_ecm(cdev->gadget))
@@ -699,22 +700,18 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst);
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to ecm_opts->bound access
- */
- if (!ecm_opts->bound) {
- mutex_lock(&ecm_opts->lock);
- gether_set_gadget(ecm_opts->net, cdev->gadget);
- status = gether_register_netdev(ecm_opts->net);
- mutex_unlock(&ecm_opts->lock);
- if (status)
- return status;
- ecm_opts->bound = true;
- }
+ scoped_guard(mutex, &ecm_opts->lock)
+ if (ecm_opts->bind_count == 0 && !ecm_opts->bound) {
+ if (!device_is_registered(&ecm_opts->net->dev)) {
+ gether_set_gadget(ecm_opts->net, cdev->gadget);
+ status = gether_register_netdev(ecm_opts->net);
+ } else
+ status = gether_attach_gadget(ecm_opts->net, cdev->gadget);
+
+ if (status)
+ return status;
+ net = ecm_opts->net;
+ }
ecm_string_defs[1].s = ecm->ethaddr;
@@ -805,6 +802,9 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm->notify_req = no_free_ptr(request);
+ ecm_opts->bind_count++;
+ no_free_ptr(net);
+
DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
@@ -853,7 +853,7 @@ static void ecm_free_inst(struct usb_function_instance *f)
struct f_ecm_opts *opts;
opts = container_of(f, struct f_ecm_opts, func_inst);
- if (opts->bound)
+ if (device_is_registered(&opts->net->dev))
gether_cleanup(netdev_priv(opts->net));
else
free_netdev(opts->net);
@@ -897,9 +897,12 @@ static void ecm_free(struct usb_function *f)
static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_ecm *ecm = func_to_ecm(f);
+ struct f_ecm_opts *ecm_opts;
DBG(c->cdev, "ecm unbind\n");
+ ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst);
+
usb_free_all_descriptors(f);
if (atomic_read(&ecm->notify_count)) {
@@ -909,6 +912,10 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
+
+ ecm_opts->bind_count--;
+ if (ecm_opts->bind_count == 0 && !ecm_opts->bound)
+ gether_detach_gadget(ecm_opts->net);
}
static struct usb_function *ecm_alloc(struct usb_function_instance *fi)
diff --git a/drivers/usb/gadget/function/u_ecm.h b/drivers/usb/gadget/function/u_ecm.h
index 77cfb89932bea..7f666b9dea026 100644
--- a/drivers/usb/gadget/function/u_ecm.h
+++ b/drivers/usb/gadget/function/u_ecm.h
@@ -15,17 +15,26 @@
#include <linux/usb/composite.h>
+/**
+ * struct f_ecm_opts - ECM function options
+ * @func_inst: USB function instance.
+ * @net: The net_device associated with the ECM function.
+ * @bound: True if the net_device is shared and pre-registered during the
+ * legacy composite driver's bind phase (e.g., multi.c). If false,
+ * the ECM function will register the net_device during its own
+ * bind phase.
+ * @bind_count: Tracks the number of configurations the ECM function is
+ * bound to, preventing double-registration of the @net device.
+ * @lock: Protects the data from concurrent access by configfs read/write
+ * and create symlink/remove symlink operations.
+ * @refcnt: Reference counter for the function instance.
+ */
struct f_ecm_opts {
struct usb_function_instance func_inst;
struct net_device *net;
bool bound;
+ int bind_count;
- /*
- * Read/write access to configfs attributes is handled by configfs.
- *
- * This is to protect the data from concurrent access by read/write
- * and create symlink/remove symlink.
- */
struct mutex lock;
int refcnt;
};
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0968/1887] drm/i915/dsi: Dont do DSC horizontal timing adjustments in command mode
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (966 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0967/1887] usb: gadget: f_ecm: " Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0969/1887] Bluetooth: hci_event: move wake reason storage into validated event handlers Greg Kroah-Hartman
` (30 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ville Syrjälä, Jani Nikula,
Joonas Lahtinen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
[ Upstream commit 4dfce79e098915d8e5fc2b9e1d980bc3251dd32c ]
Stop adjusting the horizontal timing values based on the
compression ratio in command mode. Bspec seems to be telling
us to do this only in video mode, and this is also how the
Windows driver does things.
This should also fix a div-by-zero on some machines because
the adjusted htotal ends up being so small that we end up with
line_time_us==0 when trying to determine the vtotal value in
command mode.
Note that this doesn't actually make the display on the
Huawei Matebook E work, but at least the kernel no longer
explodes when the driver loads.
Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12045
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260326111814.9800-2-ville.syrjala@linux.intel.com
Fixes: 53693f02d80e ("drm/i915/dsi: account for DSC in horizontal timings")
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit 0b475e91ecc2313207196c6d7fd5c53e1a878525)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index f7422f0cf579d..1134d01629219 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -913,7 +913,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
* non-compressed link speeds, and simplifies down to the ratio between
* compressed and non-compressed bpp.
*/
- if (crtc_state->dsc.compression_enable) {
+ if (is_vid_mode(intel_dsi) && crtc_state->dsc.compression_enable) {
mul = crtc_state->dsc.compressed_bpp;
div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
}
@@ -1518,7 +1518,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
- if (pipe_config->dsc.compressed_bpp) {
+ if (is_vid_mode(intel_dsi) && pipe_config->dsc.compressed_bpp) {
int div = pipe_config->dsc.compressed_bpp;
int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0969/1887] Bluetooth: hci_event: move wake reason storage into validated event handlers
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (967 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0968/1887] drm/i915/dsi: Dont do DSC horizontal timing adjustments in command mode Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0970/1887] bpf: Fix incorrect pruning due to atomic fetch precision tracking Greg Kroah-Hartman
` (29 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleh Konko, Luiz Augusto von Dentz,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleh Konko <security@1seal.org>
[ Upstream commit 2b2bf47cd75518c36fa2d41380e4a40641cc89cd ]
hci_store_wake_reason() is called from hci_event_packet() immediately
after stripping the HCI event header but before hci_event_func()
enforces the per-event minimum payload length from hci_ev_table.
This means a short HCI event frame can reach bacpy() before any bounds
check runs.
Rather than duplicating skb parsing and per-event length checks inside
hci_store_wake_reason(), move wake-address storage into the individual
event handlers after their existing event-length validation has
succeeded. Convert hci_store_wake_reason() into a small helper that only
stores an already-validated bdaddr while the caller holds hci_dev_lock().
Use the same helper after hci_event_func() with a NULL address to
preserve the existing unexpected-wake fallback semantics when no
validated event handler records a wake address.
Annotate the helper with __must_hold(&hdev->lock) and add
lockdep_assert_held(&hdev->lock) so future call paths keep the lock
contract explicit.
Call the helper from hci_conn_request_evt(), hci_conn_complete_evt(),
hci_sync_conn_complete_evt(), le_conn_complete_evt(),
hci_le_adv_report_evt(), hci_le_ext_adv_report_evt(),
hci_le_direct_adv_report_evt(), hci_le_pa_sync_established_evt(), and
hci_le_past_received_evt().
Fixes: 2f20216c1d6f ("Bluetooth: Emit controller suspend and resume events")
Cc: stable@vger.kernel.org
Signed-off-by: Oleh Konko <security@1seal.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_event.c | 93 ++++++++++++++-------------------------
1 file changed, 34 insertions(+), 59 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 97899057a262c..e319d55dc0068 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -80,6 +80,10 @@ static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
return data;
}
+static void hci_store_wake_reason(struct hci_dev *hdev,
+ const bdaddr_t *bdaddr, u8 addr_type)
+ __must_hold(&hdev->lock);
+
static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
struct sk_buff *skb)
{
@@ -3078,6 +3082,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "status 0x%2.2x", status);
hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
/* Check for existing connection:
*
@@ -3262,6 +3267,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
+ hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
+ hci_dev_unlock(hdev);
+
/* Reject incoming connection from device with same BD ADDR against
* CVE-2020-26555
*/
@@ -4915,6 +4924,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "status 0x%2.2x", status);
hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
@@ -5623,6 +5633,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
u8 addr_type;
hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, bdaddr, bdaddr_type);
/* Advertising stops when a connection is created. On a failed
* connection it keeps running, so leave the state bit alone.
@@ -6251,6 +6262,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
info->length + 1))
break;
+ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
+
if (info->length <= max_adv_len(hdev)) {
rssi = info->data[info->length];
process_adv_report(hdev, info->type, &info->bdaddr,
@@ -6334,6 +6347,8 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
info->length))
break;
+ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
+
evt_type = __le16_to_cpu(info->type);
legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
if (legacy_evt_type != LE_ADV_INVALID) {
@@ -6371,6 +6386,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
return;
hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, &ev->bdaddr, ev->bdaddr_type);
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
@@ -6608,6 +6624,8 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
for (i = 0; i < ev->num; i++) {
struct hci_ev_le_direct_adv_info *info = &ev->info[i];
+ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
+
process_adv_report(hdev, info->type, &info->bdaddr,
info->bdaddr_type, &info->direct_addr,
info->direct_addr_type, info->rssi, NULL, 0,
@@ -7063,73 +7081,29 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
return true;
}
-static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
- struct sk_buff *skb)
+static void hci_store_wake_reason(struct hci_dev *hdev,
+ const bdaddr_t *bdaddr, u8 addr_type)
+ __must_hold(&hdev->lock)
{
- struct hci_ev_le_advertising_info *adv;
- struct hci_ev_le_direct_adv_info *direct_adv;
- struct hci_ev_le_ext_adv_info *ext_adv;
- const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
- const struct hci_ev_conn_request *conn_request = (void *)skb->data;
-
- hci_dev_lock(hdev);
+ lockdep_assert_held(&hdev->lock);
/* If we are currently suspended and this is the first BT event seen,
* save the wake reason associated with the event.
*/
if (!hdev->suspended || hdev->wake_reason)
- goto unlock;
+ return;
+
+ if (!bdaddr) {
+ hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
+ return;
+ }
/* Default to remote wake. Values for wake_reason are documented in the
* Bluez mgmt api docs.
*/
hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
-
- /* Once configured for remote wakeup, we should only wake up for
- * reconnections. It's useful to see which device is waking us up so
- * keep track of the bdaddr of the connection event that woke us up.
- */
- if (event == HCI_EV_CONN_REQUEST) {
- bacpy(&hdev->wake_addr, &conn_request->bdaddr);
- hdev->wake_addr_type = BDADDR_BREDR;
- } else if (event == HCI_EV_CONN_COMPLETE) {
- bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
- hdev->wake_addr_type = BDADDR_BREDR;
- } else if (event == HCI_EV_LE_META) {
- struct hci_ev_le_meta *le_ev = (void *)skb->data;
- u8 subevent = le_ev->subevent;
- u8 *ptr = &skb->data[sizeof(*le_ev)];
- u8 num_reports = *ptr;
-
- if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
- subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
- subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
- num_reports) {
- adv = (void *)(ptr + 1);
- direct_adv = (void *)(ptr + 1);
- ext_adv = (void *)(ptr + 1);
-
- switch (subevent) {
- case HCI_EV_LE_ADVERTISING_REPORT:
- bacpy(&hdev->wake_addr, &adv->bdaddr);
- hdev->wake_addr_type = adv->bdaddr_type;
- break;
- case HCI_EV_LE_DIRECT_ADV_REPORT:
- bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
- hdev->wake_addr_type = direct_adv->bdaddr_type;
- break;
- case HCI_EV_LE_EXT_ADV_REPORT:
- bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
- hdev->wake_addr_type = ext_adv->bdaddr_type;
- break;
- }
- }
- } else {
- hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
- }
-
-unlock:
- hci_dev_unlock(hdev);
+ bacpy(&hdev->wake_addr, bdaddr);
+ hdev->wake_addr_type = addr_type;
}
#define HCI_EV_VL(_op, _func, _min_len, _max_len) \
@@ -7374,14 +7348,15 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
skb_pull(skb, HCI_EVENT_HDR_SIZE);
- /* Store wake reason if we're suspended */
- hci_store_wake_reason(hdev, event, skb);
-
bt_dev_dbg(hdev, "event 0x%2.2x", event);
hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
&req_complete_skb);
+ hci_dev_lock(hdev);
+ hci_store_wake_reason(hdev, NULL, 0);
+ hci_dev_unlock(hdev);
+
if (req_complete) {
req_complete(hdev, status, opcode);
} else if (req_complete_skb) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0970/1887] bpf: Fix incorrect pruning due to atomic fetch precision tracking
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (968 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0969/1887] Bluetooth: hci_event: move wake reason storage into validated event handlers Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0971/1887] bpf: Reject sleepable kprobe_multi programs at attach time Greg Kroah-Hartman
` (28 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, STAR Labs SG, Daniel Borkmann,
Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <daniel@iogearbox.net>
[ Upstream commit 179ee84a89114b854ac2dd1d293633a7f6c8dac1 ]
When backtrack_insn encounters a BPF_STX instruction with BPF_ATOMIC
and BPF_FETCH, the src register (or r0 for BPF_CMPXCHG) also acts as
a destination, thus receiving the old value from the memory location.
The current backtracking logic does not account for this. It treats
atomic fetch operations the same as regular stores where the src
register is only an input. This leads the backtrack_insn to fail to
propagate precision to the stack location, which is then not marked
as precise!
Later, the verifier's path pruning can incorrectly consider two states
equivalent when they differ in terms of stack state. Meaning, two
branches can be treated as equivalent and thus get pruned when they
should not be seen as such.
Fix it as follows: Extend the BPF_LDX handling in backtrack_insn to
also cover atomic fetch operations via is_atomic_fetch_insn() helper.
When the fetch dst register is being tracked for precision, clear it,
and propagate precision over to the stack slot. For non-stack memory,
the precision walk stops at the atomic instruction, same as regular
BPF_LDX. This covers all fetch variants.
Before:
0: (b7) r1 = 8 ; R1=8
1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8
2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs=r2 stack= before 2: (b7) r2 = 0
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
After:
0: (b7) r1 = 8 ; R1=8
1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8
2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs= stack=-8 before 2: (b7) r2 = 0
mark_precise: frame0: regs= stack=-8 before 1: (7b) *(u64 *)(r10 -8) = r1
mark_precise: frame0: regs=r1 stack= before 0: (b7) r1 = 8
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
Fixes: 5ffa25502b5a ("bpf: Add instructions for atomic_[cmp]xchg")
Fixes: 5ca419f2864a ("bpf: Add BPF_FETCH field / create atomic_fetch_add instruction")
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260331222020.401848-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d7e9b84ff491b..2e26fdfa59e99 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -473,6 +473,13 @@ static bool is_cmpxchg_insn(const struct bpf_insn *insn)
insn->imm == BPF_CMPXCHG;
}
+static bool is_atomic_fetch_insn(const struct bpf_insn *insn)
+{
+ return BPF_CLASS(insn->code) == BPF_STX &&
+ BPF_MODE(insn->code) == BPF_ATOMIC &&
+ (insn->imm & BPF_FETCH);
+}
+
/* string representation of 'enum bpf_reg_type'
*
* Note that reg_type_str() can not appear more than once in a single verbose()
@@ -2608,10 +2615,25 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
* dreg still needs precision before this insn
*/
}
- } else if (class == BPF_LDX) {
- if (!(*reg_mask & dreg))
+ } else if (class == BPF_LDX || is_atomic_fetch_insn(insn)) {
+ u32 load_reg = dreg;
+ u8 base_reg = insn->src_reg;
+
+ /*
+ * Atomic fetch operation writes the old value into
+ * a register (sreg or r0) and if it was tracked for
+ * precision, propagate to the stack slot like we do
+ * in regular ldx.
+ */
+ if (is_atomic_fetch_insn(insn)) {
+ load_reg = insn->imm == BPF_CMPXCHG ?
+ 1u << BPF_REG_0 : sreg;
+ base_reg = insn->dst_reg;
+ }
+
+ if (!(*reg_mask & load_reg))
return 0;
- *reg_mask &= ~dreg;
+ *reg_mask &= ~load_reg;
/* scalars can only be spilled into stack w/o losing precision.
* Load from any other memory can be zero extended.
@@ -2619,7 +2641,7 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
* by 'precise' mark in corresponding register of this state.
* No further tracking necessary.
*/
- if (insn->src_reg != BPF_REG_FP)
+ if (base_reg != BPF_REG_FP)
return 0;
/* dreg = *(u64 *)[fp - off] was a fill from the stack.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0971/1887] bpf: Reject sleepable kprobe_multi programs at attach time
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (969 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0970/1887] bpf: Fix incorrect pruning due to atomic fetch precision tracking Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0972/1887] bpf: sockmap: Fix use-after-free of sk->sk_socket in sk_psock_verdict_data_ready() Greg Kroah-Hartman
` (27 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Varun R Mallya,
Kumar Kartikeya Dwivedi, Leon Hwang, Jiri Olsa,
Alexei Starovoitov, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varun R Mallya <varunrmallya@gmail.com>
[ Upstream commit eb7024bfcc5f68ed11ed9dd4891a3073c15f04a8 ]
kprobe.multi programs run in atomic/RCU context and cannot sleep.
However, bpf_kprobe_multi_link_attach() did not validate whether the
program being attached had the sleepable flag set, allowing sleepable
helpers such as bpf_copy_from_user() to be invoked from a non-sleepable
context.
This causes a "sleeping function called from invalid context" splat:
BUG: sleeping function called from invalid context at ./include/linux/uaccess.h:169
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1787, name: sudo
preempt_count: 1, expected: 0
RCU nest depth: 2, expected: 0
Fix this by rejecting sleepable programs early in
bpf_kprobe_multi_link_attach(), before any further processing.
Fixes: 0dcac2725406 ("bpf: Add multi kprobe link")
Signed-off-by: Varun R Mallya <varunrmallya@gmail.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Leon Hwang <leon.hwang@linux.dev>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20260401191126.440683-1-varunrmallya@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/bpf_trace.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 5342e0574b9d9..db5484a1dbd31 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -2730,6 +2730,10 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
if (prog->expected_attach_type != BPF_TRACE_KPROBE_MULTI)
return -EINVAL;
+ /* kprobe_multi is not allowed to be sleepable. */
+ if (prog->aux->sleepable)
+ return -EINVAL;
+
flags = attr->link_create.kprobe_multi.flags;
if (flags & ~BPF_F_KPROBE_MULTI_RETURN)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0972/1887] bpf: sockmap: Fix use-after-free of sk->sk_socket in sk_psock_verdict_data_ready().
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (970 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0971/1887] bpf: Reject sleepable kprobe_multi programs at attach time Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0973/1887] Bluetooth: hci_sync: hci_cmd_sync_queue_once() return -EEXIST if exists Greg Kroah-Hartman
` (26 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2184232f07e3677fbaef,
Kuniyuki Iwashima, Martin KaFai Lau, Jiayuan Chen, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit ad8391d37f334ee73ba91926f8b4e4cf6d31ea04 ]
syzbot reported use-after-free of AF_UNIX socket's sk->sk_socket
in sk_psock_verdict_data_ready(). [0]
In unix_stream_sendmsg(), the peer socket's ->sk_data_ready() is
called after dropping its unix_state_lock().
Although the sender socket holds the peer's refcount, it does not
prevent the peer's sock_orphan(), and the peer's sk_socket might
be freed after one RCU grace period.
Let's fetch the peer's sk->sk_socket and sk->sk_socket->ops under
RCU in sk_psock_verdict_data_ready().
[0]:
BUG: KASAN: slab-use-after-free in sk_psock_verdict_data_ready+0xec/0x590 net/core/skmsg.c:1278
Read of size 8 at addr ffff8880594da860 by task syz.4.1842/11013
CPU: 1 UID: 0 PID: 11013 Comm: syz.4.1842 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xba/0x230 mm/kasan/report.c:482
kasan_report+0x117/0x150 mm/kasan/report.c:595
sk_psock_verdict_data_ready+0xec/0x590 net/core/skmsg.c:1278
unix_stream_sendmsg+0x8a3/0xe80 net/unix/af_unix.c:2482
sock_sendmsg_nosec net/socket.c:721 [inline]
__sock_sendmsg net/socket.c:736 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2585
___sys_sendmsg+0x2a5/0x360 net/socket.c:2639
__sys_sendmsg net/socket.c:2671 [inline]
__do_sys_sendmsg net/socket.c:2676 [inline]
__se_sys_sendmsg net/socket.c:2674 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2674
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7facf899c819
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007facf9827028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007facf8c15fa0 RCX: 00007facf899c819
RDX: 0000000000000000 RSI: 0000200000000500 RDI: 0000000000000004
RBP: 00007facf8a32c91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007facf8c16038 R14: 00007facf8c15fa0 R15: 00007ffd41b01c78
</TASK>
Allocated by task 11013:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
unpoison_slab_object mm/kasan/common.c:340 [inline]
__kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:366
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4538 [inline]
slab_alloc_node mm/slub.c:4866 [inline]
kmem_cache_alloc_lru_noprof+0x2b8/0x640 mm/slub.c:4885
sock_alloc_inode+0x28/0xc0 net/socket.c:316
alloc_inode+0x6a/0x1b0 fs/inode.c:347
new_inode_pseudo include/linux/fs.h:3003 [inline]
sock_alloc net/socket.c:631 [inline]
__sock_create+0x12d/0x9d0 net/socket.c:1562
sock_create net/socket.c:1656 [inline]
__sys_socketpair+0x1c4/0x560 net/socket.c:1803
__do_sys_socketpair net/socket.c:1856 [inline]
__se_sys_socketpair net/socket.c:1853 [inline]
__x64_sys_socketpair+0x9b/0xb0 net/socket.c:1853
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 15:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x5c/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2685 [inline]
slab_free mm/slub.c:6165 [inline]
kmem_cache_free+0x187/0x630 mm/slub.c:6295
rcu_do_batch kernel/rcu/tree.c:2617 [inline]
rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
handle_softirqs+0x22a/0x870 kernel/softirq.c:622
run_ksoftirqd+0x36/0x60 kernel/softirq.c:1063
smpboot_thread_fn+0x541/0xa50 kernel/smpboot.c:160
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Fixes: c63829182c37 ("af_unix: Implement ->psock_update_sk_prot()")
Closes: https://lore.kernel.org/bpf/69cc6b9f.a70a0220.128fd0.004b.GAE@google.com/
Reported-by: syzbot+2184232f07e3677fbaef@syzkaller.appspotmail.com
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260401005418.2452999-1-kuniyu@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/skmsg.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 20e67399f0b6a..8163bcf574f01 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -1266,12 +1266,19 @@ static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb)
static void sk_psock_verdict_data_ready(struct sock *sk)
{
- struct socket *sock = sk->sk_socket;
+ const struct proto_ops *ops = NULL;
+ struct socket *sock;
int copied;
- if (unlikely(!sock || !sock->ops || !sock->ops->read_skb))
+ rcu_read_lock();
+ sock = READ_ONCE(sk->sk_socket);
+ if (likely(sock))
+ ops = READ_ONCE(sock->ops);
+ rcu_read_unlock();
+ if (!ops || !ops->read_skb)
return;
- copied = sock->ops->read_skb(sk, sk_psock_verdict_recv);
+
+ copied = ops->read_skb(sk, sk_psock_verdict_recv);
if (copied >= 0) {
struct sk_psock *psock;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0973/1887] Bluetooth: hci_sync: hci_cmd_sync_queue_once() return -EEXIST if exists
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (971 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0972/1887] bpf: sockmap: Fix use-after-free of sk->sk_socket in sk_psock_verdict_data_ready() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0974/1887] net: use skb_header_pointer() for TCPv4 GSO frag_off check Greg Kroah-Hartman
` (25 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
Luiz Augusto von Dentz, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <pav@iki.fi>
[ Upstream commit 2969554bcfccb5c609f6b6cd4a014933f3a66dd0 ]
hci_cmd_sync_queue_once() needs to indicate whether a queue item was
added, so caller can know if callbacks are called, so it can avoid
leaking resources.
Change the function to return -EEXIST if queue item already exists.
Modify all callsites to handle that.
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_sync.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 4e4eae12ee3fb..4295c803cfd4a 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -811,7 +811,7 @@ int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
void *data, hci_cmd_sync_work_destroy_t destroy)
{
if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy))
- return 0;
+ return -EEXIST;
return hci_cmd_sync_queue(hdev, func, data, destroy);
}
@@ -3326,6 +3326,8 @@ static int update_passive_scan_sync(struct hci_dev *hdev, void *data)
int hci_update_passive_scan(struct hci_dev *hdev)
{
+ int err;
+
/* Only queue if it would have any effect */
if (!test_bit(HCI_UP, &hdev->flags) ||
test_bit(HCI_INIT, &hdev->flags) ||
@@ -3335,8 +3337,9 @@ int hci_update_passive_scan(struct hci_dev *hdev)
hci_dev_test_flag(hdev, HCI_UNREGISTER))
return 0;
- return hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL,
- NULL);
+ err = hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL,
+ NULL);
+ return (err == -EEXIST) ? 0 : err;
}
int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0974/1887] net: use skb_header_pointer() for TCPv4 GSO frag_off check
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (972 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0973/1887] Bluetooth: hci_sync: hci_cmd_sync_queue_once() return -EEXIST if exists Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0975/1887] mpls: add seqcount to protect the platform_label{,s} pair Greg Kroah-Hartman
` (24 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1543a7d954d9c6d00407,
Guoyu Su, Willem de Bruijn, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoyu Su <yss2813483011xxl@gmail.com>
[ Upstream commit ddc748a391dd8642ba6b2e4fe22e7f2ddf84b7f0 ]
Syzbot reported a KMSAN uninit-value warning in gso_features_check()
called from netif_skb_features() [1].
gso_features_check() reads iph->frag_off to decide whether to clear
mangleid_features. Accessing the IPv4 header via ip_hdr()/inner_ip_hdr()
can rely on skb header offsets that are not always safe for direct
dereference on packets injected from PF_PACKET paths.
Use skb_header_pointer() for the TCPv4 frag_off check so the header read
is robust whether data is already linear or needs copying.
[1] https://syzkaller.appspot.com/bug?extid=1543a7d954d9c6d00407
Link: https://lore.kernel.org/netdev/willemdebruijn.kernel.1a9f35039caab@gmail.com/
Fixes: cbc53e08a793 ("GSO: Add GSO type for fixed IPv4 ID")
Reported-by: syzbot+1543a7d954d9c6d00407@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1543a7d954d9c6d00407
Tested-by: syzbot+1543a7d954d9c6d00407@syzkaller.appspotmail.com
Signed-off-by: Guoyu Su <yss2813483011xxl@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260327153507.39742-1-yss2813483011xxl@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index e467e81226396..c8d0f98d375e6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3633,10 +3633,15 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
* IPv4 header has the potential to be fragmented.
*/
if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
- struct iphdr *iph = skb->encapsulation ?
- inner_ip_hdr(skb) : ip_hdr(skb);
+ const struct iphdr *iph;
+ struct iphdr _iph;
+ int nhoff = skb->encapsulation ?
+ skb_inner_network_offset(skb) :
+ skb_network_offset(skb);
- if (!(iph->frag_off & htons(IP_DF)))
+ iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+
+ if (!iph || !(iph->frag_off & htons(IP_DF)))
features &= ~NETIF_F_TSO_MANGLEID;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0975/1887] mpls: add seqcount to protect the platform_label{,s} pair
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (973 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0974/1887] net: use skb_header_pointer() for TCPv4 GSO frag_off check Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0976/1887] HID: core: Add reserved item tag for main items Greg Kroah-Hartman
` (23 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuan Tan, Yifan Wu, Juefei Pu,
Xin Liu, Sabrina Dubroca, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
[ Upstream commit 629ec78ef8608d955ce217880cdc3e1873af3a15 ]
The RCU-protected codepaths (mpls_forward, mpls_dump_routes) can have
an inconsistent view of platform_labels vs platform_label in case of a
concurrent resize (resize_platform_label_table, under
platform_mutex). This can lead to OOB accesses.
This patch adds a seqcount, so that we get a consistent snapshot.
Note that mpls_label_ok is also susceptible to this, so the check
against RTA_DST in rtm_to_route_config, done outside platform_mutex,
is not sufficient. This value gets passed to mpls_label_ok once more
in both mpls_route_add and mpls_route_del, so there is no issue, but
that additional check must not be removed.
Reported-by: Yuan Tan <tanyuan98@outlook.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Fixes: 7720c01f3f590 ("mpls: Add a sysctl to control the size of the mpls label table")
Fixes: dde1b38e873c ("mpls: Convert mpls_dump_routes() to RCU.")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/cd8fca15e3eb7e212b094064cd83652e20fd9d31.1774284088.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netns/mpls.h | 1 +
net/mpls/af_mpls.c | 40 ++++++++++++++++++++++++++++++----------
2 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/include/net/netns/mpls.h b/include/net/netns/mpls.h
index 19ad2574b267c..f364286adf288 100644
--- a/include/net/netns/mpls.h
+++ b/include/net/netns/mpls.h
@@ -16,6 +16,7 @@ struct netns_mpls {
int default_ttl;
size_t platform_labels;
struct mpls_route __rcu * __rcu *platform_label;
+ seqcount_t platform_label_seq;
struct ctl_table_header *ctl;
};
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 5e0900bd48b6b..73443cf8b69ce 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -74,16 +74,31 @@ static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
struct nlmsghdr *nlh, struct net *net, u32 portid,
unsigned int nlm_flags);
-static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index)
+static struct mpls_route __rcu **mpls_platform_label_rcu(struct net *net, size_t *platform_labels)
{
- struct mpls_route *rt = NULL;
+ struct mpls_route __rcu **platform_label;
+ unsigned int sequence;
- if (index < net->mpls.platform_labels) {
- struct mpls_route __rcu **platform_label =
- rcu_dereference_rtnl(net->mpls.platform_label);
- rt = rcu_dereference_rtnl(platform_label[index]);
- }
- return rt;
+ do {
+ sequence = read_seqcount_begin(&net->mpls.platform_label_seq);
+ platform_label = rcu_dereference_rtnl(net->mpls.platform_label);
+ *platform_labels = net->mpls.platform_labels;
+ } while (read_seqcount_retry(&net->mpls.platform_label_seq, sequence));
+
+ return platform_label;
+}
+
+static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned int index)
+{
+ struct mpls_route __rcu **platform_label;
+ size_t platform_labels;
+
+ platform_label = mpls_platform_label_rcu(net, &platform_labels);
+
+ if (index >= platform_labels)
+ return NULL;
+
+ return rcu_dereference_rtnl(platform_label[index]);
}
bool mpls_output_possible(const struct net_device *dev)
@@ -2209,8 +2224,7 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
if (index < MPLS_LABEL_FIRST_UNRESERVED)
index = MPLS_LABEL_FIRST_UNRESERVED;
- platform_label = rtnl_dereference(net->mpls.platform_label);
- platform_labels = net->mpls.platform_labels;
+ platform_label = mpls_platform_label_rcu(net, &platform_labels);
if (filter.filter_set)
flags |= NLM_F_DUMP_FILTERED;
@@ -2597,8 +2611,12 @@ static int resize_platform_label_table(struct net *net, size_t limit)
}
/* Update the global pointers */
+ local_bh_disable();
+ write_seqcount_begin(&net->mpls.platform_label_seq);
net->mpls.platform_labels = limit;
rcu_assign_pointer(net->mpls.platform_label, labels);
+ write_seqcount_end(&net->mpls.platform_label_seq);
+ local_bh_enable();
rtnl_unlock();
@@ -2679,6 +2697,8 @@ static int mpls_net_init(struct net *net)
struct ctl_table *table;
int i;
+ seqcount_init(&net->mpls.platform_label_seq);
+
net->mpls.platform_labels = 0;
net->mpls.platform_label = NULL;
net->mpls.ip_ttl_propagate = 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0976/1887] HID: core: Add reserved item tag for main items
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (974 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0975/1887] mpls: add seqcount to protect the platform_label{,s} pair Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0977/1887] HID: rate-limit hid_warn to prevent log flooding Greg Kroah-Hartman
` (22 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tatsuya S, Jiri Kosina, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tatsuya S <tatsuya.s2862@gmail.com>
[ Upstream commit c600a55922640b1c4dcfdc5a694cadd2dd9d1599 ]
For main items, separate warning of reserved item tag from
warning of unknown item tag.
This comes from 6.2.2.4 Main Items of Device Class Definition
for HID 1.11 specification.
Signed-off-by: Tatsuya S <tatsuya.s2862@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Stable-dep-of: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-core.c | 6 +++++-
include/linux/hid.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 3b1952e66ca42..9ad52318a86de 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -640,7 +640,11 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
break;
default:
- hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag);
+ if (item->tag >= HID_MAIN_ITEM_TAG_RESERVED_MIN &&
+ item->tag <= HID_MAIN_ITEM_TAG_RESERVED_MAX)
+ hid_warn(parser->device, "reserved main item tag 0x%x\n", item->tag);
+ else
+ hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag);
ret = 0;
}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 803bbaccec6ab..941a58f4b5bb6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -80,6 +80,8 @@ struct hid_item {
#define HID_MAIN_ITEM_TAG_FEATURE 11
#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
#define HID_MAIN_ITEM_TAG_END_COLLECTION 12
+#define HID_MAIN_ITEM_TAG_RESERVED_MIN 13
+#define HID_MAIN_ITEM_TAG_RESERVED_MAX 15
/*
* HID report descriptor main item contents
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0977/1887] HID: rate-limit hid_warn to prevent log flooding
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (975 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0976/1887] HID: core: Add reserved item tag for main items Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0978/1887] HID: core: Mitigate potential OOB by removing bogus memset() Greg Kroah-Hartman
` (21 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Li Chen, Jiri Kosina, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Chen <chenl311@chinatelecom.cn>
[ Upstream commit 4051ead99888f101be92c7ce90d2de09aac6fd1c ]
Syzkaller can create many uhid devices that trigger
repeated warnings like:
"hid-generic xxxx: unknown main item tag 0x0"
These messages can flood the system log, especially if a crash occurs
(e.g., with a slow UART console, leading to soft lockups). To mitigate
this, convert `hid_warn()` to use `dev_warn_ratelimited()`.
This helps reduce log noise and improves system stability under fuzzing
or faulty device scenarios.
Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Stable-dep-of: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-core.c | 4 ++--
include/linux/hid.h | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 9ad52318a86de..4b717cc838cf1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -642,9 +642,9 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
default:
if (item->tag >= HID_MAIN_ITEM_TAG_RESERVED_MIN &&
item->tag <= HID_MAIN_ITEM_TAG_RESERVED_MAX)
- hid_warn(parser->device, "reserved main item tag 0x%x\n", item->tag);
+ hid_warn_ratelimited(parser->device, "reserved main item tag 0x%x\n", item->tag);
else
- hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag);
+ hid_warn_ratelimited(parser->device, "unknown main item tag 0x%x\n", item->tag);
ret = 0;
}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 941a58f4b5bb6..09f6ba66f1db2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1248,6 +1248,8 @@ do { \
dev_notice(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_warn(hid, fmt, ...) \
dev_warn(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_warn_ratelimited(hid, fmt, ...) \
+ dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_info(hid, fmt, ...) \
dev_info(&(hid)->dev, fmt, ##__VA_ARGS__)
#define hid_dbg(hid, fmt, ...) \
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0978/1887] HID: core: Mitigate potential OOB by removing bogus memset()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (976 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0977/1887] HID: rate-limit hid_warn to prevent log flooding Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0979/1887] HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure Greg Kroah-Hartman
` (20 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, Benjamin Tissoires,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
[ Upstream commit 0a3fe972a7cb1404f693d6f1711f32bc1d244b1c ]
The memset() in hid_report_raw_event() has the good intention of
clearing out bogus data by zeroing the area from the end of the incoming
data string to the assumed end of the buffer. However, as we have
previously seen, doing so can easily result in OOB reads and writes in
the subsequent thread of execution.
The current suggestion from one of the HID maintainers is to remove the
memset() and simply return if the incoming event buffer size is not
large enough to fill the associated report.
Suggested-by Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Lee Jones <lee@kernel.org>
[bentiss: changed the return value]
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4b717cc838cf1..66deabcfb68b8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2052,9 +2052,9 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
}
if (csize < rsize) {
- dbg_hid("report %d is too short, (%d < %d)\n", report->id,
- csize, rsize);
- memset(cdata + csize, 0, rsize - csize);
+ hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
+ report->id, rsize, csize);
+ return -EINVAL;
}
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0979/1887] HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (977 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0978/1887] HID: core: Mitigate potential OOB by removing bogus memset() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0980/1887] net: ioam6: fix OOB and missing lock Greg Kroah-Hartman
` (19 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, Günther Noack,
Benjamin Tissoires, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
[ Upstream commit f7a4c78bfeb320299c1b641500fe7761eadbd101 ]
Presently, if the force feedback initialisation fails when probing the
Logitech G920 Driving Force Racing Wheel for Xbox One, an error number
will be returned and propagated before the userspace infrastructure
(sysfs and /dev/input) has been torn down. If userspace ignores the
errors and continues to use its references to these dangling entities, a
UAF will promptly follow.
We have 2 options; continue to return the error, but ensure that all of
the infrastructure is torn down accordingly or continue to treat this
condition as a warning by emitting the message but returning success.
It is thought that the original author's intention was to emit the
warning but keep the device functional, less the force feedback feature,
so let's go with that.
Signed-off-by: Lee Jones <lee@kernel.org>
Reviewed-by: Günther Noack <gnoack@google.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-logitech-hidpp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 37fe852dd2da9..ebaca3588342f 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -4278,10 +4278,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
ret = hidpp_ff_init(hidpp, &data);
- if (ret)
+ if (ret) {
hid_warn(hidpp->hid_dev,
"Unable to initialize force feedback support, errno %d\n",
ret);
+ ret = 0;
+ }
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0980/1887] net: ioam6: fix OOB and missing lock
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (978 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0979/1887] HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0981/1887] xfrm: Wait for RCU readers during policy netns exit Greg Kroah-Hartman
` (18 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Justin Iurman,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Iurman <justin.iurman@gmail.com>
[ Upstream commit b30b1675aa2bcf0491fd3830b051df4e08a7c8ca ]
When trace->type.bit6 is set:
if (trace->type.bit6) {
...
queue = skb_get_tx_queue(dev, skb);
qdisc = rcu_dereference(queue->qdisc);
This code can lead to an out-of-bounds access of the dev->_tx[] array
when is_input is true. In such a case, the packet is on the RX path and
skb->queue_mapping contains the RX queue index of the ingress device. If
the ingress device has more RX queues than the egress device (dev) has
TX queues, skb_get_queue_mapping(skb) will exceed dev->num_tx_queues.
Add a check to avoid this situation since skb_get_tx_queue() does not
clamp the index. This issue has also revealed that per queue visibility
cannot be accurate and will be replaced later as a new feature.
While at it, add missing lock around qdisc_qstats_qlen_backlog(). The
function __ioam6_fill_trace_data() is called from both softirq and
process contexts, hence the use of spin_lock_bh() here.
Fixes: b63c5478e9cb ("ipv6: ioam: Support for Queue depth data field")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/netdev/20260403214418.2233266-2-kuba@kernel.org/
Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
Link: https://patch.msgid.link/20260404134137.24553-1-justin.iurman@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ioam6.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index a1953cf6131be..8db53f4da6604 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -737,12 +737,16 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct Qdisc *qdisc;
__u32 qlen, backlog;
- if (skb_dst(skb)->dev->flags & IFF_LOOPBACK) {
+ if (skb_dst(skb)->dev->flags & IFF_LOOPBACK ||
+ skb_get_queue_mapping(skb) >= skb_dst(skb)->dev->num_tx_queues) {
*(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
} else {
queue = skb_get_tx_queue(skb_dst(skb)->dev, skb);
qdisc = rcu_dereference(queue->qdisc);
+
+ spin_lock_bh(qdisc_lock(qdisc));
qdisc_qstats_qlen_backlog(qdisc, &qlen, &backlog);
+ spin_unlock_bh(qdisc_lock(qdisc));
*(__be32 *)data = cpu_to_be32(backlog);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0981/1887] xfrm: Wait for RCU readers during policy netns exit
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (979 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0980/1887] net: ioam6: fix OOB and missing lock Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0982/1887] ipv6: ioam: fix potential NULL dereferences in __ioam6_fill_trace_data() Greg Kroah-Hartman
` (17 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Steffen Klassert, Florian Westphal,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Klassert <steffen.klassert@secunet.com>
[ Upstream commit 069daad4f2ae9c5c108131995529d5f02392c446 ]
xfrm_policy_fini() frees the policy_bydst hash tables after flushing the
policy work items and deleting all policies, but it does not wait for
concurrent RCU readers to leave their read-side critical sections first.
The policy_bydst tables are published via rcu_assign_pointer() and are
looked up through rcu_dereference_check(), so netns teardown must also
wait for an RCU grace period before freeing the table memory.
Fix this by adding synchronize_rcu() before freeing the policy hash tables.
Fixes: e1e551bc5630 ("xfrm: policy: prepare policy_bydst hash for rcu lookups")
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_policy.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 76b7b94132c00..7ababb73d08e3 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -4142,6 +4142,8 @@ static void xfrm_policy_fini(struct net *net)
#endif
xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false);
+ synchronize_rcu();
+
WARN_ON(!list_empty(&net->xfrm.policy_all));
for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0982/1887] ipv6: ioam: fix potential NULL dereferences in __ioam6_fill_trace_data()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (980 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0981/1887] xfrm: Wait for RCU readers during policy netns exit Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0983/1887] xfrm: account XFRMA_IF_ID in aevent size calculation Greg Kroah-Hartman
` (16 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yiming Qian, Eric Dumazet,
Justin Iurman, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 4e65a8b8daa18d63255ec58964dd192c7fdd9f8b ]
We need to check __in6_dev_get() for possible NULL value, as
suggested by Yiming Qian.
Also add skb_dst_dev_rcu() instead of skb_dst_dev(),
and two missing READ_ONCE().
Note that @dev can't be NULL.
Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace")
Reported-by: Yiming Qian <yimingqian591@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
Link: https://patch.msgid.link/20260402101732.1188059-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ioam6.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index 8db53f4da6604..05d8d9a5b3537 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -650,6 +650,9 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct ioam6_schema *sc,
unsigned int sclen, bool is_input)
{
+ /* Note: skb_dst_dev_rcu() can't be NULL at this point. */
+ struct net_device *dev = skb_dst_dev_rcu(skb);
+ struct inet6_dev *i_skb_dev, *idev;
struct timespec64 ts;
ktime_t tstamp;
u64 raw64;
@@ -660,13 +663,16 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
data = trace->data + trace->remlen * 4 - trace->nodelen * 4 - sclen * 4;
+ i_skb_dev = skb->dev ? __in6_dev_get(skb->dev) : NULL;
+ idev = __in6_dev_get(dev);
+
/* hop_lim and node_id */
if (trace->type.bit0) {
byte = ipv6_hdr(skb)->hop_limit;
if (is_input)
byte--;
- raw32 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id;
+ raw32 = READ_ONCE(dev_net(dev)->ipv6.sysctl.ioam6_id);
*(__be32 *)data = cpu_to_be32((byte << 24) | raw32);
data += sizeof(__be32);
@@ -674,18 +680,18 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* ingress_if_id and egress_if_id */
if (trace->type.bit1) {
- if (!skb->dev)
+ if (!i_skb_dev)
raw16 = IOAM6_U16_UNAVAILABLE;
else
- raw16 = (__force u16)__in6_dev_get(skb->dev)->cnf.ioam6_id;
+ raw16 = (__force u16)READ_ONCE(i_skb_dev->cnf.ioam6_id);
*(__be16 *)data = cpu_to_be16(raw16);
data += sizeof(__be16);
- if (skb_dst(skb)->dev->flags & IFF_LOOPBACK)
+ if ((dev->flags & IFF_LOOPBACK) || !idev)
raw16 = IOAM6_U16_UNAVAILABLE;
else
- raw16 = (__force u16)__in6_dev_get(skb_dst(skb)->dev)->cnf.ioam6_id;
+ raw16 = (__force u16)READ_ONCE(idev->cnf.ioam6_id);
*(__be16 *)data = cpu_to_be16(raw16);
data += sizeof(__be16);
@@ -765,7 +771,7 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
if (is_input)
byte--;
- raw64 = dev_net(skb_dst(skb)->dev)->ipv6.sysctl.ioam6_id_wide;
+ raw64 = READ_ONCE(dev_net(dev)->ipv6.sysctl.ioam6_id_wide);
*(__be64 *)data = cpu_to_be64(((u64)byte << 56) | raw64);
data += sizeof(__be64);
@@ -773,18 +779,18 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
/* ingress_if_id and egress_if_id (wide) */
if (trace->type.bit9) {
- if (!skb->dev)
+ if (!i_skb_dev)
raw32 = IOAM6_U32_UNAVAILABLE;
else
- raw32 = __in6_dev_get(skb->dev)->cnf.ioam6_id_wide;
+ raw32 = READ_ONCE(i_skb_dev->cnf.ioam6_id_wide);
*(__be32 *)data = cpu_to_be32(raw32);
data += sizeof(__be32);
- if (skb_dst(skb)->dev->flags & IFF_LOOPBACK)
+ if ((dev->flags & IFF_LOOPBACK) || !idev)
raw32 = IOAM6_U32_UNAVAILABLE;
else
- raw32 = __in6_dev_get(skb_dst(skb)->dev)->cnf.ioam6_id_wide;
+ raw32 = READ_ONCE(idev->cnf.ioam6_id_wide);
*(__be32 *)data = cpu_to_be32(raw32);
data += sizeof(__be32);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0983/1887] xfrm: account XFRMA_IF_ID in aevent size calculation
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (981 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0982/1887] ipv6: ioam: fix potential NULL dereferences in __ioam6_fill_trace_data() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0984/1887] btrfs: fix zero size inode with non-zero size after log replay Greg Kroah-Hartman
` (15 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Keenan Dong, Steffen Klassert,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keenan Dong <keenanat2000@gmail.com>
[ Upstream commit 7081d46d32312f1a31f0e0e99c6835a394037599 ]
xfrm_get_ae() allocates the reply skb with xfrm_aevent_msgsize(), then
build_aevent() appends attributes including XFRMA_IF_ID when x->if_id is
set.
xfrm_aevent_msgsize() does not include space for XFRMA_IF_ID. For states
with if_id, build_aevent() can fail with -EMSGSIZE and hit BUG_ON(err < 0)
in xfrm_get_ae(), turning a malformed netlink interaction into a kernel
panic.
Account XFRMA_IF_ID in the size calculation unconditionally and replace
the BUG_ON with normal error unwinding.
Fixes: 7e6526404ade ("xfrm: Add a new lookup key to match xfrm interfaces.")
Reported-by: Keenan Dong <keenanat2000@gmail.com>
Signed-off-by: Keenan Dong <keenanat2000@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_user.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 6fb79def144c8..9041a9885854f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2366,7 +2366,8 @@ static inline unsigned int xfrm_aevent_msgsize(struct xfrm_state *x)
+ nla_total_size_64bit(sizeof(struct xfrm_lifetime_cur))
+ nla_total_size(sizeof(struct xfrm_mark))
+ nla_total_size(4) /* XFRM_AE_RTHR */
- + nla_total_size(4); /* XFRM_AE_ETHR */
+ + nla_total_size(4) /* XFRM_AE_ETHR */
+ + nla_total_size(sizeof(x->if_id)); /* XFRMA_IF_ID */
}
static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c)
@@ -2467,7 +2468,12 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
c.portid = nlh->nlmsg_pid;
err = build_aevent(r_skb, x, &c);
- BUG_ON(err < 0);
+ if (err < 0) {
+ spin_unlock_bh(&x->lock);
+ xfrm_state_put(x);
+ kfree_skb(r_skb);
+ return err;
+ }
err = nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, NETLINK_CB(skb).portid);
spin_unlock_bh(&x->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0984/1887] btrfs: fix zero size inode with non-zero size after log replay
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (982 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0983/1887] xfrm: account XFRMA_IF_ID in aevent size calculation Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0985/1887] Bluetooth: hci_sync: annotate data-races around hdev->req_status Greg Kroah-Hartman
` (14 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vyacheslav Kovalevsky, Filipe Manana,
David Sterba, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 5254d4181add9dfaa5e3519edd71cc8f752b2f85 ]
When logging that an inode exists, as part of logging a new name or
logging new dir entries for a directory, we always set the generation of
the logged inode item to 0. This is to signal during log replay (in
overwrite_item()), that we should not set the i_size since we only logged
that an inode exists, so the i_size of the inode in the subvolume tree
must be preserved (as when we log new names or that an inode exists, we
don't log extents).
This works fine except when we have already logged an inode in full mode
or it's the first time we are logging an inode created in a past
transaction, that inode has a new i_size of 0 and then we log a new name
for the inode (due to a new hardlink or a rename), in which case we log
an i_size of 0 for the inode and a generation of 0, which causes the log
replay code to not update the inode's i_size to 0 (in overwrite_item()).
An example scenario:
mkdir /mnt/dir
xfs_io -f -c "pwrite 0 64K" /mnt/dir/foo
sync
xfs_io -c "truncate 0" -c "fsync" /mnt/dir/foo
ln /mnt/dir/foo /mnt/dir/bar
xfs_io -c "fsync" /mnt/dir
<power fail>
After log replay the file remains with a size of 64K. This is because when
we first log the inode, when we fsync file foo, we log its current i_size
of 0, and then when we create a hard link we log again the inode in exists
mode (LOG_INODE_EXISTS) but we set a generation of 0 for the inode item we
add to the log tree, so during log replay overwrite_item() sees that the
generation is 0 and i_size is 0 so we skip updating the inode's i_size
from 64K to 0.
Fix this by making sure at fill_inode_item() we always log the real
generation of the inode if it was logged in the current transaction with
the i_size we logged before. Also if an inode created in a previous
transaction is logged in exists mode only, make sure we log the i_size
stored in the inode item located from the commit root, so that if we log
multiple times that the inode exists we get the correct i_size.
A test case for fstests will follow soon.
Reported-by: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/af8c15fa-4e41-4bb2-885c-0bc4e97532a6@gmail.com/
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/tree-log.c | 99 +++++++++++++++++++++++++++++----------------
1 file changed, 65 insertions(+), 34 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e361a608f3ae9..c7697a77e770c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4200,24 +4200,34 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
u64 logged_isize)
{
struct btrfs_map_token token;
+ u64 gen = BTRFS_I(inode)->generation;
u64 flags;
btrfs_init_map_token(&token, leaf);
if (log_inode_only) {
- /* set the generation to zero so the recover code
- * can tell the difference between an logging
- * just to say 'this inode exists' and a logging
- * to say 'update this inode with these values'
+ /*
+ * Set the generation to zero so the recover code can tell the
+ * difference between a logging just to say 'this inode exists'
+ * and a logging to say 'update this inode with these values'.
+ * But only if the inode was not already logged before.
+ * We access ->logged_trans directly since it was already set
+ * up in the call chain by btrfs_log_inode(), and data_race()
+ * to avoid false alerts from KCSAN and since it was set already
+ * and one can set it to 0 since that only happens on eviction
+ * and we are holding a ref on the inode.
*/
- btrfs_set_token_inode_generation(&token, item, 0);
+ ASSERT(data_race(BTRFS_I(inode)->logged_trans) > 0);
+ if (data_race(BTRFS_I(inode)->logged_trans) < trans->transid)
+ gen = 0;
+
btrfs_set_token_inode_size(&token, item, logged_isize);
} else {
- btrfs_set_token_inode_generation(&token, item,
- BTRFS_I(inode)->generation);
btrfs_set_token_inode_size(&token, item, inode->i_size);
}
+ btrfs_set_token_inode_generation(&token, item, gen);
+
btrfs_set_token_inode_uid(&token, item, i_uid_read(inode));
btrfs_set_token_inode_gid(&token, item, i_gid_read(inode));
btrfs_set_token_inode_mode(&token, item, inode->i_mode);
@@ -5033,42 +5043,63 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
return 0;
}
-static int logged_inode_size(struct btrfs_root *log, struct btrfs_inode *inode,
- struct btrfs_path *path, u64 *size_ret)
+static int get_inode_size_to_log(struct btrfs_trans_handle *trans,
+ struct btrfs_inode *inode,
+ struct btrfs_path *path, u64 *size_ret)
{
struct btrfs_key key;
+ struct btrfs_inode_item *item;
int ret;
key.objectid = btrfs_ino(inode);
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, log, &key, path, 0, 0);
- if (ret < 0) {
- return ret;
- } else if (ret > 0) {
- *size_ret = 0;
- } else {
- struct btrfs_inode_item *item;
+ /*
+ * Our caller called inode_logged(), so logged_trans is up to date.
+ * Use data_race() to silence any warning from KCSAN. Once logged_trans
+ * is set, it can only be reset to 0 after inode eviction.
+ */
+ if (data_race(inode->logged_trans) == trans->transid) {
+ ret = btrfs_search_slot(NULL, inode->root->log_root, &key, path, 0, 0);
+ } else if (inode->generation < trans->transid) {
+ path->search_commit_root = true;
+ path->skip_locking = true;
+ ret = btrfs_search_slot(NULL, inode->root, &key, path, 0, 0);
+ path->search_commit_root = false;
+ path->skip_locking = false;
- item = btrfs_item_ptr(path->nodes[0], path->slots[0],
- struct btrfs_inode_item);
- *size_ret = btrfs_inode_size(path->nodes[0], item);
- /*
- * If the in-memory inode's i_size is smaller then the inode
- * size stored in the btree, return the inode's i_size, so
- * that we get a correct inode size after replaying the log
- * when before a power failure we had a shrinking truncate
- * followed by addition of a new name (rename / new hard link).
- * Otherwise return the inode size from the btree, to avoid
- * data loss when replaying a log due to previously doing a
- * write that expands the inode's size and logging a new name
- * immediately after.
- */
- if (*size_ret > inode->vfs_inode.i_size)
- *size_ret = inode->vfs_inode.i_size;
+ } else {
+ *size_ret = 0;
+ return 0;
}
+ /*
+ * If the inode was logged before or is from a past transaction, then
+ * its inode item must exist in the log root or in the commit root.
+ */
+ ASSERT(ret <= 0);
+ if (WARN_ON_ONCE(ret > 0))
+ ret = -ENOENT;
+
+ if (ret < 0)
+ return ret;
+
+ item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ struct btrfs_inode_item);
+ *size_ret = btrfs_inode_size(path->nodes[0], item);
+ /*
+ * If the in-memory inode's i_size is smaller then the inode size stored
+ * in the btree, return the inode's i_size, so that we get a correct
+ * inode size after replaying the log when before a power failure we had
+ * a shrinking truncate followed by addition of a new name (rename / new
+ * hard link). Otherwise return the inode size from the btree, to avoid
+ * data loss when replaying a log due to previously doing a write that
+ * expands the inode's size and logging a new name immediately after.
+ */
+ if (*size_ret > inode->vfs_inode.i_size)
+ *size_ret = inode->vfs_inode.i_size;
+
btrfs_release_path(path);
return 0;
}
@@ -6573,7 +6604,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
ret = drop_inode_items(trans, log, path, inode,
BTRFS_XATTR_ITEM_KEY);
} else {
- if (inode_only == LOG_INODE_EXISTS && ctx->logged_before) {
+ if (inode_only == LOG_INODE_EXISTS) {
/*
* Make sure the new inode item we write to the log has
* the same isize as the current one (if it exists).
@@ -6587,7 +6618,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
* (zeroes), as if an expanding truncate happened,
* instead of getting a file of 4Kb only.
*/
- ret = logged_inode_size(log, inode, path, &logged_isize);
+ ret = get_inode_size_to_log(trans, inode, path, &logged_isize);
if (ret)
goto out_unlock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0985/1887] Bluetooth: hci_sync: annotate data-races around hdev->req_status
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (983 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0984/1887] btrfs: fix zero size inode with non-zero size after log replay Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0986/1887] ALSA: mixer: oss: Add card disconnect checkpoints Greg Kroah-Hartman
` (13 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Luiz Augusto von Dentz,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit b6807cfc195ef99e1ac37b2e1e60df40295daa8c ]
__hci_cmd_sync_sk() sets hdev->req_status under hdev->req_lock:
hdev->req_status = HCI_REQ_PEND;
However, several other functions read or write hdev->req_status without
holding any lock:
- hci_send_cmd_sync() reads req_status in hci_cmd_work (workqueue)
- hci_cmd_sync_complete() reads/writes from HCI event completion
- hci_cmd_sync_cancel() / hci_cmd_sync_cancel_sync() read/write
- hci_abort_conn() reads in connection abort path
Since __hci_cmd_sync_sk() runs on hdev->req_workqueue while
hci_send_cmd_sync() runs on hdev->workqueue, these are different
workqueues that can execute concurrently on different CPUs. The plain
C accesses constitute a data race.
Add READ_ONCE()/WRITE_ONCE() annotations on all concurrent accesses
to hdev->req_status to prevent potential compiler optimizations that
could affect correctness (e.g., load fusing in the wait_event
condition or store reordering).
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_request.c | 2 +-
net/bluetooth/hci_sync.c | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index cf69e973b724f..303fb14fdfad9 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -46,7 +46,7 @@ void hci_req_purge(struct hci_request *req)
bool hci_req_status_pend(struct hci_dev *hdev)
{
- return hdev->req_status == HCI_REQ_PEND;
+ return READ_ONCE(hdev->req_status) == HCI_REQ_PEND;
}
static int req_run(struct hci_request *req, hci_req_complete_t complete,
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 4295c803cfd4a..9529dd7e2a352 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -24,11 +24,11 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
{
bt_dev_dbg(hdev, "result 0x%2.2x", result);
- if (hdev->req_status != HCI_REQ_PEND)
+ if (READ_ONCE(hdev->req_status) != HCI_REQ_PEND)
return;
hdev->req_result = result;
- hdev->req_status = HCI_REQ_DONE;
+ WRITE_ONCE(hdev->req_status, HCI_REQ_DONE);
if (skb) {
struct sock *sk = hci_skb_sk(skb);
@@ -163,20 +163,20 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
hci_cmd_sync_add(&req, opcode, plen, param, event, sk);
- hdev->req_status = HCI_REQ_PEND;
+ WRITE_ONCE(hdev->req_status, HCI_REQ_PEND);
err = hci_req_sync_run(&req);
if (err < 0)
return ERR_PTR(err);
err = wait_event_interruptible_timeout(hdev->req_wait_q,
- hdev->req_status != HCI_REQ_PEND,
+ READ_ONCE(hdev->req_status) != HCI_REQ_PEND,
timeout);
if (err == -ERESTARTSYS)
return ERR_PTR(-EINTR);
- switch (hdev->req_status) {
+ switch (READ_ONCE(hdev->req_status)) {
case HCI_REQ_DONE:
err = -bt_to_errno(hdev->req_result);
break;
@@ -190,7 +190,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
break;
}
- hdev->req_status = 0;
+ WRITE_ONCE(hdev->req_status, 0);
hdev->req_result = 0;
skb = hdev->req_skb;
hdev->req_skb = NULL;
@@ -696,9 +696,9 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
{
bt_dev_dbg(hdev, "err 0x%2.2x", err);
- if (hdev->req_status == HCI_REQ_PEND) {
+ if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
hdev->req_result = err;
- hdev->req_status = HCI_REQ_CANCELED;
+ WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED);
queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
}
@@ -714,12 +714,12 @@ void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
{
bt_dev_dbg(hdev, "err 0x%2.2x", err);
- if (hdev->req_status == HCI_REQ_PEND) {
+ if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND) {
/* req_result is __u32 so error must be positive to be properly
* propagated.
*/
hdev->req_result = err < 0 ? -err : err;
- hdev->req_status = HCI_REQ_CANCELED;
+ WRITE_ONCE(hdev->req_status, HCI_REQ_CANCELED);
wake_up_interruptible(&hdev->req_wait_q);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0986/1887] ALSA: mixer: oss: Add card disconnect checkpoints
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (984 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0985/1887] Bluetooth: hci_sync: annotate data-races around hdev->req_status Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0987/1887] ima: verify the previous kernels IMA buffer lies in addressable RAM Greg Kroah-Hartman
` (12 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 084d5d44418148662365eced3e126ad1a81ee3e2 ]
ALSA OSS mixer layer calls the kcontrol ops rather individually, and
pending calls might be not always caught at disconnecting the device.
For avoiding the potential UAF scenarios, add sanity checks of the
card disconnection at each entry point of OSS mixer accesses. The
rwsem is taken just before that check, hence the rest context should
be covered by that properly.
Link: https://patch.msgid.link/20260209121212.171430-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/oss/mixer_oss.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index abc99ae333282..ecb4af6709598 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -540,6 +540,10 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ up_read(&card->controls_rwsem);
+ return;
+ }
kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) {
up_read(&card->controls_rwsem);
@@ -579,6 +583,10 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ up_read(&card->controls_rwsem);
+ return;
+ }
kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) {
up_read(&card->controls_rwsem);
@@ -645,6 +653,10 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ up_read(&card->controls_rwsem);
+ return;
+ }
kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) {
up_read(&card->controls_rwsem);
@@ -688,6 +700,10 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
if (numid == ID_UNKNOWN)
return;
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ up_read(&card->controls_rwsem);
+ return;
+ }
kctl = snd_ctl_find_numid_locked(card, numid);
if (!kctl) {
up_read(&card->controls_rwsem);
@@ -833,6 +849,10 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
goto __free_only;
}
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ err = -ENODEV;
+ goto __unlock;
+ }
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
if (! kctl) {
err = -ENOENT;
@@ -886,6 +906,10 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
goto __free_only;
}
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ err = -ENODEV;
+ goto __unlock;
+ }
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
if (! kctl) {
err = -ENOENT;
@@ -937,6 +961,10 @@ static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *sl
int err;
down_read(&card->controls_rwsem);
+ if (card->shutdown) {
+ up_read(&card->controls_rwsem);
+ return -ENODEV;
+ }
kcontrol = snd_mixer_oss_test_id(mixer, name, index);
if (kcontrol == NULL) {
up_read(&card->controls_rwsem);
@@ -1069,6 +1097,10 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer,
if (snd_mixer_oss_build_test_all(mixer, ptr, &slot))
return 0;
down_read(&mixer->card->controls_rwsem);
+ if (mixer->card->shutdown) {
+ up_read(&mixer->card->controls_rwsem);
+ return -ENODEV;
+ }
kctl = NULL;
if (!ptr->index)
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0987/1887] ima: verify the previous kernels IMA buffer lies in addressable RAM
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (985 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0986/1887] ALSA: mixer: oss: Add card disconnect checkpoints Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0988/1887] xfs: remove xfs_attr_leaf_hasname Greg Kroah-Hartman
` (11 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harshit Mogalapalli, Mimi Zohar,
Alexander Graf, Ard Biesheuvel, Borislav Betkov, guoweikang,
Henry Willard, H. Peter Anvin, Ingo Molnar, Jiri Bohac,
Joel Granados, Jonathan McDowell, Mike Rapoport, Paul Webb,
Sohil Mehta, Sourabh Jain, Thomas Gleinxer, Yifei Liu, Baoquan He,
Andrew Morton, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
[ Upstream commit 10d1c75ed4382a8e79874379caa2ead8952734f9 ]
Patch series "Address page fault in ima_restore_measurement_list()", v3.
When the second-stage kernel is booted via kexec with a limiting command
line such as "mem=<size>" we observe a pafe fault that happens.
BUG: unable to handle page fault for address: ffff97793ff47000
RIP: ima_restore_measurement_list+0xdc/0x45a
#PF: error_code(0x0000) not-present page
This happens on x86_64 only, as this is already fixed in aarch64 in
commit: cbf9c4b9617b ("of: check previous kernel's ima-kexec-buffer
against memory bounds")
This patch (of 3):
When the second-stage kernel is booted with a limiting command line (e.g.
"mem=<size>"), the IMA measurement buffer handed over from the previous
kernel may fall outside the addressable RAM of the new kernel. Accessing
such a buffer can fault during early restore.
Introduce a small generic helper, ima_validate_range(), which verifies
that a physical [start, end] range for the previous-kernel IMA buffer lies
within addressable memory:
- On x86, use pfn_range_is_mapped().
- On OF based architectures, use page_is_ram().
Link: https://lkml.kernel.org/r/20251231061609.907170-1-harshit.m.mogalapalli@oracle.com
Link: https://lkml.kernel.org/r/20251231061609.907170-2-harshit.m.mogalapalli@oracle.com
Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Cc: Alexander Graf <graf@amazon.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Borislav Betkov <bp@alien8.de>
Cc: guoweikang <guoweikang.kernel@gmail.com>
Cc: Henry Willard <henry.willard@oracle.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Joel Granados <joel.granados@kernel.org>
Cc: Jonathan McDowell <noodles@fb.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Paul Webb <paul.x.webb@oracle.com>
Cc: Sohil Mehta <sohil.mehta@intel.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
Cc: Thomas Gleinxer <tglx@linutronix.de>
Cc: Yifei Liu <yifei.l.liu@oracle.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ima.h | 1 +
security/integrity/ima/ima_kexec.c | 35 ++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 83ddee788583e..21f442c3fa887 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -145,6 +145,7 @@ static inline int ima_measure_critical_data(const char *event_label,
#ifdef CONFIG_HAVE_IMA_KEXEC
int __init ima_free_kexec_buffer(void);
int __init ima_get_kexec_buffer(void **addr, size_t *size);
+int ima_validate_range(phys_addr_t phys, size_t size);
#endif
#ifdef CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 419dc405c8310..9a63c9a327d48 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -12,6 +12,8 @@
#include <linux/kexec.h>
#include <linux/of.h>
#include <linux/ima.h>
+#include <linux/mm.h>
+#include <linux/overflow.h>
#include "ima.h"
#ifdef CONFIG_IMA_KEXEC
@@ -164,3 +166,36 @@ void __init ima_load_kexec_buffer(void)
pr_debug("Error restoring the measurement list: %d\n", rc);
}
}
+
+/*
+ * ima_validate_range - verify a physical buffer lies in addressable RAM
+ * @phys: physical start address of the buffer from previous kernel
+ * @size: size of the buffer
+ *
+ * On success return 0. On failure returns -EINVAL so callers can skip
+ * restoring.
+ */
+int ima_validate_range(phys_addr_t phys, size_t size)
+{
+ unsigned long start_pfn, end_pfn;
+ phys_addr_t end_phys;
+
+ if (check_add_overflow(phys, (phys_addr_t)size - 1, &end_phys))
+ return -EINVAL;
+
+ start_pfn = PHYS_PFN(phys);
+ end_pfn = PHYS_PFN(end_phys);
+
+#ifdef CONFIG_X86
+ if (!pfn_range_is_mapped(start_pfn, end_pfn))
+#else
+ if (!page_is_ram(start_pfn) || !page_is_ram(end_pfn))
+#endif
+ {
+ pr_warn("IMA: previous kernel measurement buffer %pa (size 0x%zx) lies outside available memory\n",
+ &phys, size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0988/1887] xfs: remove xfs_attr_leaf_hasname
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (986 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0987/1887] ima: verify the previous kernels IMA buffer lies in addressable RAM Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0989/1887] xfrm: always flush state and policy upon NETDEV_UNREGISTER event Greg Kroah-Hartman
` (10 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Tinguely, Christoph Hellwig,
Darrick J. Wong, Carlos Maiolino, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit 3a65ea768b8094e4699e72f9ab420eb9e0f3f568 ]
The calling convention of xfs_attr_leaf_hasname() is problematic, because
it returns a NULL buffer when xfs_attr3_leaf_read fails, a valid buffer
when xfs_attr3_leaf_lookup_int returns -ENOATTR or -EEXIST, and a
non-NULL buffer pointer for an already released buffer when
xfs_attr3_leaf_lookup_int fails with other error values.
Fix this by simply open coding xfs_attr_leaf_hasname in the callers, so
that the buffer release code is done by each caller of
xfs_attr3_leaf_read.
Cc: stable@vger.kernel.org # v5.19+
Fixes: 07120f1abdff ("xfs: Add xfs_has_attr and subroutines")
Reported-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/libxfs/xfs_attr.c | 74 +++++++++++++---------------------------
1 file changed, 23 insertions(+), 51 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 32d350e97e0f6..236291dbb427f 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -49,7 +49,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
*/
STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
/*
@@ -866,11 +865,11 @@ xfs_attr_lookup(
return xfs_attr_sf_findname(args, NULL, NULL);
if (xfs_attr_is_leaf(dp)) {
- error = xfs_attr_leaf_hasname(args, &bp);
-
- if (bp)
- xfs_trans_brelse(args->trans, bp);
-
+ error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
+ if (error)
+ return error;
+ error = xfs_attr3_leaf_lookup_int(bp, args);
+ xfs_trans_brelse(args->trans, bp);
return error;
}
@@ -1246,27 +1245,6 @@ xfs_attr_leaf_try_add(
return error;
}
-/*
- * Return EEXIST if attr is found, or ENOATTR if not
- */
-STATIC int
-xfs_attr_leaf_hasname(
- struct xfs_da_args *args,
- struct xfs_buf **bp)
-{
- int error = 0;
-
- error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
- if (error)
- return error;
-
- error = xfs_attr3_leaf_lookup_int(*bp, args);
- if (error != -ENOATTR && error != -EEXIST)
- xfs_trans_brelse(args->trans, *bp);
-
- return error;
-}
-
/*
* Remove a name from the leaf attribute list structure
*
@@ -1277,25 +1255,22 @@ STATIC int
xfs_attr_leaf_removename(
struct xfs_da_args *args)
{
- struct xfs_inode *dp;
- struct xfs_buf *bp;
+ struct xfs_inode *dp = args->dp;
int error, forkoff;
+ struct xfs_buf *bp;
trace_xfs_attr_leaf_removename(args);
- /*
- * Remove the attribute.
- */
- dp = args->dp;
-
- error = xfs_attr_leaf_hasname(args, &bp);
- if (error == -ENOATTR) {
+ error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
+ if (error)
+ return error;
+ error = xfs_attr3_leaf_lookup_int(bp, args);
+ if (error != -EEXIST) {
xfs_trans_brelse(args->trans, bp);
- if (args->op_flags & XFS_DA_OP_RECOVERY)
+ if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
return 0;
return error;
- } else if (error != -EEXIST)
- return error;
+ }
xfs_attr3_leaf_remove(bp, args);
@@ -1319,23 +1294,20 @@ xfs_attr_leaf_removename(
* Returns 0 on successful retrieval, otherwise an error.
*/
STATIC int
-xfs_attr_leaf_get(xfs_da_args_t *args)
+xfs_attr_leaf_get(
+ struct xfs_da_args *args)
{
- struct xfs_buf *bp;
- int error;
+ struct xfs_buf *bp;
+ int error;
trace_xfs_attr_leaf_get(args);
- error = xfs_attr_leaf_hasname(args, &bp);
-
- if (error == -ENOATTR) {
- xfs_trans_brelse(args->trans, bp);
- return error;
- } else if (error != -EEXIST)
+ error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
+ if (error)
return error;
-
-
- error = xfs_attr3_leaf_getvalue(bp, args);
+ error = xfs_attr3_leaf_lookup_int(bp, args);
+ if (error == -EEXIST)
+ error = xfs_attr3_leaf_getvalue(bp, args);
xfs_trans_brelse(args->trans, bp);
return error;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0989/1887] xfrm: always flush state and policy upon NETDEV_UNREGISTER event
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (987 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0988/1887] xfs: remove xfs_attr_leaf_hasname Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0990/1887] usb: dwc3: gadget: Move vbus draw to workqueue context Greg Kroah-Hartman
` (9 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+881d65229ca4f9ae8c84,
Sabrina Dubroca, Tetsuo Handa, Steffen Klassert, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[ Upstream commit 4efa91a28576054aae0e6dad9cba8fed8293aef8 ]
syzbot is reporting that "struct xfrm_state" refcount is leaking.
unregister_netdevice: waiting for netdevsim0 to become free. Usage count = 2
ref_tracker: netdev@ffff888052f24618 has 1/1 users at
__netdev_tracker_alloc include/linux/netdevice.h:4400 [inline]
netdev_tracker_alloc include/linux/netdevice.h:4412 [inline]
xfrm_dev_state_add+0x3a5/0x1080 net/xfrm/xfrm_device.c:316
xfrm_state_construct net/xfrm/xfrm_user.c:986 [inline]
xfrm_add_sa+0x34ff/0x5fa0 net/xfrm/xfrm_user.c:1022
xfrm_user_rcv_msg+0x58e/0xc00 net/xfrm/xfrm_user.c:3507
netlink_rcv_skb+0x158/0x420 net/netlink/af_netlink.c:2550
xfrm_netlink_rcv+0x71/0x90 net/xfrm/xfrm_user.c:3529
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x5aa/0x870 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x8c8/0xdd0 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg net/socket.c:742 [inline]
____sys_sendmsg+0xa5d/0xc30 net/socket.c:2592
___sys_sendmsg+0x134/0x1d0 net/socket.c:2646
__sys_sendmsg+0x16d/0x220 net/socket.c:2678
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xcd/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
This is because commit d77e38e612a0 ("xfrm: Add an IPsec hardware
offloading API") implemented xfrm_dev_unregister() as no-op despite
xfrm_dev_state_add() from xfrm_state_construct() acquires a reference
to "struct net_device".
I guess that that commit expected that NETDEV_DOWN event is fired before
NETDEV_UNREGISTER event fires, and also assumed that xfrm_dev_state_add()
is called only if (dev->features & NETIF_F_HW_ESP) != 0.
Sabrina Dubroca identified steps to reproduce the same symptoms as below.
echo 0 > /sys/bus/netdevsim/new_device
dev=$(ls -1 /sys/bus/netdevsim/devices/netdevsim0/net/)
ip xfrm state add src 192.168.13.1 dst 192.168.13.2 proto esp \
spi 0x1000 mode tunnel aead 'rfc4106(gcm(aes))' $key 128 \
offload crypto dev $dev dir out
ethtool -K $dev esp-hw-offload off
echo 0 > /sys/bus/netdevsim/del_device
Like these steps indicate, the NETIF_F_HW_ESP bit can be cleared after
xfrm_dev_state_add() acquired a reference to "struct net_device".
Also, xfrm_dev_state_add() does not check for the NETIF_F_HW_ESP bit
when acquiring a reference to "struct net_device".
Commit 03891f820c21 ("xfrm: handle NETDEV_UNREGISTER for xfrm device")
re-introduced the NETDEV_UNREGISTER event to xfrm_dev_event(), but that
commit for unknown reason chose to share xfrm_dev_down() between the
NETDEV_DOWN event and the NETDEV_UNREGISTER event.
I guess that that commit missed the behavior in the previous paragraph.
Therefore, we need to re-introduce xfrm_dev_unregister() in order to
release the reference to "struct net_device" by unconditionally flushing
state and policy.
Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84
Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
Cc: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_device.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 313c0eb3381f3..c676ff2f21acc 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -424,6 +424,13 @@ static int xfrm_dev_down(struct net_device *dev)
return NOTIFY_DONE;
}
+static int xfrm_dev_unregister(struct net_device *dev)
+{
+ xfrm_dev_state_flush(dev_net(dev), dev, true);
+
+ return NOTIFY_DONE;
+}
+
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
@@ -436,8 +443,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
return xfrm_api_check(dev);
case NETDEV_DOWN:
- case NETDEV_UNREGISTER:
return xfrm_dev_down(dev);
+
+ case NETDEV_UNREGISTER:
+ return xfrm_dev_unregister(dev);
}
return NOTIFY_DONE;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0990/1887] usb: dwc3: gadget: Move vbus draw to workqueue context
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (988 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0989/1887] xfrm: always flush state and policy upon NETDEV_UNREGISTER event Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0991/1887] ksmbd: fix signededness bug in smb_direct_prepare_negotiation() Greg Kroah-Hartman
` (8 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Samuel Wu, Thinh Nguyen,
Prashanth K, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth K <prashanth.k@oss.qualcomm.com>
[ Upstream commit 54aaa3b387c2f580a99dc86a9cc2eb6dfaf599a7 ]
Currently dwc3_gadget_vbus_draw() can be called from atomic
context, which in turn invokes power-supply-core APIs. And
some these PMIC APIs have operations that may sleep, leading
to kernel panic.
Fix this by moving the vbus_draw into a workqueue context.
Fixes: 99288de36020 ("usb: dwc3: add an alternate path in vbus_draw callback")
Cc: stable <stable@kernel.org>
Tested-by: Samuel Wu <wusamuel@google.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com>
Link: https://patch.msgid.link/20260204054155.3063825-1-prashanth.k@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/dwc3/core.c | 19 ++++++++++++++++++-
drivers/usb/dwc3/core.h | 4 ++++
drivers/usb/dwc3/gadget.c | 8 +++-----
3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7793936757ac3..dbddc1d45fdcc 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1855,6 +1855,20 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
return edev;
}
+static void dwc3_vbus_draw_work(struct work_struct *work)
+{
+ struct dwc3 *dwc = container_of(work, struct dwc3, vbus_draw_work);
+ union power_supply_propval val = {0};
+ int ret;
+
+ val.intval = 1000 * (dwc->current_limit);
+ ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
+
+ if (ret < 0)
+ dev_dbg(dwc->dev, "Error (%d) setting vbus draw (%d mA)\n",
+ ret, dwc->current_limit);
+}
+
static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
{
struct power_supply *usb_psy;
@@ -1869,6 +1883,7 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
if (!usb_psy)
return ERR_PTR(-EPROBE_DEFER);
+ INIT_WORK(&dwc->vbus_draw_work, dwc3_vbus_draw_work);
return usb_psy;
}
@@ -2120,8 +2135,10 @@ static int dwc3_remove(struct platform_device *pdev)
dwc3_free_event_buffers(dwc);
dwc3_free_scratch_buffers(dwc);
- if (dwc->usb_psy)
+ if (dwc->usb_psy) {
+ cancel_work_sync(&dwc->vbus_draw_work);
power_supply_put(dwc->usb_psy);
+ }
return 0;
}
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index e4e0c40dc51d3..0119a8940c8d5 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1035,6 +1035,8 @@ struct dwc3_scratchpad_array {
* @role_switch_default_mode: default operation mode of controller while
* usb role is USB_ROLE_NONE.
* @usb_psy: pointer to power supply interface.
+ * @vbus_draw_work: Work to set the vbus drawing limit
+ * @current_limit: How much current to draw from vbus, in milliAmperes.
* @usb2_phy: pointer to USB2 PHY
* @usb3_phy: pointer to USB3 PHY
* @usb2_generic_phy: pointer to USB2 PHY
@@ -1207,6 +1209,8 @@ struct dwc3 {
enum usb_dr_mode role_switch_default_mode;
struct power_supply *usb_psy;
+ struct work_struct vbus_draw_work;
+ unsigned int current_limit;
u32 fladj;
u32 ref_clk_per;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index cd0532158ba0b..18fab84af369e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3019,8 +3019,6 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g,
static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
{
struct dwc3 *dwc = gadget_to_dwc(g);
- union power_supply_propval val = {0};
- int ret;
if (dwc->usb2_phy)
return usb_phy_set_power(dwc->usb2_phy, mA);
@@ -3028,10 +3026,10 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
if (!dwc->usb_psy)
return -EOPNOTSUPP;
- val.intval = 1000 * mA;
- ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
+ dwc->current_limit = mA;
+ schedule_work(&dwc->vbus_draw_work);
- return ret;
+ return 0;
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0991/1887] ksmbd: fix signededness bug in smb_direct_prepare_negotiation()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (989 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0990/1887] usb: dwc3: gadget: Move vbus draw to workqueue context Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0992/1887] ASoC: qcom: q6asm: handle the responses after closing Greg Kroah-Hartman
` (7 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Stefan Metzmacher,
Namjae Jeon, Steve French, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Carlini <nicholas@carlini.com>
[ Upstream commit 6b4f875aac344cdd52a1f34cc70ed2f874a65757 ]
smb_direct_prepare_negotiation() casts an unsigned __u32 value
from sp->max_recv_size and req->preferred_send_size to a signed
int before computing min_t(int, ...). A maliciously provided
preferred_send_size of 0x80000000 will return as smaller than
max_recv_size, and then be used to set the maximum allowed
alowed receive size for the next message.
By sending a second message with a large value (>1420 bytes)
the attacker can then achieve a heap buffer overflow.
This fix replaces min_t(int, ...) with min_t(u32)
Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
Signed-off-by: Nicholas Carlini <nicholas@carlini.com>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_rdma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index 1290c0fa7dd18..bcf0631ce10a6 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -1967,9 +1967,9 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
goto out;
req = (struct smb_direct_negotiate_req *)recvmsg->packet;
- st->max_recv_size = min_t(int, st->max_recv_size,
+ st->max_recv_size = min_t(u32, st->max_recv_size,
le32_to_cpu(req->preferred_send_size));
- st->max_send_size = min_t(int, st->max_send_size,
+ st->max_send_size = min_t(u32, st->max_send_size,
le32_to_cpu(req->max_receive_size));
st->max_fragmented_send_size =
le32_to_cpu(req->max_fragmented_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0992/1887] ASoC: qcom: q6asm: handle the responses after closing
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (990 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0991/1887] ksmbd: fix signededness bug in smb_direct_prepare_negotiation() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0993/1887] ASoC: qcom: q6asm: drop DSP responses for closed data streams Greg Kroah-Hartman
` (6 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Martino Facchin, Srinivas Kandagatla,
Mark Brown, Sasha Levin, Alexey Klimov
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
[ Upstream commit a354f030dbce17ab3cf299660a38b162d97f7151 ]
For record path, multiple read requests are queued to dsp in advance.
However when data stream is closed, the pending read requests are rejected
by the dsp and a response is sent to the driver, this case is not handled
in the driver resulting in errors like below
q6asm-dai ab00000.remoteproc:glink-edge:apr:service@7:dais: command[0x10dac] not expecting rsp
q6asm-dai ab00000.remoteproc:glink-edge:apr:service@7:dais: command[0x10dac] not expecting rsp
q6asm-dai ab00000.remoteproc:glink-edge:apr:service@7:dais: command[0x10dac] not expecting rsp
This is same for both write and eos.
Fix this by allowing ASM_DATA_CMD_READ_V2, ASM_DATA_CMD_EOS and
ASM_DATA_CMD_WRITE_V2 as expected response.
Reported-by: Martino Facchin <m.facchin@arduino.cc>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Tested-by: Alexey Klimov <alexey.klimov@linaro.org> # RB5, RB3
Link: https://patch.msgid.link/20251023102444.88158-6-srinivas.kandagatla@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 8a066a81ee0c ("ASoC: qcom: q6asm: drop DSP responses for closed data streams")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/qcom/qdsp6/q6asm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 9f53cffe5184e..85abf2ce091fe 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -637,6 +637,7 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
client_event = ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE;
break;
case ASM_STREAM_CMD_OPEN_WRITE_V3:
+ case ASM_DATA_CMD_WRITE_V2:
case ASM_STREAM_CMD_OPEN_READ_V3:
case ASM_STREAM_CMD_OPEN_READWRITE_V2:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
@@ -653,6 +654,10 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
goto done;
}
break;
+ case ASM_DATA_CMD_EOS:
+ case ASM_DATA_CMD_READ_V2:
+ /* response as result of close stream */
+ break;
default:
dev_err(ac->dev, "command[0x%x] not expecting rsp\n",
result->opcode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0993/1887] ASoC: qcom: q6asm: drop DSP responses for closed data streams
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (991 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0992/1887] ASoC: qcom: q6asm: handle the responses after closing Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0994/1887] wifi: rtw89: pci: validate sequence number of TX release report Greg Kroah-Hartman
` (5 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cédric Bellegarde, Mark Brown,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cédric Bellegarde <cedric.bellegarde@adishatz.org>
[ Upstream commit 8a066a81ee0c1b6cdbd81393536c3b2d19ccef25 ]
'Commit a354f030dbce ("ASoC: qcom: q6asm: handle the responses
after closing")' attempted to ignore DSP responses arriving
after a stream had been closed.
However, those responses were still handled, causing lockups.
Fix this by unconditionally dropping all DSP responses associated with
closed data streams.
Signed-off-by: Cédric Bellegarde <cedric.bellegarde@adishatz.org>
Link: https://patch.msgid.link/20260102215225.609166-1-cedric.bellegarde@adishatz.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/qcom/qdsp6/q6asm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 85abf2ce091fe..b6bdb977029da 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -637,7 +637,6 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
client_event = ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE;
break;
case ASM_STREAM_CMD_OPEN_WRITE_V3:
- case ASM_DATA_CMD_WRITE_V2:
case ASM_STREAM_CMD_OPEN_READ_V3:
case ASM_STREAM_CMD_OPEN_READWRITE_V2:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
@@ -656,8 +655,9 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
break;
case ASM_DATA_CMD_EOS:
case ASM_DATA_CMD_READ_V2:
+ case ASM_DATA_CMD_WRITE_V2:
/* response as result of close stream */
- break;
+ goto done;
default:
dev_err(ac->dev, "command[0x%x] not expecting rsp\n",
result->opcode);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0994/1887] wifi: rtw89: pci: validate sequence number of TX release report
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (992 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0993/1887] ASoC: qcom: q6asm: drop DSP responses for closed data streams Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0995/1887] cifs: Fix locking usage for tcon fields Greg Kroah-Hartman
` (4 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ping-Ke Shih <pkshih@realtek.com>
[ Upstream commit 957eda596c7665f2966970fd1dcc35fe299b38e8 ]
Hardware rarely reports abnormal sequence number in TX release report,
which will access out-of-bounds of wd_ring->pages array, causing NULL
pointer dereference.
BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
CPU: 1 PID: 1085 Comm: irq/129-rtw89_p Tainted: G S U
6.1.145-17510-g2f3369c91536 #1 (HASH:69e8 1)
Call Trace:
<IRQ>
rtw89_pci_release_tx+0x18f/0x300 [rtw89_pci (HASH:4c83 2)]
rtw89_pci_napi_poll+0xc2/0x190 [rtw89_pci (HASH:4c83 2)]
net_rx_action+0xfc/0x460 net/core/dev.c:6578 net/core/dev.c:6645 net/core/dev.c:6759
handle_softirqs+0xbe/0x290 kernel/softirq.c:601
? rtw89_pci_interrupt_threadfn+0xc5/0x350 [rtw89_pci (HASH:4c83 2)]
__local_bh_enable_ip+0xeb/0x120 kernel/softirq.c:499 kernel/softirq.c:423
</IRQ>
<TASK>
rtw89_pci_interrupt_threadfn+0xf8/0x350 [rtw89_pci (HASH:4c83 2)]
? irq_thread+0xa7/0x340 kernel/irq/manage.c:0
irq_thread+0x177/0x340 kernel/irq/manage.c:1205 kernel/irq/manage.c:1314
? thaw_kernel_threads+0xb0/0xb0 kernel/irq/manage.c:1202
? irq_forced_thread_fn+0x80/0x80 kernel/irq/manage.c:1220
kthread+0xea/0x110 kernel/kthread.c:376
? synchronize_irq+0x1a0/0x1a0 kernel/irq/manage.c:1287
? kthread_associate_blkcg+0x80/0x80 kernel/kthread.c:331
ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
</TASK>
To prevent crash, validate rpp_info.seq before using.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260110022019.2254969-2-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw89/pci.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index ac76697dc4627..11634b6d40145 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -472,11 +472,16 @@ static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev,
tx_status = le32_get_bits(rpp->dword, RTW89_PCI_RPP_TX_STATUS);
txch = rtw89_core_get_ch_dma(rtwdev, qsel);
- if (txch == RTW89_TXCH_CH12) {
+ if (unlikely(txch == RTW89_TXCH_CH12)) {
rtw89_warn(rtwdev, "should no fwcmd release report\n");
return;
}
+ if (unlikely(seq >= RTW89_PCI_TXWD_NUM_MAX)) {
+ rtw89_warn(rtwdev, "invalid seq %d\n", seq);
+ return;
+ }
+
tx_ring = &rtwpci->tx_rings[txch];
wd_ring = &tx_ring->wd_ring;
txwd = &wd_ring->pages[seq];
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0995/1887] cifs: Fix locking usage for tcon fields
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (993 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0994/1887] wifi: rtw89: pci: validate sequence number of TX release report Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0996/1887] team: avoid NETDEV_CHANGEMTU event when unregistering slave Greg Kroah-Hartman
` (3 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shyam Prasad N, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <sprasad@microsoft.com>
[ Upstream commit 96c4af418586ee9a6aab61738644366426e05316 ]
We used to use the cifs_tcp_ses_lock to protect a lot of objects
that are not just the server, ses or tcon lists. We later introduced
srv_lock, ses_lock and tc_lock to protect fields within the
corresponding structs. This was done to provide a more granular
protection and avoid unnecessary serialization.
There were still a couple of uses of cifs_tcp_ses_lock to provide
tcon fields. In this patch, I've replaced them with tc_lock.
Cc: stable@vger.kernel.org
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2misc.c | 6 +++---
fs/smb/client/smb2ops.c | 10 +++-------
fs/smb/client/smb2pdu.c | 2 ++
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index ecab56c00f627..27d0fc56cd825 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -847,14 +847,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
int rc;
cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
- spin_lock(&cifs_tcp_ses_lock);
+ spin_lock(&tcon->tc_lock);
if (tcon->tc_count <= 0) {
struct TCP_Server_Info *server = NULL;
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
netfs_trace_tcon_ref_see_cancelled_close);
WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
- spin_unlock(&cifs_tcp_ses_lock);
+ spin_unlock(&tcon->tc_lock);
if (tcon->ses) {
server = tcon->ses->server;
@@ -868,7 +868,7 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
tcon->tc_count++;
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
netfs_trace_tcon_ref_get_cancelled_close);
- spin_unlock(&cifs_tcp_ses_lock);
+ spin_unlock(&tcon->tc_lock);
rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
persistent_fid, volatile_fid, false);
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index ef61a60a082ef..a59df97b55282 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2863,7 +2863,9 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
struct cifs_tcon,
tcon_list);
if (tcon) {
+ spin_lock(&tcon->tc_lock);
tcon->tc_count++;
+ spin_unlock(&tcon->tc_lock);
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
netfs_trace_tcon_ref_get_dfs_refer);
}
@@ -2928,13 +2930,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
out:
if (tcon && !tcon->ipc) {
/* ipc tcons are not refcounted */
- spin_lock(&cifs_tcp_ses_lock);
- tcon->tc_count--;
- trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
- netfs_trace_tcon_ref_dec_dfs_refer);
- /* tc_count can never go negative */
- WARN_ON(tcon->tc_count < 0);
- spin_unlock(&cifs_tcp_ses_lock);
+ cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_dfs_refer);
}
kfree(utf16_path);
kfree(dfs_req);
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index c50881cf4c8d7..8f23b8968beb4 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -4025,7 +4025,9 @@ void smb2_reconnect_server(struct work_struct *work)
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
if (tcon->need_reconnect || tcon->need_reopen_files) {
+ spin_lock(&tcon->tc_lock);
tcon->tc_count++;
+ spin_unlock(&tcon->tc_lock);
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
netfs_trace_tcon_ref_get_reconnect_server);
list_add_tail(&tcon->rlist, &tmp_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0996/1887] team: avoid NETDEV_CHANGEMTU event when unregistering slave
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (994 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0995/1887] cifs: Fix locking usage for tcon fields Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0997/1887] smb: client: prevent races in ->query_interfaces() Greg Kroah-Hartman
` (2 subsequent siblings)
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+881d65229ca4f9ae8c84,
Ido Schimmel, Jiri Pirko, Tetsuo Handa, Stanislav Fomichev,
Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[ Upstream commit bb4c698633c0e19717586a6524a33196cff01a32 ]
syzbot is reporting
unregister_netdevice: waiting for netdevsim0 to become free. Usage count = 3
ref_tracker: netdev@ffff88807dcf8618 has 1/2 users at
__netdev_tracker_alloc include/linux/netdevice.h:4400 [inline]
netdev_hold include/linux/netdevice.h:4429 [inline]
inetdev_init+0x201/0x4e0 net/ipv4/devinet.c:286
inetdev_event+0x251/0x1610 net/ipv4/devinet.c:1600
notifier_call_chain+0x19d/0x3a0 kernel/notifier.c:85
call_netdevice_notifiers_mtu net/core/dev.c:2318 [inline]
netif_set_mtu_ext+0x5aa/0x800 net/core/dev.c:9886
netif_set_mtu+0xd7/0x1b0 net/core/dev.c:9907
dev_set_mtu+0x126/0x260 net/core/dev_api.c:248
team_port_del+0xb07/0xcb0 drivers/net/team/team_core.c:1333
team_del_slave drivers/net/team/team_core.c:1936 [inline]
team_device_event+0x207/0x5b0 drivers/net/team/team_core.c:2929
notifier_call_chain+0x19d/0x3a0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
call_netdevice_notifiers net/core/dev.c:2295 [inline]
__dev_change_net_namespace+0xcb7/0x2050 net/core/dev.c:12592
do_setlink+0x2ce/0x4590 net/core/rtnetlink.c:3060
rtnl_changelink net/core/rtnetlink.c:3776 [inline]
__rtnl_newlink net/core/rtnetlink.c:3935 [inline]
rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
problem. Ido Schimmel found steps to reproduce
ip link add name team1 type team
ip link add name dummy1 mtu 1499 master team1 type dummy
ip netns add ns1
ip link set dev dummy1 netns ns1
ip -n ns1 link del dev dummy1
and also found that the same issue was fixed in the bond driver in
commit f51048c3e07b ("bonding: avoid NETDEV_CHANGEMTU event when
unregistering slave").
Let's do similar thing for the team driver, with commit ad7c7b2172c3 ("net:
hold netdev instance lock during sysfs operations") and commit 303a8487a657
("net: s/__dev_set_mtu/__netif_set_mtu/") also applied.
Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device")
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20260224125709.317574-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/team/team.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 386c989641a3e..9d5f7026adec4 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1361,7 +1361,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
static void __team_port_change_port_removed(struct team_port *port);
-static int team_port_del(struct team *team, struct net_device *port_dev)
+static int team_port_del(struct team *team, struct net_device *port_dev, bool unregister)
{
struct net_device *dev = team->dev;
struct team_port *port;
@@ -1399,7 +1399,10 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
__team_port_change_port_removed(port);
team_port_set_orig_dev_addr(port);
- dev_set_mtu(port_dev, port->orig.mtu);
+ if (unregister)
+ __dev_set_mtu(port_dev, port->orig.mtu);
+ else
+ dev_set_mtu(port_dev, port->orig.mtu);
kfree_rcu(port, rcu);
netdev_info(dev, "Port device %s removed\n", portname);
__team_compute_features(team);
@@ -1714,7 +1717,7 @@ static void team_uninit(struct net_device *dev)
mutex_lock(&team->lock);
list_for_each_entry_safe(port, tmp, &team->port_list, list)
- team_port_del(team, port->dev);
+ team_port_del(team, port->dev, false);
__team_change_mode(team, NULL); /* cleanup */
__team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
@@ -2025,13 +2028,14 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
return err;
}
-static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
+static int __team_del_slave(struct net_device *dev, struct net_device *port_dev,
+ bool unregister)
{
struct team *team = netdev_priv(dev);
int err;
mutex_lock(&team->lock);
- err = team_port_del(team, port_dev);
+ err = team_port_del(team, port_dev, unregister);
mutex_unlock(&team->lock);
if (err)
@@ -2047,6 +2051,11 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
return err;
}
+static int team_del_slave(struct net_device *dev, struct net_device *port_dev)
+{
+ return __team_del_slave(dev, port_dev, false);
+}
+
static netdev_features_t team_fix_features(struct net_device *dev,
netdev_features_t features)
{
@@ -3146,7 +3155,7 @@ static int team_device_event(struct notifier_block *unused,
!!netif_oper_up(port->dev));
break;
case NETDEV_UNREGISTER:
- team_del_slave(port->team->dev, dev);
+ __team_del_slave(port->team->dev, dev, true);
break;
case NETDEV_FEAT_CHANGE:
if (!port->team->notifier_ctx) {
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0997/1887] smb: client: prevent races in ->query_interfaces()
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (995 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0996/1887] team: avoid NETDEV_CHANGEMTU event when unregistering slave Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0998/1887] kcm: fix zero-frag skb in frag_list on partial sendmsg error Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0999/1887] vhost: move vdpa group bound check to vhost_vdpa Greg Kroah-Hartman
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henrique Carvalho, Steve French,
Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henrique Carvalho <henrique.carvalho@suse.com>
[ Upstream commit c3c06e42e1527716c54f3ad2ced6a034b5f3a489 ]
It was possible for two query interface works to be concurrently trying
to update the interfaces.
Prevent this by checking and updating iface_last_update under
iface_lock.
Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index a59df97b55282..590f8d44279a9 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -590,13 +590,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
p = buf;
spin_lock(&ses->iface_lock);
- /* do not query too frequently, this time with lock held */
- if (ses->iface_last_update &&
- time_before(jiffies, ses->iface_last_update +
- (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
- spin_unlock(&ses->iface_lock);
- return 0;
- }
/*
* Go through iface_list and mark them as inactive
@@ -727,7 +720,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
ses->iface_count++;
spin_unlock(&ses->iface_lock);
- ses->iface_last_update = jiffies;
next_iface:
nb_iface++;
next = le32_to_cpu(p->Next);
@@ -792,10 +784,17 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
struct TCP_Server_Info *pserver;
/* do not query too frequently */
+ spin_lock(&ses->iface_lock);
if (ses->iface_last_update &&
time_before(jiffies, ses->iface_last_update +
- (SMB_INTERFACE_POLL_INTERVAL * HZ)))
+ (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
+ spin_unlock(&ses->iface_lock);
return 0;
+ }
+
+ ses->iface_last_update = jiffies;
+
+ spin_unlock(&ses->iface_lock);
rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
FSCTL_QUERY_NETWORK_INTERFACE_INFO,
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0998/1887] kcm: fix zero-frag skb in frag_list on partial sendmsg error
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (996 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0997/1887] smb: client: prevent races in ->query_interfaces() Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
2026-10-28 16:51 ` [PATCH 6.1 0999/1887] vhost: move vdpa group bound check to vhost_vdpa Greg Kroah-Hartman
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+52624bdfbf2746d37d70,
Jiayuan Chen, Jakub Kicinski, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@shopee.com>
[ Upstream commit ca220141fa8ebae09765a242076b2b77338106b0 ]
Syzkaller reported a warning in kcm_write_msgs() when processing a
message with a zero-fragment skb in the frag_list.
When kcm_sendmsg() fills MAX_SKB_FRAGS fragments in the current skb,
it allocates a new skb (tskb) and links it into the frag_list before
copying data. If the copy subsequently fails (e.g. -EFAULT from
user memory), tskb remains in the frag_list with zero fragments:
head skb (msg being assembled, NOT yet in sk_write_queue)
+-----------+
| frags[17] | (MAX_SKB_FRAGS, all filled with data)
| frag_list-+--> tskb
+-----------+ +----------+
| frags[0] | (empty! copy failed before filling)
+----------+
For SOCK_SEQPACKET with partial data already copied, the error path
saves this message via partial_message for later completion. For
SOCK_SEQPACKET, sock_write_iter() automatically sets MSG_EOR, so a
subsequent zero-length write(fd, NULL, 0) completes the message and
queues it to sk_write_queue. kcm_write_msgs() then walks the
frag_list and hits:
WARN_ON(!skb_shinfo(skb)->nr_frags)
TCP has a similar pattern where skbs are enqueued before data copy
and cleaned up on failure via tcp_remove_empty_skb(). KCM was
missing the equivalent cleanup.
Fix this by tracking the predecessor skb (frag_prev) when allocating
a new frag_list entry. On error, if the tail skb has zero frags,
use frag_prev to unlink and free it in O(1) without walking the
singly-linked frag_list. frag_prev is safe to dereference because
the entire message chain is only held locally (or in kcm->seq_skb)
and is not added to sk_write_queue until MSG_EOR, so the send path
cannot free it underneath us.
Also change the WARN_ON to WARN_ON_ONCE to avoid flooding the log
if the condition is somehow hit repeatedly.
There are currently no KCM selftests in the kernel tree; a simple
reproducer is available at [1].
[1] https://gist.github.com/mrpre/a94d431c757e8d6f168f4dd1a3749daa
Reported-by: syzbot+52624bdfbf2746d37d70@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/000000000000269a1405a12fdc77@google.com/T/
Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
Link: https://patch.msgid.link/20260219014256.370092-1-jiayuan.chen@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/kcm/kcmsock.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index ab7629cee1bd0..7778a444ccb10 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -634,7 +634,7 @@ static int kcm_write_msgs(struct kcm_sock *kcm)
sent = 0;
do_frag_list:
- if (WARN_ON(!skb_shinfo(skb)->nr_frags)) {
+ if (WARN_ON_ONCE(!skb_shinfo(skb)->nr_frags)) {
ret = -EINVAL;
goto out;
}
@@ -908,7 +908,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
struct kcm_sock *kcm = kcm_sk(sk);
- struct sk_buff *skb = NULL, *head = NULL;
+ struct sk_buff *skb = NULL, *head = NULL, *frag_prev = NULL;
size_t copy, copied = 0;
long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
int eor = (sock->type == SOCK_DGRAM) ?
@@ -983,6 +983,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
else
skb->next = tskb;
+ frag_prev = skb;
skb = tskb;
skb->ip_summed = CHECKSUM_UNNECESSARY;
continue;
@@ -1070,6 +1071,22 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
out_error:
kcm_push(kcm);
+ /* When MAX_SKB_FRAGS was reached, a new skb was allocated and
+ * linked into the frag_list before data copy. If the copy
+ * subsequently failed, this skb has zero frags. Remove it from
+ * the frag_list to prevent kcm_write_msgs from later hitting
+ * WARN_ON(!skb_shinfo(skb)->nr_frags).
+ */
+ if (frag_prev && !skb_shinfo(skb)->nr_frags) {
+ if (head == frag_prev)
+ skb_shinfo(head)->frag_list = NULL;
+ else
+ frag_prev->next = NULL;
+ kfree_skb(skb);
+ /* Update skb as it may be saved in partial_message via goto */
+ skb = frag_prev;
+ }
+
if (sock->type == SOCK_SEQPACKET) {
/* Wrote some bytes before encountering an
* error, return partial success.
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread* [PATCH 6.1 0999/1887] vhost: move vdpa group bound check to vhost_vdpa
2026-10-28 16:34 [PATCH 6.1 0000/1887] 6.1.191-rc1 review Greg Kroah-Hartman
` (997 preceding siblings ...)
2026-10-28 16:51 ` [PATCH 6.1 0998/1887] kcm: fix zero-frag skb in frag_list on partial sendmsg error Greg Kroah-Hartman
@ 2026-10-28 16:51 ` Greg Kroah-Hartman
998 siblings, 0 replies; 1899+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-28 16:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Wang, Eugenio Pérez,
Michael S. Tsirkin, Sasha Levin
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugenio Pérez <eperezma@redhat.com>
[ Upstream commit cd025c1e876b4e262e71398236a1550486a73ede ]
Remove duplication by consolidating these here. This reduces the
posibility of a parent driver missing them.
While we're at it, fix a bug in vdpa_sim where a valid ASID can be
assigned to a group equal to ngroups, causing an out of bound write.
Cc: stable@vger.kernel.org
Fixes: bda324fd037a ("vdpasim: control virtqueue support")
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260119143306.1818855-2-eperezma@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/mlx5/net/mlx5_vnet.c | 3 ---
drivers/vdpa/vdpa_sim/vdpa_sim.c | 6 ------
drivers/vhost/vdpa.c | 2 +-
3 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index a599259af8632..fd4a62101a3d0 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2845,9 +2845,6 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group,
{
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
- if (group >= MLX5_VDPA_NUMVQ_GROUPS)
- return -EINVAL;
-
mvdev->group2asid[group] = asid;
return 0;
}
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index e7fc25bfdd237..74d8de5f1e8ba 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -599,12 +599,6 @@ static int vdpasim_set_group_asid(struct vdpa_device *vdpa, unsigned int group,
struct vhost_iotlb *iommu;
int i;
- if (group > vdpasim->dev_attr.ngroups)
- return -EINVAL;
-
- if (asid >= vdpasim->dev_attr.nas)
- return -EINVAL;
-
iommu = &vdpasim->iommu[asid];
spin_lock(&vdpasim->lock);
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 40c43e0611ca2..27a7a168e5bd9 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -546,7 +546,7 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
case VHOST_VDPA_SET_GROUP_ASID:
if (copy_from_user(&s, argp, sizeof(s)))
return -EFAULT;
- if (s.num >= vdpa->nas)
+ if (idx >= vdpa->ngroups || s.num >= vdpa->nas)
return -EINVAL;
if (!ops->set_group_asid)
return -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 1899+ messages in thread