
Function bounce_buffer_start can return ENOMEM when memalign fails, but the error code is never checked.
One such failure happens when state->len_aligned is larger than the remaining free memory (set via CONFIG_SYS_MALLOC_LEN). This leaves state->bounce_buffer as a NULL. If unchecked, the tegra_mmc driver writes the entire block as a 0xFF and will continue on its way.
Let's handle this error by printing that it happened, and then return it up the chain.
This bug was discoverd during fastboot flashing of sparse images. A pointer is moved through buffered data and often needs to be DMA aligned prior to MMC write. These blocks are are often more than 4mb which is the default Tegra setting for CONFIG_SYS_MALLOC_LEN.
Signed-off-by: Michael Scott michael.scott@linaro.org Cc: Tom Warren twarren@nvidia.com Cc: Stephen Warren swarren@nvidia.com --- drivers/mmc/tegra_mmc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index ca9c4aa..5ecc2c9 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -332,7 +332,13 @@ static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } len = data->blocks * data->blocksize;
- bounce_buffer_start(&bbstate, buf, len, bbflags); + ret = bounce_buffer_start(&bbstate, buf, len, bbflags); + if (ret) { + printf("%s: bounce_buffer_start failed with error %d " + "(buf = %p, len = %u, flags = %u)\n", + __func__, ret, buf, len, bbflags); + return ret; + } }
ret = mmc_send_cmd_bounced(mmc, cmd, data, &bbstate);