initial import
[patches.git] / bfin-proc-mem.patch
1 --- a/mm/memory.c
2 +++ b/mm/memory.c
3 @@ -2505,3 +2505,56 @@ #endif
4 }
5
6 #endif /* __HAVE_ARCH_GATE_AREA */
7 +
8 +/*
9 + * Access another process' address space.
10 + * Source/target buffer must be kernel space,
11 + * Do not walk the page table directly, use get_user_pages
12 + */
13 +int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
14 +{
15 + struct mm_struct *mm;
16 + struct vm_area_struct *vma;
17 + struct page *page;
18 + void *old_buf = buf;
19 +
20 + mm = get_task_mm(tsk);
21 + if (!mm)
22 + return 0;
23 +
24 + down_read(&mm->mmap_sem);
25 + /* ignore errors, just check how much was sucessfully transfered */
26 + while (len) {
27 + int bytes, ret, offset;
28 + void *maddr;
29 +
30 + ret = get_user_pages(tsk, mm, addr, 1,
31 + write, 1, &page, &vma);
32 + if (ret <= 0)
33 + break;
34 +
35 + bytes = len;
36 + offset = addr & (PAGE_SIZE-1);
37 + if (bytes > PAGE_SIZE-offset)
38 + bytes = PAGE_SIZE-offset;
39 +
40 + maddr = kmap(page);
41 + if (write) {
42 + copy_to_user_page(vma, page, addr,
43 + maddr + offset, buf, bytes);
44 + set_page_dirty_lock(page);
45 + } else {
46 + copy_from_user_page(vma, page, addr,
47 + buf, maddr + offset, bytes);
48 + }
49 + kunmap(page);
50 + page_cache_release(page);
51 + len -= bytes;
52 + buf += bytes;
53 + addr += bytes;
54 + }
55 + up_read(&mm->mmap_sem);
56 + mmput(mm);
57 +
58 + return buf - old_buf;
59 +}
60 --- a/mm/nommu.c
61 +++ b/mm/nommu.c
62 @@ -1206,3 +1206,51 @@ struct page *filemap_nopage(struct vm_ar
63 BUG();
64 return NULL;
65 }
66 +
67 +/*
68 + * Access another process' address space.
69 + * - source/target buffer must be kernel space
70 + */
71 +int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
72 +{
73 + struct vm_list_struct *vml;
74 + struct vm_area_struct *vma;
75 + struct mm_struct *mm;
76 +printk("!!! OH YEAH\n");
77 + if (addr + len < addr)
78 + return 0;
79 +
80 + mm = get_task_mm(tsk);
81 + if (!mm)
82 + return 0;
83 +
84 + down_read(&mm->mmap_sem);
85 +
86 + /* the access must start within one of the target process's mappings */
87 + for (vml = mm->context.vmlist; vml; vml = vml->next) {
88 + if (addr >= vml->vma->vm_start && addr < vml->vma->vm_end)
89 + break;
90 + }
91 +
92 + if (vml) {
93 + vma = vml->vma;
94 +
95 + /* don't overrun this mapping */
96 + if (addr + len >= vma->vm_end)
97 + len = vma->vm_end - addr;
98 +
99 + /* only read or write mappings where it is permitted */
100 + if (write && vma->vm_flags & VM_WRITE)
101 + len -= copy_to_user((void *) addr, buf, len);
102 + else if (!write && vma->vm_flags & VM_READ)
103 + len -= copy_from_user(buf, (void *) addr, len);
104 + else
105 + len = 0;
106 + } else {
107 + len = 0;
108 + }
109 +
110 + up_read(&mm->mmap_sem);
111 + mmput(mm);
112 + return len;
113 +}