3.16.57-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin shawn.lin@rock-chips.com
commit 0d84b9e5631d923744767dc6608672df906dd092 upstream.
Add num_caps field for dw_mci_drv_data to validate the controller id from DT alias and non-DT ways.
Reported-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Shawn Lin shawn.lin@rock-chips.com Fixes: 800d78bfccb3 ("mmc: dw_mmc: add support for implementation specific callbacks") Signed-off-by: Ulf Hansson ulf.hansson@linaro.org [bwh: Backported to 3.16: - Drop changes to dw_mmc-{k3,rockchip,zx}.c - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -394,6 +394,7 @@ static unsigned long exynos_dwmmc_caps[4
static const struct dw_mci_drv_data exynos_drv_data = { .caps = exynos_dwmmc_caps, + .num_caps = ARRAY_SIZE(exynos_dwmmc_caps), .init = dw_mci_exynos_priv_init, .setup_clock = dw_mci_exynos_setup_clock, .prepare_command = dw_mci_exynos_prepare_command, --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2064,8 +2064,15 @@ static int dw_mci_init_slot_caps(struct } else { ctrl_id = to_platform_device(host->dev)->id; } - if (drv_data && drv_data->caps) + + if (drv_data && drv_data->caps) { + if (ctrl_id >= drv_data->num_caps) { + dev_err(host->dev, "invalid controller id %d\n", + ctrl_id); + return -EINVAL; + } mmc->caps |= drv_data->caps[ctrl_id]; + }
if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -237,6 +237,7 @@ struct dw_mci_tuning_data { /** * dw_mci driver data - dw-mshc implementation specific driver data. * @caps: mmc subsystem specified capabilities of the controller(s). + * @num_caps: number of capabilities specified by @caps. * @init: early implementation specific initialization. * @setup_clock: implementation specific clock configuration. * @prepare_command: handle CMD register extensions. @@ -250,6 +251,7 @@ struct dw_mci_tuning_data { */ struct dw_mci_drv_data { unsigned long *caps; + u32 num_caps; int (*init)(struct dw_mci *host); int (*setup_clock)(struct dw_mci *host); void (*prepare_command)(struct dw_mci *host, u32 *cmdr);