From 6e8d77cd33cae5d5aef6f0842973a49d85e29f34 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 17 Aug 2020 13:19:25 -0700 Subject: [PATCH 1/4] mhi: core: Add NULL check in mhi_get_exec_env In case power up failed due to incorrect bhi offset bhi pointer in mhi controller remains NULL. Later if MHI controller forces RDDM it checks the execution environment by accessing the BHI offset. This results into NULL pointer dereference. Fix this by adding NULL check for both mhi controller and bhi pointer before reading the BHI offset. Change-Id: I93f8918d7d595a77a5c8bcb6fd610f1a2b484fc4 Signed-off-by: Hemant Kumar --- drivers/bus/mhi/core/mhi_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 7b1b95daa6ee..dcb4b31caea8 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -244,8 +244,13 @@ static enum mhi_ee mhi_translate_dev_ee(struct mhi_controller *mhi_cntrl, enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl) { + int ret; u32 exec; - int ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_EXECENV, &exec); + + if (!mhi_cntrl || !mhi_cntrl->bhi) + return MHI_EE_MAX; + + ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_EXECENV, &exec); return (ret) ? MHI_EE_MAX : mhi_translate_dev_ee(mhi_cntrl, exec); } From c61705f68b2c704f1f3039a68cd06ccc09a2ba6b Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 17 Aug 2020 21:37:06 -0700 Subject: [PATCH 2/4] mhi: core: Skip RDDM download if execution env is unknown If mhi_get_exec_env API returns MHI_EE_MAX skip RDDM download. API returns this value if BHI offset read failed or BHI_EXECENV register read fails. This indicates the underlying transport is unresponsive so there is no need to trigger RDDM using SYSERR or request SOC reset. Change-Id: I0cc85af84f19b425c94fe8aea987ab03af6de032 Signed-off-by: Hemant Kumar --- drivers/bus/mhi/core/mhi_boot.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index 6fda43f72242..5df5ad6f985e 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -217,6 +217,9 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) * waiting for image download completion. */ ee = mhi_get_exec_env(mhi_cntrl); + if (ee == MHI_EE_MAX) + goto err_no_rddm; + if (ee != MHI_EE_RDDM) { MHI_CNTRL_LOG("Trigger device into RDDM mode using SYSERR\n"); @@ -265,10 +268,12 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) ee = mhi_get_exec_env(mhi_cntrl); ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status); - MHI_CNTRL_ERR("Did not complete RDDM transfer\n"); - MHI_CNTRL_ERR("Current EE:%s\n", TO_MHI_EXEC_STR(ee)); MHI_CNTRL_ERR("RXVEC_STATUS:0x%x, ret:%d\n", rx_status, ret); +err_no_rddm: + MHI_CNTRL_ERR("Current EE:%s\n", TO_MHI_EXEC_STR(ee)); + MHI_CNTRL_ERR("Did not complete RDDM transfer\n"); + return -EIO; } From 775e234a678d4475896e02c3afe3e4364c5c0ae3 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Wed, 20 May 2020 15:45:22 +0530 Subject: [PATCH 3/4] cnss2: Update device MMIO region length for MHI core It can be used by MHI core to have a sanity check for bhi and bhie offsets reported by device. Change-Id: Ibcdef53a4c1f7c951721cbec0b1d7285cf19cd72 Signed-off-by: Manu Gautam --- drivers/net/wireless/cnss2/pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index cba709e316e1..1257b3ffe0ec 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -4453,8 +4453,10 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) mhi_ctrl->fw_image = plat_priv->firmware_name; mhi_ctrl->regs = pci_priv->bar; - cnss_pr_dbg("BAR starts at %pa\n", - &pci_resource_start(pci_priv->pci_dev, PCI_BAR_NUM)); + mhi_ctrl->len = pci_resource_len(pci_priv->pci_dev, PCI_BAR_NUM); + cnss_pr_dbg("BAR starts at %pa, len-%x\n", + &pci_resource_start(pci_priv->pci_dev, PCI_BAR_NUM), + mhi_ctrl->len); ret = cnss_pci_get_mhi_msi(pci_priv); if (ret) { From d2796402258b70afe2bf3200bf9105e8f421d38f Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Wed, 20 May 2020 15:47:31 +0530 Subject: [PATCH 4/4] mhi: core: Add checks for bhi and bhie offsets Bail out if device returns invalid bhi/bhie offsets. Change-Id: Ifc92c53a4c1f7c951721cbec0b1d7285cf19cd72 Signed-off-by: Manu Gautam --- drivers/bus/mhi/core/mhi_pm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 61477d823742..c0017336b2a2 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -968,6 +968,13 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) goto error_bhi_offset; } + if (val >= mhi_cntrl->len) { + ret = -ENODEV; + write_unlock_irq(&mhi_cntrl->pm_lock); + MHI_ERR("Invalid bhi offset:%x\n", val); + goto error_bhi_offset; + } + mhi_cntrl->bhi = mhi_cntrl->regs + val; /* setup bhie offset if not set */ @@ -979,6 +986,13 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) goto error_bhi_offset; } + if (val >= mhi_cntrl->len) { + ret = -ENODEV; + write_unlock_irq(&mhi_cntrl->pm_lock); + MHI_ERR("Invalid bhie offset:%x\n", val); + goto error_bhi_offset; + } + mhi_cntrl->bhie = mhi_cntrl->regs + val; }