|
@@ -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,11 +3707,31 @@ 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.
|
|
|
*/
|