mmc: sdio: Avoid ABI change in 4.9.54
authorBen Hutchings <ben@decadent.org.uk>
Wed, 29 Nov 2017 19:54:22 +0000 (19:54 +0000)
committerYves-Alexis Perez <corsac@debian.org>
Fri, 9 Feb 2018 12:58:52 +0000 (12:58 +0000)
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

drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_io.c
include/linux/mmc/sdio_func.h

index d56a3b6c2fb9db689e329fc5aa91b720eaa9788b..90cd2763c4bc8981e67d16c55f2dc2fc39f3f3df 100644 (file)
@@ -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);
        }
index 406e5f037e3203618e2997498df58110563e19d6..cff38d49565c4d9b02a5e4cc6b89f8bb667ca24e 100644 (file)
@@ -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;
 }
index 97ca105347a6c5e608297ae1a3562925dc6f6834..73ad0594215f0d259a92c61b85ccbdea8bda0e27 100644 (file)
@@ -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)