--- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -441,6 +441,7 @@ int dma_direct_mmap(struct device *dev, unsigned long user_count = vma_pages(vma); unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; unsigned long pfn = PHYS_PFN(dma_to_phys(dev, dma_addr)); + unsigned long pa; int ret = -ENXIO; vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs); @@ -450,6 +451,17 @@ int dma_direct_mmap(struct device *dev, if (vma->vm_pgoff >= count || user_count > count - vma->vm_pgoff) return -ENXIO; + + if (pfn > pfn + vma->vm_pgoff) + return -ENXIO; + + pa = (pfn + vma->vm_pgoff) << PAGE_SHIFT; + if (pa < (pfn << PAGE_SHIFT)) + return -ENXIO; + + if (pa > pa + (user_count << PAGE_SHIFT)) + return -ENXIO; + return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, user_count << PAGE_SHIFT, vma->vm_page_prot); }