From bd363955aba7c59653b92e3bd1a1d4850d70dfdf Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Thu, 16 Oct 2014 10:43:00 +0530 Subject: [PATCH] mmc: core: Fix unclocked access in get_xfer_remain/stop_request The unclocked access could happen in the following scenario - 1. mmcqd thread is waiting for previously submitted io to be done 2. before this io is done, it is woken up due to is_urgent event 3. mmcqd thread is running and is processing the is_urgent event 4. Just about the same time the previously submitted io is done and it sets is_done_rcv flag, tries to wake up mmcqd thread and release host clock so as to gate the clocks. If step 3 and 4 happen at the same time, then clocks will be gated off before is_urgent is completely handled. Hence, make sure to hold the clock before invoking get_xfer_remain and stop_request host->op. Change-Id: If03177bf5e28cc217cc8e86b10d81d4adbab78b9 Signed-off-by: Sahitya Tummala --- drivers/mmc/core/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index da62cb0837b..939379f1165 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -616,8 +616,10 @@ static bool mmc_should_stop_curr_req(struct mmc_host *host) (host->areq->cmd_flags & REQ_FUA)) return false; + mmc_host_clk_hold(host); remainder = (host->ops->get_xfer_remain) ? host->ops->get_xfer_remain(host) : -1; + mmc_host_clk_release(host); return (remainder > 0); } @@ -642,6 +644,7 @@ static int mmc_stop_request(struct mmc_host *host) mmc_hostname(host)); return -ENOTSUPP; } + mmc_host_clk_hold(host); err = host->ops->stop_request(host); if (err) { pr_err("%s: Call to host->ops->stop_request() failed (%d)\n", @@ -676,6 +679,7 @@ static int mmc_stop_request(struct mmc_host *host) goto out; } out: + mmc_host_clk_release(host); return err; }