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:
parent
e7f22e207b
commit
206cb63657
35
mm/memory.c
35
mm/memory.c
@ -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.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user