From: Ben Hutchings Date: Wed, 29 Nov 2017 19:54:22 +0000 (+0000) Subject: mmc: sdio: Avoid ABI change in 4.9.54 X-Git-Tag: archive/raspbian/4.9.80-2+rpi1~8^2~14 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=39ca92576c5bf387a50b6f6de484e16f9caa8417;p=linux-4.9.git mmc: sdio: Avoid ABI change in 4.9.54 Commit 5ef1ecf060f2 "mmc: sdio: fix alignment issue in struct sdio_func" changed the type of sdio_func::tmpbuf from array to pointer. On 64-bit architectures this also changes the size of the field. It appears that tmpbuf is only used by the MMC core, and the structure is always allocated there. So put padding in the old position, move the pointer to the end of the structure, and hide this from genksyms. Just in case I missed a user elsewhere, which might end up accessing memory off the end of an old structure, rename the field to core_tmpbuf (and update its users in the core). Gbp-Pq: Topic debian Gbp-Pq: Name mmc-sdio-avoid-abi-change-in-4.9.54.patch --- diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d56a3b6c2fb9..90cd2763c4bc 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -266,7 +266,7 @@ static void sdio_release_func(struct device *dev) sdio_free_func_cis(func); kfree(func->info); - kfree(func->tmpbuf); + kfree(func->core_tmpbuf); kfree(func); } @@ -285,8 +285,8 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) * allocate buffer separately to make sure it's properly aligned for * DMA usage (incl. 64 bit DMA) */ - func->tmpbuf = kmalloc(4, GFP_KERNEL); - if (!func->tmpbuf) { + func->core_tmpbuf = kmalloc(4, GFP_KERNEL); + if (!func->core_tmpbuf) { kfree(func); return ERR_PTR(-ENOMEM); } diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 406e5f037e32..cff38d49565c 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -530,14 +530,14 @@ u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret) if (err_ret) *err_ret = 0; - ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2); + ret = sdio_memcpy_fromio(func, func->core_tmpbuf, addr, 2); if (ret) { if (err_ret) *err_ret = ret; return 0xFFFF; } - return le16_to_cpup((__le16 *)func->tmpbuf); + return le16_to_cpup((__le16 *)func->core_tmpbuf); } EXPORT_SYMBOL_GPL(sdio_readw); @@ -556,9 +556,9 @@ void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret) { int ret; - *(__le16 *)func->tmpbuf = cpu_to_le16(b); + *(__le16 *)func->core_tmpbuf = cpu_to_le16(b); - ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2); + ret = sdio_memcpy_toio(func, addr, func->core_tmpbuf, 2); if (err_ret) *err_ret = ret; } @@ -582,14 +582,14 @@ u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret) if (err_ret) *err_ret = 0; - ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4); + ret = sdio_memcpy_fromio(func, func->core_tmpbuf, addr, 4); if (ret) { if (err_ret) *err_ret = ret; return 0xFFFFFFFF; } - return le32_to_cpup((__le32 *)func->tmpbuf); + return le32_to_cpup((__le32 *)func->core_tmpbuf); } EXPORT_SYMBOL_GPL(sdio_readl); @@ -608,9 +608,9 @@ void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret) { int ret; - *(__le32 *)func->tmpbuf = cpu_to_le32(b); + *(__le32 *)func->core_tmpbuf = cpu_to_le32(b); - ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4); + ret = sdio_memcpy_toio(func, addr, func->core_tmpbuf, 4); if (err_ret) *err_ret = ret; } diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 97ca105347a6..73ad0594215f 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -53,12 +53,21 @@ struct sdio_func { unsigned int state; /* function state */ #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ - u8 *tmpbuf; /* DMA:able scratch buffer */ +#ifndef __GENKSYMS__ + u8 pad_tmpbuf[4]; +#else + u8 tmpbuf[4]; +#endif unsigned num_info; /* number of info strings */ const char **info; /* info strings */ struct sdio_func_tuple *tuples; + +#ifndef __GENKSYMS__ + u8 *core_tmpbuf; /* DMA:able scratch buffer + * for SDIO core use */ +#endif }; #define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT)