From 0ab48b0841de138f4a428a6d32d3e4d3e552db53 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 18:24:44 +1100 Subject: [PATCH] mm: incorrect VM_FAULT_OOM returns from drivers Some drivers are returning OOM when it is not in response to a memory shortage. Signed-off-by: Nick Piggin --- linux-core/drm_vm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 6eb996ad..4f6a20eb 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -269,13 +269,13 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; page = vmalloc_to_page((void *)i); if (!page) - return NOPAGE_OOM; + return NOPAGE_SIGBUS; get_page(page); DRM_DEBUG("shm_nopage 0x%lx\n", address); @@ -396,7 +396,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!dma->pagelist) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ page_nr = offset >> PAGE_SHIFT; @@ -435,7 +435,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!entry->pagelist) - return NOPAGE_OOM; /* Nothing allocated */ + return NOPAGE_SIGBUS; /* Nothing allocated */ offset = address - vma->vm_start; map_offset = map->offset - (unsigned long)dev->sg->virtual; -- cgit v1.2.3 From 656c3a3737180d507bec352d56fbd9ef8b8a4feb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 18:27:20 +1100 Subject: [SPARC]: Respect vm_page_prot in io_remap_page_range(). Make sure the callers do a pgprot_noncached() on vma->vm_page_prot. Pointed out by Hugh Dickens. Signed-off-by: David S. Miller --- linux-core/drm_vm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 4f6a20eb..a65fbc73 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -829,6 +829,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_IO; /* not in core dump */ vma->vm_page_prot = drm_io_prot(map->type, vma); #ifdef __sparc__ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, (map->offset + offset) >>PAGE_SHIFT, vma->vm_end - vma->vm_start, -- cgit v1.2.3 From 86ff2aeb9bfea357d5748b3587ab224e813b37b6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 19 Dec 2006 20:29:03 +1100 Subject: drm: remove all 2.4 support for drm development tree. Bye bye 2.4 you served us well.. --- linux-core/drm_vm.c | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index a65fbc73..2bf408eb 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -446,8 +446,6 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, return page; } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) - static struct page *drm_vm_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { @@ -481,34 +479,6 @@ static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, } -#else /* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */ - -static struct page *drm_vm_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_nopage(vma, address); -} - -static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_shm_nopage(vma, address); -} - -static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_dma_nopage(vma, address); -} - -static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address, int unused) -{ - return drm_do_vm_sg_nopage(vma, address); -} - -#endif - /** AGP virtual memory operations */ static struct vm_operations_struct drm_vm_ops = { .nopage = drm_vm_nopage, @@ -712,12 +682,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) } vma->vm_ops = &drm_vm_dma_ops; - -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ -#else vma->vm_flags |= VM_RESERVED; /* Don't swap */ -#endif vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); @@ -860,20 +825,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_private_data = (void *)map; /* Don't let this area swap. Change when DRM_KERNEL advisory is supported. */ -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED; -#else vma->vm_flags |= VM_RESERVED; -#endif break; case _DRM_SCATTER_GATHER: vma->vm_ops = &drm_vm_sg_ops; vma->vm_private_data = (void *)map; -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED; -#else vma->vm_flags |= VM_RESERVED; -#endif break; case _DRM_TTM: { vma->vm_ops = &drm_vm_ttm_ops; @@ -892,11 +849,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) default: return -EINVAL; /* This should never happen. */ } -#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */ - vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ -#else vma->vm_flags |= VM_RESERVED; /* Don't swap */ -#endif vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); -- cgit v1.2.3 From 3b8e6ccd2573a027aa30c10d08253de1756540c2 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 19 Dec 2006 23:45:59 +0100 Subject: Security fix. Zero pages before they are handed to user space. TTM pages were not cleared when allocated and handed to user space. Sensitive information may leak. --- linux-core/drm_vm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 2bf408eb..f36218e9 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -220,6 +220,8 @@ struct page *drm_vm_ttm_fault(struct vm_area_struct *vma, #else SetPageReserved(page); #endif + clear_page(kmap(page)); + kunmap(page); } if (ttm->page_flags & DRM_TTM_PAGE_UNCACHED) { -- cgit v1.2.3 From 975136d6e5adc6b6a03719499cf39fbd3f67dc90 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 27 Dec 2006 15:32:09 +0100 Subject: Proper allocation of AGP pages for ttms. --- linux-core/drm_vm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index f36218e9..7ac7f3c0 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -208,7 +208,8 @@ struct page *drm_vm_ttm_fault(struct vm_area_struct *vma, data->type = VM_FAULT_OOM; goto out; } - page = ttm->pages[page_offset] = drm_alloc_gatt_pages(0); + page = ttm->pages[page_offset] = + alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); if (!page) { drm_free_memctl(PAGE_SIZE); data->type = VM_FAULT_OOM; @@ -220,8 +221,6 @@ struct page *drm_vm_ttm_fault(struct vm_area_struct *vma, #else SetPageReserved(page); #endif - clear_page(kmap(page)); - kunmap(page); } if (ttm->page_flags & DRM_TTM_PAGE_UNCACHED) { -- cgit v1.2.3 From 2dcbf6a59918761cffb27e027b1235c551ed03dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 1 Jan 2007 11:30:38 +1100 Subject: make build against 2.6.20 hopefully --- linux-core/drm_vm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 7ac7f3c0..24130162 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -159,9 +159,9 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, } #endif /* __OS_HAS_AGP */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) || \ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) || \ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) static #endif struct page *drm_vm_ttm_fault(struct vm_area_struct *vma, @@ -508,7 +508,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { .close = drm_vm_close, }; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) static struct vm_operations_struct drm_vm_ttm_ops = { .nopage = drm_vm_ttm_nopage, .open = drm_vm_ttm_open_wrapper, -- cgit v1.2.3 From b147c3926352e4dcb9dbf53b8b12baae8ce34254 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Jan 2007 10:55:49 +1100 Subject: drm: remove drm_follow_page, and drm_ioremap and ioremapfree This comes from the Re: [patch] paravirt: isolate module ops on lkml It needs some testing, please report any regressions caused. Signed-off-by: Dave Airlie --- linux-core/drm_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/drm_vm.c') diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 24130162..827a7bdb 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -349,7 +349,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) map->size); DRM_DEBUG("mtrr_del = %d\n", retcode); } - drm_ioremapfree(map->handle, map->size, dev); + iounmap(map->handle); break; case _DRM_SHM: vfree(map->handle); -- cgit v1.2.3