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 e1716e0..aa0f50d 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 db203ff..1525ac0 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 01305c7..75b7957 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 e99993c..b4aa853 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 45e0a1a..3002cbc 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 159336a..f79457c 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 04c48f1..2391623 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 346ba38..9e52d15 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 baa2356..f896038 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 91be139..f770ee7 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 fb771a6..e8d5d73 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 1fc138b..9171bff 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 c327985..6479435 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 631ddec..ebe1288 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;