[FIX] call un/kmap() if non-atomic context
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 21 Apr 2014 11:35:01 +0000 (15:35 +0400)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 22 Apr 2014 08:53:12 +0000 (01:53 -0700)
Change-Id: I4d7e93dba7cfc6731e6b88f8a7a39caa3da5e88a
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
kprobe/dbi_kprobes_deps.c

index bc409ae..39c99b2 100644 (file)
@@ -1085,6 +1085,7 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
        struct mm_struct *mm;
        struct vm_area_struct *vma;
        void *old_buf = buf;
+       int atomic;
 
        if (len <= 0) {
                return -1;
@@ -1101,6 +1102,9 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
        if (!mm)
                return 0;
 
+       /* FIXME: danger: write memory in atomic context */
+       atomic = in_atomic();
+
        /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, ret, offset;
@@ -1132,7 +1136,7 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
                        if (bytes > PAGE_SIZE-offset)
                                bytes = PAGE_SIZE-offset;
 
-                       maddr = dbi_kmap_atomic(page);
+                       maddr = atomic ? dbi_kmap_atomic(page) : kmap(page);
 
                        if (write) {
                                copy_to_user_page(vma, page, addr,
@@ -1143,7 +1147,7 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
                                                        buf, maddr + offset, bytes);
                        }
 
-                       dbi_kunmap_atomic(maddr);
+                       atomic ? dbi_kunmap_atomic(maddr) : kunmap(page);
                        page_cache_release(page);
                }
                len -= bytes;