Commit 206cb636 authored by Stephen Wilson's avatar Stephen Wilson Committed by Al Viro

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: default avatarStephen Wilson <wilsons@start.ca>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e7f22e20
...@@ -3650,20 +3650,15 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, ...@@ -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 ...@@ -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.
*/ */
......
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