aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorStephen Wilson <wilsons@start.ca>2011-03-13 15:49:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-23 16:36:56 -0400
commit206cb636576b969e9b471cdedeaea7752e6acb33 (patch)
tree252a1b5e9ce41521fb93b519265d4a1dbd18cfe9 /mm
parente7f22e207bacdba5b73f2893a3abe935a5373e2e (diff)
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>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 5f585b65d734..820b4c4810f0 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3650,20 +3650,15 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
3650#endif 3650#endif
3651 3651
3652/* 3652/*
3653 * Access another process' address space. 3653 * Access another process' address space as given in mm. If non-NULL, use the
3654 * Source/target buffer must be kernel space, 3654 * given task for page fault accounting.
3655 * Do not walk the page table directly, use get_user_pages
3656 */ 3655 */
3657int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) 3656static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
3657 unsigned long addr, void *buf, int len, int write)
3658{ 3658{
3659 struct mm_struct *mm;
3660 struct vm_area_struct *vma; 3659 struct vm_area_struct *vma;
3661 void *old_buf = buf; 3660 void *old_buf = buf;
3662 3661
3663 mm = get_task_mm(tsk);
3664 if (!mm)
3665 return 0;
3666
3667 down_read(&mm->mmap_sem); 3662 down_read(&mm->mmap_sem);
3668 /* ignore errors, just check how much was successfully transferred */ 3663 /* ignore errors, just check how much was successfully transferred */
3669 while (len) { 3664 while (len) {
@@ -3712,12 +3707,32 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
3712 addr += bytes; 3707 addr += bytes;
3713 } 3708 }
3714 up_read(&mm->mmap_sem); 3709 up_read(&mm->mmap_sem);
3715 mmput(mm);
3716 3710
3717 return buf - old_buf; 3711 return buf - old_buf;
3718} 3712}
3719 3713
3720/* 3714/*
3715 * Access another process' address space.
3716 * Source/target buffer must be kernel space,
3717 * Do not walk the page table directly, use get_user_pages
3718 */
3719int access_process_vm(struct task_struct *tsk, unsigned long addr,
3720 void *buf, int len, int write)
3721{
3722 struct mm_struct *mm;
3723 int ret;
3724
3725 mm = get_task_mm(tsk);
3726 if (!mm)
3727 return 0;
3728
3729 ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
3730 mmput(mm);
3731
3732 return ret;
3733}
3734
3735/*
3721 * Print the name of a VMA. 3736 * Print the name of a VMA.
3722 */ 3737 */
3723void print_vma_addr(char *prefix, unsigned long ip) 3738void print_vma_addr(char *prefix, unsigned long ip)