diff options
author | Chuansheng Liu <chuansheng.liu@intel.com> | 2013-11-05 01:52:45 -0500 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2014-01-13 12:48:13 -0500 |
commit | 63c211803a272d59dcb11af82ad0364b3d1d2a2e (patch) | |
tree | 5c0884f4ded5994df5a09501a3ec4be7058b1f3e /drivers/mmc/host | |
parent | 00411135474264ce74310d2a7f7017885dd41545 (diff) |
mmc: sdhci: Setting the host->mrq to NULL before executing tuning
In function sdhci_request(), it is possible to do the tuning execution
like below:
sdhci_request() {
spin_lock_irqsave(&host->lock, flags);
host->mrq = mrq;
...
spin_unlock_irqrestore(&host->lock, flags);
<=== Here it is possible one pending finish_tasklet get running
and it will operate the original mrq, and notified the mrq
is done, and causes memory corruption.
sdhci_execute_tuning(mmc, tuning_opcode);
spin_lock_irqsave(&host->lock, flags);
host->mrq = mrq;
...
}
In the above race place, the original mrq should not be finished wrongly,
so here before unlock the spinlock, we need to set the host->mrq to NULL
to avoid this case.
Signed-off-by: Liu, Chuansheng <chuansheng.liu@intel.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6840322c12a0..cc00bed3e200 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1396,6 +1396,13 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1396 | mmc->card->type == MMC_TYPE_MMC ? | 1396 | mmc->card->type == MMC_TYPE_MMC ? |
1397 | MMC_SEND_TUNING_BLOCK_HS200 : | 1397 | MMC_SEND_TUNING_BLOCK_HS200 : |
1398 | MMC_SEND_TUNING_BLOCK; | 1398 | MMC_SEND_TUNING_BLOCK; |
1399 | |||
1400 | /* Here we need to set the host->mrq to NULL, | ||
1401 | * in case the pending finish_tasklet | ||
1402 | * finishes it incorrectly. | ||
1403 | */ | ||
1404 | host->mrq = NULL; | ||
1405 | |||
1399 | spin_unlock_irqrestore(&host->lock, flags); | 1406 | spin_unlock_irqrestore(&host->lock, flags); |
1400 | sdhci_execute_tuning(mmc, tuning_opcode); | 1407 | sdhci_execute_tuning(mmc, tuning_opcode); |
1401 | spin_lock_irqsave(&host->lock, flags); | 1408 | spin_lock_irqsave(&host->lock, flags); |