mm: factor out main logic of access_process_vm

Introduce an internal helper __access_remote_vm and base access_process_vm on
top of it.  This new method may be called with a NULL task_struct if page fault
accounting is not desired.  This code will be shared with a new address space
accessor that is independent of task_struct.

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:19 -04:00 committed by Al Viro
parent e7f22e207b
commit 206cb63657

View file

@ -3650,20 +3650,15 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
#endif #endif
/* /*
* Access another process' address space. * Access another process' address space as given in mm. If non-NULL, use the
* Source/target buffer must be kernel space, * given task for page fault accounting.
* Do not walk the page table directly, use get_user_pages
*/ */
int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
unsigned long addr, void *buf, int len, int write)
{ {
struct mm_struct *mm;
struct vm_area_struct *vma; struct vm_area_struct *vma;
void *old_buf = buf; void *old_buf = buf;
mm = get_task_mm(tsk);
if (!mm)
return 0;
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
/* ignore errors, just check how much was successfully transferred */ /* ignore errors, just check how much was successfully transferred */
while (len) { while (len) {
@ -3712,11 +3707,31 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
addr += bytes; addr += bytes;
} }
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
mmput(mm);
return buf - old_buf; return buf - old_buf;
} }
/*
* Access another process' address space.
* Source/target buffer must be kernel space,
* Do not walk the page table directly, use get_user_pages
*/
int access_process_vm(struct task_struct *tsk, unsigned long addr,
void *buf, int len, int write)
{
struct mm_struct *mm;
int ret;
mm = get_task_mm(tsk);
if (!mm)
return 0;
ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
mmput(mm);
return ret;
}
/* /*
* Print the name of a VMA. * Print the name of a VMA.
*/ */