summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorStephen Wilson <wilsons@start.ca>2011-03-13 22:49:19 +0300
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-23 23:36:56 +0300
commit206cb636576b969e9b471cdedeaea7752e6acb33 (patch)
tree252a1b5e9ce41521fb93b519265d4a1dbd18cfe9 /mm
parente7f22e207bacdba5b73f2893a3abe935a5373e2e (diff)
downloadlinux-206cb636576b969e9b471cdedeaea7752e6acb33.tar.xz
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,
#endif
/*
- * Access another process' address space.
- * Source/target buffer must be kernel space,
- * Do not walk the page table directly, use get_user_pages
+ * Access another process' address space as given in mm. If non-NULL, use the
+ * given task for page fault accounting.
*/
-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;
void *old_buf = buf;
- mm = get_task_mm(tsk);
- if (!mm)
- return 0;
-
down_read(&mm->mmap_sem);
/* ignore errors, just check how much was successfully transferred */
while (len) {
@@ -3712,12 +3707,32 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
addr += bytes;
}
up_read(&mm->mmap_sem);
- mmput(mm);
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.
*/
void print_vma_addr(char *prefix, unsigned long ip)