]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Jun 2026 07:23:43 +0000 (09:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Jun 2026 07:23:43 +0000 (09:23 +0200)
added patches:
mailbox-fix-null-message-support-in-mbox_send_message.patch

queue-7.0/mailbox-fix-null-message-support-in-mbox_send_message.patch [new file with mode: 0644]
queue-7.0/series

diff --git a/queue-7.0/mailbox-fix-null-message-support-in-mbox_send_message.patch b/queue-7.0/mailbox-fix-null-message-support-in-mbox_send_message.patch
new file mode 100644 (file)
index 0000000..4f6197f
--- /dev/null
@@ -0,0 +1,160 @@
+From c58e9456e30c7098cbcd9f04571992be8a2e4e63 Mon Sep 17 00:00:00 2001
+From: Jassi Brar <jassisinghbrar@gmail.com>
+Date: Fri, 27 Mar 2026 17:00:40 -0500
+Subject: mailbox: Fix NULL message support in mbox_send_message()
+
+From: Jassi Brar <jassisinghbrar@gmail.com>
+
+commit c58e9456e30c7098cbcd9f04571992be8a2e4e63 upstream.
+
+The active_req field serves double duty as both the "is a TX in
+flight" flag (NULL means idle) and the storage for the in-flight
+message pointer. When a client sends NULL via mbox_send_message(),
+active_req is set to NULL, which the framework misinterprets as
+"no active request". This breaks the TX state machine by:
+
+ - tx_tick() short-circuits on (!mssg), skipping the tx_done
+   callback and the tx_complete completion
+ - txdone_hrtimer() skips the channel entirely since active_req
+   is NULL, so poll-based TX-done detection never fires.
+
+Fix this by introducing a MBOX_NO_MSG sentinel value that means
+"no active request," freeing NULL to be valid message data. The
+sentinel is defined in the subsystem-internal mailbox.h so that
+controller drivers within drivers/mailbox/ can reference it, but
+it is not exposed to clients outside the subsystem.
+
+Fifteen in-tree callers send NULL (doorbell-style IPCs on Qualcomm,
+Tegra, TI, Xilinx, i.MX, SCMI, and PCC platforms). All were
+audited for regression:
+
+ - Most already work around the bug via knows_txdone=true with a
+   manual mbox_client_txdone() call, making the framework's
+   tracking irrelevant. These are unaffected.
+
+ - Poll-based callers (Xilinx zynqmp/r5) are strictly better off:
+   the poll timer now correctly detects NULL-active channels
+   instead of silently skipping them.
+
+ - irq-qcom-mpm.c was a pre-existing bug -- the only Qualcomm
+   caller that omitted the knows_txdone + mbox_client_txdone()
+   pattern. Fixed in a companion commit ("irqchip/qcom-mpm: Fix
+   missing mailbox TX done acknowledgment").
+
+ - No caller sets both a tx_done callback and sends NULL, nor
+   combines tx_block=true with NULL sends, so the newly reachable
+   callback/completion paths are never exercised.
+
+Also update tegra-hsp's flush callback, which directly inspects
+active_req to wait for the channel to drain: the old "!= NULL"
+check becomes "!= MBOX_NO_MSG", otherwise flush spins until
+timeout since the sentinel is non-NULL.
+
+The only tradeoff is that 'MBOX_NO_MSG' can not be used as a message
+by clients.
+
+Reported-by: Joonwon Kang <joonwonkang@google.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Joonwon Kang <joonwonkang@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mailbox/mailbox.c          |   15 ++++++++-------
+ drivers/mailbox/tegra-hsp.c        |    2 +-
+ include/linux/mailbox_controller.h |    3 +++
+ 3 files changed, 12 insertions(+), 8 deletions(-)
+
+--- a/drivers/mailbox/mailbox.c
++++ b/drivers/mailbox/mailbox.c
+@@ -52,7 +52,7 @@ static void msg_submit(struct mbox_chan
+       int err = -EBUSY;
+       scoped_guard(spinlock_irqsave, &chan->lock) {
+-              if (!chan->msg_count || chan->active_req)
++              if (!chan->msg_count || chan->active_req != MBOX_NO_MSG)
+                       break;
+               count = chan->msg_count;
+@@ -87,13 +87,13 @@ static void tx_tick(struct mbox_chan *ch
+       scoped_guard(spinlock_irqsave, &chan->lock) {
+               mssg = chan->active_req;
+-              chan->active_req = NULL;
++              chan->active_req = MBOX_NO_MSG;
+       }
+       /* Submit next message */
+       msg_submit(chan);
+-      if (!mssg)
++      if (mssg == MBOX_NO_MSG)
+               return;
+       /* Notify the client */
+@@ -114,7 +114,7 @@ static enum hrtimer_restart txdone_hrtim
+       for (i = 0; i < mbox->num_chans; i++) {
+               struct mbox_chan *chan = &mbox->chans[i];
+-              if (chan->active_req && chan->cl) {
++              if (chan->active_req != MBOX_NO_MSG && chan->cl) {
+                       txdone = chan->mbox->ops->last_tx_done(chan);
+                       if (txdone)
+                               tx_tick(chan, 0);
+@@ -246,7 +246,7 @@ int mbox_send_message(struct mbox_chan *
+ {
+       int t;
+-      if (!chan || !chan->cl)
++      if (!chan || !chan->cl || mssg == MBOX_NO_MSG)
+               return -EINVAL;
+       t = add_to_rbuf(chan, mssg);
+@@ -319,7 +319,7 @@ static int __mbox_bind_client(struct mbo
+       scoped_guard(spinlock_irqsave, &chan->lock) {
+               chan->msg_free = 0;
+               chan->msg_count = 0;
+-              chan->active_req = NULL;
++              chan->active_req = MBOX_NO_MSG;
+               chan->cl = cl;
+               init_completion(&chan->tx_complete);
+@@ -477,7 +477,7 @@ void mbox_free_channel(struct mbox_chan
+       /* The queued TX requests are simply aborted, no callbacks are made */
+       scoped_guard(spinlock_irqsave, &chan->lock) {
+               chan->cl = NULL;
+-              chan->active_req = NULL;
++              chan->active_req = MBOX_NO_MSG;
+               if (chan->txdone_method == TXDONE_BY_ACK)
+                       chan->txdone_method = TXDONE_BY_POLL;
+       }
+@@ -531,6 +531,7 @@ int mbox_controller_register(struct mbox
+               chan->cl = NULL;
+               chan->mbox = mbox;
++              chan->active_req = MBOX_NO_MSG;
+               chan->txdone_method = txdone;
+               spin_lock_init(&chan->lock);
+       }
+--- a/drivers/mailbox/tegra-hsp.c
++++ b/drivers/mailbox/tegra-hsp.c
+@@ -497,7 +497,7 @@ static int tegra_hsp_mailbox_flush(struc
+                       mbox_chan_txdone(chan, 0);
+                       /* Wait until channel is empty */
+-                      if (chan->active_req != NULL)
++                      if (chan->active_req != MBOX_NO_MSG)
+                               continue;
+                       return 0;
+--- a/include/linux/mailbox_controller.h
++++ b/include/linux/mailbox_controller.h
+@@ -11,6 +11,9 @@
+ struct mbox_chan;
++/* Sentinel value distinguishing "no active request" from "NULL message data" */
++#define MBOX_NO_MSG   ((void *)-1)
++
+ /**
+  * struct mbox_chan_ops - methods to control mailbox channels
+  * @send_data:        The API asks the MBOX controller driver, in atomic
index 13f68c95ad854d9be8202ae61bfddc7e4689db1b..861044e428803678ac8351795c18daf612723bde 100644 (file)
@@ -329,3 +329,4 @@ hwmon-pmbus-adm1266-serialize-sequencer_state-debugfs-read-with-pmbus_lock.patch
 hwmon-pmbus-adm1266-serialize-gpio-pmbus-accesses-with-pmbus_lock.patch
 net-phy-micrel-fix-lan8814-qsgmii-soft-reset.patch
 xhci-tegra-fix-ghost-usb-device-on-dual-role-port-un.patch
+mailbox-fix-null-message-support-in-mbox_send_message.patch