lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20250901-allegro-dvt-fixes-v1-2-4e4d493836ef@emfend.at>
Date: Mon, 01 Sep 2025 17:13:37 +0200
From: Matthias Fend <matthias.fend@...end.at>
To: Michael Tretter <m.tretter@...gutronix.de>, 
 Pengutronix Kernel Team <kernel@...gutronix.de>, 
 Mauro Carvalho Chehab <mchehab@...nel.org>
Cc: linux-media@...r.kernel.org, linux-kernel@...r.kernel.org, 
 Matthias Fend <matthias.fend@...end.at>
Subject: [PATCH 2/3] media: allegro: process all pending status mbox
 messages

Under certain circumstances, not every message written by the MCU to the
status mailbox may trigger a corresponding interrupt. This is likely when
multiple messages are generated in a very short period of time. Since the
current implementation only processes one message per interrupt, even if
multiple messages are already available in the mailbox, expected messages
are either not received or are processed late. This leads to various
subsequent problems and causes the driver to no longer function properly.

The behavior has been adjusted so that after an interrupt, all messages
available in the mailbox are processed.

Signed-off-by: Matthias Fend <matthias.fend@...end.at>
---
 drivers/media/platform/allegro-dvt/allegro-core.c | 42 ++++++++++++++++++-----
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
index 4c5c2a7fe5426aa81ba341aba046ef166c51f664..d3aea46b7d1d9854307d61d2f1647eaa340d504d 100644
--- a/drivers/media/platform/allegro-dvt/allegro-core.c
+++ b/drivers/media/platform/allegro-dvt/allegro-core.c
@@ -828,6 +828,20 @@ static int allegro_mbox_write(struct allegro_mbox *mbox,
 	return err;
 }
 
+static unsigned int allegro_mbox_get_available(struct allegro_mbox *mbox)
+{
+	struct regmap *sram = mbox->dev->sram;
+	unsigned int head, tail;
+
+	regmap_read(sram, mbox->head, &head);
+	regmap_read(sram, mbox->tail, &tail);
+
+	if (tail >= head)
+		return tail - head;
+	else
+		return mbox->size - (head - tail);
+}
+
 static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
 				 u32 *dst, size_t nbyte)
 {
@@ -836,11 +850,15 @@ static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
 		u16 type;
 	} __attribute__ ((__packed__)) *header;
 	struct regmap *sram = mbox->dev->sram;
-	unsigned int head;
+	unsigned int available, head;
 	ssize_t size;
 	size_t body_no_wrap;
 	int stride = regmap_get_reg_stride(sram);
 
+	available = allegro_mbox_get_available(mbox);
+	if (available < sizeof(*header))
+		return -EAGAIN;
+
 	regmap_read(sram, mbox->head, &head);
 	if (head > mbox->size)
 		return -EIO;
@@ -854,6 +872,8 @@ static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
 		return -EIO;
 	if (size > nbyte)
 		return -EINVAL;
+	if (size > available)
+		return -EAGAIN;
 
 	/*
 	 * The message might wrap within the mailbox. If the message does not
@@ -913,26 +933,27 @@ static int allegro_mbox_send(struct allegro_mbox *mbox, void *msg)
  * allegro_mbox_notify() - Notify the mailbox about a new message
  * @mbox: The allegro_mbox to notify
  */
-static void allegro_mbox_notify(struct allegro_mbox *mbox)
+static int allegro_mbox_notify(struct allegro_mbox *mbox)
 {
 	struct allegro_dev *dev = mbox->dev;
 	union mcu_msg_response *msg;
-	ssize_t size;
 	u32 *tmp;
 	int err;
 
 	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
 	if (!msg)
-		return;
+		return -ENOMEM;
 
 	msg->header.version = dev->fw_info->mailbox_version;
 
 	tmp = kmalloc(mbox->size, GFP_KERNEL);
-	if (!tmp)
+	if (!tmp) {
+		err = -ENOMEM;
 		goto out;
+	}
 
-	size = allegro_mbox_read(mbox, tmp, mbox->size);
-	if (size < 0)
+	err = allegro_mbox_read(mbox, tmp, mbox->size);
+	if (err < 0)
 		goto out;
 
 	err = allegro_decode_mail(msg, tmp);
@@ -944,6 +965,8 @@ static void allegro_mbox_notify(struct allegro_mbox *mbox)
 out:
 	kfree(tmp);
 	kfree(msg);
+
+	return err;
 }
 
 static int allegro_encoder_buffer_init(struct allegro_dev *dev,
@@ -2326,7 +2349,10 @@ static irqreturn_t allegro_irq_thread(int irq, void *data)
 	if (!dev->mbox_status)
 		return IRQ_NONE;
 
-	allegro_mbox_notify(dev->mbox_status);
+	while (allegro_mbox_get_available(dev->mbox_status) > 0) {
+		if (allegro_mbox_notify(dev->mbox_status))
+			break;
+	}
 
 	return IRQ_HANDLED;
 }

-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ