Commit ba493464 authored by Ingo Molnar's avatar Ingo Molnar

- fix mapped-pte usage - do not access it after unmapping.

parent 971027a8
...@@ -68,7 +68,7 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, ...@@ -68,7 +68,7 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
unsigned long pages, i, j; unsigned long pages, i, j;
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte, pte_entry;
DRM_DEBUG( "%s\n", __FUNCTION__ ); DRM_DEBUG( "%s\n", __FUNCTION__ );
...@@ -144,18 +144,17 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, ...@@ -144,18 +144,17 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
goto failed; goto failed;
preempt_disable(); preempt_disable();
pte = pte_offset_map( pmd, i ); pte = pte_offset_map(pmd, i);
if ( !pte_present( *pte ) ) { pte_entry = *pte;
pte_unmap(pte); pte_unmap(pte);
preempt_enable(); preempt_enable();
if (!pte_present(pte_entry))
goto failed; goto failed;
}
pte_unmap(pte);
preempt_enable();
entry->pagelist[j] = pte_page( *pte ); entry->pagelist[j] = pte_page(pte_entry);
SetPageReserved( entry->pagelist[j] ); SetPageReserved(entry->pagelist[j]);
} }
request.handle = entry->handle; request.handle = entry->handle;
......
...@@ -154,7 +154,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, ...@@ -154,7 +154,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long i; unsigned long i;
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte, entry;
struct page *page; struct page *page;
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
...@@ -166,20 +166,22 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, ...@@ -166,20 +166,22 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
* they need to be virtually contiguous in kernel space. * they need to be virtually contiguous in kernel space.
*/ */
pgd = pgd_offset_k( i ); pgd = pgd_offset_k( i );
if( !pgd_present( *pgd ) ) return NOPAGE_OOM; if (!pgd_present(*pgd))
goto oom;
pmd = pmd_offset( pgd, i ); pmd = pmd_offset( pgd, i );
if( !pmd_present( *pmd ) ) return NOPAGE_OOM; if (!pmd_present(*pmd))
goto oom;
preempt_disable(); preempt_disable();
pte = pte_offset_map( pmd, i ); pte = pte_offset_map(pmd, i);
if( !pte_present( *pte ) ) { entry = *pte;
pte_unmap(pte);
preempt_enable();
return NOPAGE_OOM;
}
pte_unmap(pte); pte_unmap(pte);
preempt_enable(); preempt_enable();
page = pte_page(*pte); if (!pte_present(entry))
goto oom;
page = pte_page(entry);
get_page(page); get_page(page);
DRM_DEBUG("shm_nopage 0x%lx\n", address); DRM_DEBUG("shm_nopage 0x%lx\n", address);
...@@ -188,6 +190,8 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, ...@@ -188,6 +190,8 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
#else #else
return page; return page;
#endif #endif
oom:
return NOPAGE_OOM;
} }
/* Special close routine which deletes map information if we are the last /* Special close routine which deletes map information if we are the last
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment