dma-mapping: zero memory returned from dma_alloc_*
authorChristoph Hellwig <hch@lst.de>
Fri, 14 Dec 2018 08:00:40 +0000 (09:00 +0100)
committerChristoph Hellwig <hch@lst.de>
Thu, 20 Dec 2018 07:13:52 +0000 (08:13 +0100)
If we want to map memory from the DMA allocator to userspace it must be
zeroed at allocation time to prevent stale data leaks.   We already do
this on most common architectures, but some architectures don't do this
yet, fix them up, either by passing GFP_ZERO when we use the normal page
allocator or doing a manual memset otherwise.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> [m68k]
Acked-by: Sam Ravnborg <sam@ravnborg.org> [sparc]
14 files changed:
arch/alpha/kernel/pci_iommu.c
arch/arc/mm/dma.c
arch/c6x/mm/dma-coherent.c
arch/m68k/kernel/dma.c
arch/microblaze/mm/consistent.c
arch/openrisc/kernel/dma.c
arch/parisc/kernel/pci-dma.c
arch/s390/pci/pci_dma.c
arch/sparc/kernel/ioport.c
arch/sparc/mm/io-unit.c
arch/sparc/mm/iommu.c
arch/xtensa/kernel/pci-dma.c
drivers/misc/mic/host/mic_boot.c
kernel/dma/virt.c

index e1716e0d92fdb49522a2bb8684e4452f610d7144..aa0f50d0f8237f73ec921239a509f51a6d20e167 100644 (file)
@@ -443,7 +443,7 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
        gfp &= ~GFP_DMA;
 
 try_again:
-       cpu_addr = (void *)__get_free_pages(gfp, order);
+       cpu_addr = (void *)__get_free_pages(gfp | __GFP_ZERO, order);
        if (! cpu_addr) {
                printk(KERN_INFO "pci_alloc_consistent: "
                       "get_free_pages failed from %pf\n",
index db203ff69ccfac59503c94eb6db557ed4e052710..1525ac00fd02ec67ccd694863a5154231f9ea995 100644 (file)
@@ -33,7 +33,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
         */
        BUG_ON(gfp & __GFP_HIGHMEM);
 
-       page = alloc_pages(gfp, order);
+       page = alloc_pages(gfp | __GFP_ZERO, order);
        if (!page)
                return NULL;
 
index 01305c78720108ec39f0a199eff7b0951205d7eb..75b79571732c12861f7ab4c734fc1f2d20ca341e 100644 (file)
@@ -78,6 +78,7 @@ static void __free_dma_pages(u32 addr, int order)
 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
                gfp_t gfp, unsigned long attrs)
 {
+       void *ret;
        u32 paddr;
        int order;
 
@@ -94,7 +95,9 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
        if (!paddr)
                return NULL;
 
-       return phys_to_virt(paddr);
+       ret = phys_to_virt(paddr);
+       memset(ret, 0, 1 << order);
+       return ret;
 }
 
 /*
index e99993c57d6b6c0a7fc8bfeac7fdffb4d25c06c8..b4aa853051bd41a84067fdbbeff4f78e95bd3314 100644 (file)
@@ -32,7 +32,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
        size = PAGE_ALIGN(size);
        order = get_order(size);
 
-       page = alloc_pages(flag, order);
+       page = alloc_pages(flag | __GFP_ZERO, order);
        if (!page)
                return NULL;
 
index 45e0a1aa935739cfac59134560605531490cf561..3002cbca3059b123673006d1303335b2beee4041 100644 (file)
@@ -81,7 +81,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
        size = PAGE_ALIGN(size);
        order = get_order(size);
 
-       vaddr = __get_free_pages(gfp, order);
+       vaddr = __get_free_pages(gfp | __GFP_ZERO, order);
        if (!vaddr)
                return NULL;
 
index 159336adfa2f66ff2ea2d491ce32b559a82f3ff9..f79457cb3741d7584ad8a179e9969e9b18196499 100644 (file)
@@ -89,7 +89,7 @@ arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
                .mm = &init_mm
        };
 
-       page = alloc_pages_exact(size, gfp);
+       page = alloc_pages_exact(size, gfp | __GFP_ZERO);
        if (!page)
                return NULL;
 
index 04c48f1ef3fbddcbc63ba8d52cbbe9683441cc5d..239162355b58c7d93a6d64951b470b2ee3a91e14 100644 (file)
@@ -404,7 +404,7 @@ static void *pcxl_dma_alloc(struct device *dev, size_t size,
        order = get_order(size);
        size = 1 << (order + PAGE_SHIFT);
        vaddr = pcxl_alloc_range(size);
-       paddr = __get_free_pages(flag, order);
+       paddr = __get_free_pages(flag | __GFP_ZERO, order);
        flush_kernel_dcache_range(paddr, size);
        paddr = __pa(paddr);
        map_uncached_pages(vaddr, size, paddr);
@@ -429,7 +429,7 @@ static void *pcx_dma_alloc(struct device *dev, size_t size,
        if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
                return NULL;
 
-       addr = (void *)__get_free_pages(flag, get_order(size));
+       addr = (void *)__get_free_pages(flag | __GFP_ZERO, get_order(size));
        if (addr)
                *dma_handle = (dma_addr_t)virt_to_phys(addr);
 
index 346ba382193ac5ba053c53740809873cbe54dc57..9e52d1527f71495f920a6d39989fb515410f3056 100644 (file)
@@ -404,7 +404,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
        dma_addr_t map;
 
        size = PAGE_ALIGN(size);
-       page = alloc_pages(flag, get_order(size));
+       page = alloc_pages(flag | __GFP_ZERO, get_order(size));
        if (!page)
                return NULL;
 
index baa235652c274b87a847bdfebc603a23f490ad6a..f89603855f1ec4e81381881d0839070745335336 100644 (file)
@@ -325,7 +325,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
                return NULL;
 
        size = PAGE_ALIGN(size);
-       va = (void *) __get_free_pages(gfp, get_order(size));
+       va = (void *) __get_free_pages(gfp | __GFP_ZERO, get_order(size));
        if (!va) {
                printk("%s: no %zd pages\n", __func__, size >> PAGE_SHIFT);
                return NULL;
index 91be13935d40888bc7628731dd15cdf5ccfb29a0..f770ee7229d8d07b08fe056392ee9df5cfb05792 100644 (file)
@@ -224,7 +224,7 @@ static void *iounit_alloc(struct device *dev, size_t len,
                return NULL;
 
        len = PAGE_ALIGN(len);
-       va = __get_free_pages(gfp, get_order(len));
+       va = __get_free_pages(gfp | __GFP_ZERO, get_order(len));
        if (!va)
                return NULL;
 
index fb771a634452061ee47043f3ebaf695ff31c1f6f..e8d5d73ca40d640f7e83f85964ff0151dc773df8 100644 (file)
@@ -344,7 +344,7 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
                return NULL;
 
        len = PAGE_ALIGN(len);
-       va = __get_free_pages(gfp, get_order(len));
+       va = __get_free_pages(gfp | __GFP_ZERO, get_order(len));
        if (va == 0)
                return NULL;
 
index 1fc138b6bc0a8db4ba86732ebd9658ee0cb86d12..9171bff76fc4c6767c905f4cf2a25ef5a74a4fb5 100644 (file)
@@ -160,7 +160,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
                                                 flag & __GFP_NOWARN);
 
        if (!page)
-               page = alloc_pages(flag, get_order(size));
+               page = alloc_pages(flag | __GFP_ZERO, get_order(size));
 
        if (!page)
                return NULL;
index c327985c9523be27067f2710db322e5e0afc03cc..6479435ac96bfd59768247c0928475c16a445961 100644 (file)
@@ -149,7 +149,7 @@ static void *__mic_dma_alloc(struct device *dev, size_t size,
        struct scif_hw_dev *scdev = dev_get_drvdata(dev);
        struct mic_device *mdev = scdev_to_mdev(scdev);
        dma_addr_t tmp;
-       void *va = kmalloc(size, gfp);
+       void *va = kmalloc(size, gfp | __GFP_ZERO);
 
        if (va) {
                tmp = mic_map_single(mdev, va, size);
index 631ddec4b60a8b94576b1c3a36db71a818bff5d8..ebe128833af7b55cc132a090e45c2609fb59e431 100644 (file)
@@ -13,7 +13,7 @@ static void *dma_virt_alloc(struct device *dev, size_t size,
 {
        void *ret;
 
-       ret = (void *)__get_free_pages(gfp, get_order(size));
+       ret = (void *)__get_free_pages(gfp | __GFP_ZERO, get_order(size));
        if (ret)
                *dma_handle = (uintptr_t)ret;
        return ret;