lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1296724233-3903-1-git-send-email-jon.povey@racelogic.co.uk>
Date:	Thu,  3 Feb 2011 18:10:33 +0900
From:	Jon Povey <jon.povey@...elogic.co.uk>
To:	davinci-linux-open-source@...ux.davincidsp.com
Cc:	gilles.chanteperdrix@...vision.fr,
	Jon Povey <jon.povey@...elogic.co.uk>,
	Chris Ball <cjb@...top.org>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Kevin Hilman <khilman@...prootsystems.com>,
	Chaithrika U S <chaithrika@...com>,
	Anton Vorontsov <cbouatmailru@...il.com>,
	linux-mmc@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [RFC] mmc: davinci: fix corruption after surprise card eject

Ejecting a card during a write results in a bad controller state which
corrupts all writes to subsequently inserted cards.

Work around this by resetting the controller in the set_ios() POWER_OFF
handler.

Tested on DM355.

Signed-off-by: Jon Povey <jon.povey@...elogic.co.uk>
---

This patch is against 2.6.36, it does not include the latest SDIO patch
at least.

To reproduce this in the unpatched sources, write heavily to the card
and eject it during a write. Note that for the first few seconds of
"writing a file" nothing is actually written to the card, it is cached
by Linux.

In the broken state that results, if a card is reinserted, the effect
is as if an internal write FIFO has not been cleared and contains 2
extra bytes. Tests suggest this is not the documented 32-byte FIFO but
something beyond that.
All blocks appear on the card starting with the last two bytes of the
previous block write, then the remaining sector data; the last two
bytes overflow into the next written sector, etc.

Toggling MMCCTL.CMDRST,DATRST clears this condition. These are toggled
several times during the error handlers called when the card is ejected
during write, but it seems the bad state is entered at some point later.

set_ios(MMC_POWER_OFF) seems to consistently be called at the end of
the cleanup process before a newly-inserted card is accessed, putting
an extra controller reset in here gets rid of the problem - but I'm not
sure this is the right way to fix this, it has a workaround feel.

Comments sought.. thanks.

---
 drivers/mmc/host/davinci_mmc.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 33d9f1b..e5ee1c1 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -795,6 +795,9 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
 	}
 }
 
+static void
+davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data);
+
 static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmc_davinci_host *host = mmc_priv(mmc);
@@ -856,9 +859,14 @@ static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 		if (lose)
 			dev_warn(mmc_dev(host->mmc), "powerup timeout\n");
-	}
 
-	/* FIXME on power OFF, reset things ... */
+	} else if (ios->power_mode == MMC_POWER_OFF) {
+
+		/* Controller maybe in bad state, e.g. card pulled while writing */
+		davinci_abort_data(host, NULL);
+
+		/* FIXME on power OFF, reset more things ...? */
+	}
 }
 
 static void
-- 
1.6.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ