]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.30/mmc-fix-host-release-issue-after-discard-operation.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.30 / mmc-fix-host-release-issue-after-discard-operation.patch
1 From f662ae48ae67dfd42739e65750274fe8de46240a Mon Sep 17 00:00:00 2001
2 From: Ray Jui <rjui@broadcom.com>
3 Date: Sat, 26 Oct 2013 11:03:44 -0700
4 Subject: mmc: fix host release issue after discard operation
5
6 From: Ray Jui <rjui@broadcom.com>
7
8 commit f662ae48ae67dfd42739e65750274fe8de46240a upstream.
9
10 Under function mmc_blk_issue_rq, after an MMC discard operation,
11 the MMC request data structure may be freed in memory. Later in
12 the same function, the check of req->cmd_flags & MMC_REQ_SPECIAL_MASK
13 is dangerous and invalid. It causes the MMC host not to be released
14 when it should.
15
16 This patch fixes the issue by marking the special request down before
17 the discard/flush operation.
18
19 Reported by: Harold (SoonYeal) Yang <haroldsy@broadcom.com>
20 Signed-off-by: Ray Jui <rjui@broadcom.com>
21 Reviewed-by: Seungwon Jeon <tgih.jun@samsung.com>
22 Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
23 Signed-off-by: Chris Ball <cjb@laptop.org>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25
26 ---
27 drivers/mmc/card/block.c | 7 ++++---
28 1 file changed, 4 insertions(+), 3 deletions(-)
29
30 --- a/drivers/mmc/card/block.c
31 +++ b/drivers/mmc/card/block.c
32 @@ -1931,6 +1931,7 @@ static int mmc_blk_issue_rq(struct mmc_q
33 struct mmc_card *card = md->queue.card;
34 struct mmc_host *host = card->host;
35 unsigned long flags;
36 + unsigned int cmd_flags = req ? req->cmd_flags : 0;
37
38 if (req && !mq->mqrq_prev->req)
39 /* claim host only for the first request */
40 @@ -1946,7 +1947,7 @@ static int mmc_blk_issue_rq(struct mmc_q
41 }
42
43 mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
44 - if (req && req->cmd_flags & REQ_DISCARD) {
45 + if (cmd_flags & REQ_DISCARD) {
46 /* complete ongoing async transfer before issuing discard */
47 if (card->host->areq)
48 mmc_blk_issue_rw_rq(mq, NULL);
49 @@ -1955,7 +1956,7 @@ static int mmc_blk_issue_rq(struct mmc_q
50 ret = mmc_blk_issue_secdiscard_rq(mq, req);
51 else
52 ret = mmc_blk_issue_discard_rq(mq, req);
53 - } else if (req && req->cmd_flags & REQ_FLUSH) {
54 + } else if (cmd_flags & REQ_FLUSH) {
55 /* complete ongoing async transfer before issuing flush */
56 if (card->host->areq)
57 mmc_blk_issue_rw_rq(mq, NULL);
58 @@ -1971,7 +1972,7 @@ static int mmc_blk_issue_rq(struct mmc_q
59
60 out:
61 if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
62 - (req && (req->cmd_flags & MMC_REQ_SPECIAL_MASK)))
63 + (cmd_flags & MMC_REQ_SPECIAL_MASK))
64 /*
65 * Release host when there are no more requests
66 * and after special request(discard, flush) is done.