[openwrt/openwrt] ltq-adsl-mei: check status register before reading mailbox messages

LEDE Commits lede-commits at lists.infradead.org
Thu Jul 17 12:12:08 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/6889ea7b9a466b73f59fad9c6ae942728b907200

commit 6889ea7b9a466b73f59fad9c6ae942728b907200
Author: Jan Hoffmann <jan at 3e8.eu>
AuthorDate: Fri Jul 11 20:31:29 2025 +0200

    ltq-adsl-mei: check status register before reading mailbox messages
    
    The interrupt handler reads from the mailbox if no other reason for the
    interrupt is known. If a spurious interrupt is received just after a
    mailbox message has been sent, this means that the response to the
    previous message is read again and returned by DSL_BSP_SendCMV instead
    of the actual response.
    
    To fix this, check the status register before reading from the mailbox
    in the interrupt handler.
    
    Tested on Fritzbox 7320. Without this change, there is occasionally a
    kernel panic due to an out-of-bounds memory access in the ltq-adsl
    driver (in DSL_DRV_DEV_G997_SnrAllocationNscGet), as a result of an
    incorrect value returned by DSL_DRV_DANUBE_CmvRead. This is reproducible
    by calling "dsl_cpe_pipe.sh g997dsnrg 1 1" multiple times.
    
    Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
    Link: https://github.com/openwrt/openwrt/pull/19385
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c b/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c
index 2680e1fa86..c0fb66c5e3 100644
--- a/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c
+++ b/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c
@@ -1787,6 +1787,7 @@ extern void ifx_usb_enable_afe_oc(void);
  */
 static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
 {
+	u32 stat;
 	u32 scratch;
 	DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0;
 #if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST)
@@ -1820,6 +1821,12 @@ static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0)
                 if (dsl_bsp_event_callback[event].function)
                         (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData);
         } else { // normal message
+                IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT, &stat);
+                if (!(stat & ARC_TO_MEI_MSGAV)) {
+                        // status register indicates there is no message
+                        return IRQ_NONE;
+                }
+
                 IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH);
                 if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) {
                         DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1;




More information about the lede-commits mailing list