summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2016-06-17 18:44:14 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-21 15:14:34 -0700
commit479ce8b7e82a3814e53a5ad41082bb537b990de7 (patch)
tree687c17495f331c5f204f909f33f667ac0e91928f /drivers
parent3351162b699c4c0e10fa734e70e0626a28efada6 (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.c7
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) {
/*