mm: use mm_struct to resolve gate vma's in __get_user_pages

We now check if a requested user page overlaps a gate vma using the supplied mm
instead of the supplied task.  The given task is now used solely for accounting
purposes and may be NULL.

Signed-off-by: Stephen Wilson <wilsons@start.ca>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Stephen Wilson 2011-03-13 15:49:18 -04:00 committed by Al Viro
parent cae5d39032
commit e7f22e207b
1 changed files with 11 additions and 7 deletions

View File

@ -1486,9 +1486,9 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
struct vm_area_struct *vma; struct vm_area_struct *vma;
vma = find_extend_vma(mm, start); vma = find_extend_vma(mm, start);
if (!vma && in_gate_area(tsk->mm, start)) { if (!vma && in_gate_area(mm, start)) {
unsigned long pg = start & PAGE_MASK; unsigned long pg = start & PAGE_MASK;
struct vm_area_struct *gate_vma = get_gate_vma(tsk->mm); struct vm_area_struct *gate_vma = get_gate_vma(mm);
pgd_t *pgd; pgd_t *pgd;
pud_t *pud; pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
@ -1589,10 +1589,13 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
return i ? i : -EFAULT; return i ? i : -EFAULT;
BUG(); BUG();
} }
if (ret & VM_FAULT_MAJOR)
tsk->maj_flt++; if (tsk) {
else if (ret & VM_FAULT_MAJOR)
tsk->min_flt++; tsk->maj_flt++;
else
tsk->min_flt++;
}
if (ret & VM_FAULT_RETRY) { if (ret & VM_FAULT_RETRY) {
*nonblocking = 0; *nonblocking = 0;
@ -1638,7 +1641,8 @@ EXPORT_SYMBOL(__get_user_pages);
/** /**
* get_user_pages() - pin user pages in memory * get_user_pages() - pin user pages in memory
* @tsk: task_struct of target task * @tsk: the task_struct to use for page fault accounting, or
* NULL if faults are not to be recorded.
* @mm: mm_struct of target mm * @mm: mm_struct of target mm
* @start: starting user address * @start: starting user address
* @nr_pages: number of pages from start to pin * @nr_pages: number of pages from start to pin