summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Hoffmann2025-07-11 18:31:29 +0000
committerHauke Mehrtens2025-08-24 13:30:57 +0000
commitba7b5d23f6977a65613ee32c28c2190cd01b485e (patch)
treed93aa6af037f92b6041f88001be51804d1993a9d
parente627539601d61099970ff41317f34dbc74342c75 (diff)
downloadopenwrt-ba7b5d23f6977a65613ee32c28c2190cd01b485e.tar.gz
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@3e8.eu> Link: https://github.com/openwrt/openwrt/pull/19385 (cherry picked from commit 6889ea7b9a466b73f59fad9c6ae942728b907200) Link: https://github.com/openwrt/openwrt/pull/19839 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-rw-r--r--package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c7
1 files changed, 7 insertions, 0 deletions
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 20a63716a3..5ee5b70b47 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;