diff options
author | Subhash Jadavani <subhashj@codeaurora.org> | 2016-06-17 18:44:14 -0700 |
---|---|---|
committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-21 15:14:34 -0700 |
commit | 479ce8b7e82a3814e53a5ad41082bb537b990de7 (patch) | |
tree | 687c17495f331c5f204f909f33f667ac0e91928f /drivers | |
parent | 3351162b699c4c0e10fa734e70e0626a28efada6 (diff) |
mmc: host: sdhci-msm: fix NULL pointer dereference
We are seeing the kernel panic due to NULL pointer dereference with
following call trace:
sdhci_msm_set_clock+0x59c/0xa28
sdhci_do_set_ios+0xf4/0x740
sdhci_set_ios+0x28/0x3c
mmc_set_ios+0xac/0x1ec
__mmc_set_clock+0x2c/0x3c
mmc_ungate_clock+0x20/0x28
mmc_host_clk_hold+0x54/0xc4
mmc_power_off+0x1c/0x70
mmc_rescan+0x250/0x27c
process_one_work+0x240/0x420
worker_thread+0x268/0x390
kthread+0xf8/0x100
This is happending when eMMC initialization is failing in HS400 mode.
sdhci_msm_set_clock() might be accessing the card pointer after it
was deallocated, this change adds the safety checks to avoid NULL
dereference.
Change-Id: I895b8b33cce4173100d58acf690e57b5f4e69081
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/sdhci-msm.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 68427bf47ca6..0568769fd94a 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2809,6 +2809,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) int rc; struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = pltfm_host->priv; + struct mmc_card *card = host->mmc->card; struct mmc_ios curr_ios = host->mmc->ios; u32 sup_clock, ddr_clock, dll_lock; bool curr_pwrsave; @@ -2832,7 +2833,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) curr_pwrsave = !!(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) & CORE_CLK_PWRSAVE); if ((clock > 400000) && - !curr_pwrsave && mmc_host_may_gate_card(host->mmc->card)) + !curr_pwrsave && card && mmc_host_may_gate_card(card)) writel_relaxed(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) | CORE_CLK_PWRSAVE, host->ioaddr + CORE_VENDOR_SPEC); @@ -2840,7 +2841,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) * Disable pwrsave for a newly added card if doesn't allow clock * gating. */ - else if (curr_pwrsave && !mmc_host_may_gate_card(host->mmc->card)) + else if (curr_pwrsave && card && !mmc_host_may_gate_card(card)) writel_relaxed(readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) & ~CORE_CLK_PWRSAVE, host->ioaddr + CORE_VENDOR_SPEC); @@ -2888,7 +2889,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) * register */ if ((msm_host->tuning_done || - (mmc_card_strobe(msm_host->mmc->card) && + (card && mmc_card_strobe(card) && msm_host->enhanced_strobe)) && !msm_host->calibration_done) { /* |