]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/tile/mm/elf.c
Merge tag 'drm-misc-next-fixes-2017-02-27' of git://anongit.freedesktop.org/git/drm...
[karo-tx-linux.git] / arch / tile / mm / elf.c
index 23f044e8a7ab0e1f06c425655f1f8ecf11f9996e..88990182440026d06c6d69634eb2cbd12788e6e2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/binfmts.h>
 #include <linux/compat.h>
 #include <linux/mman.h>
+#include <linux/file.h>
 #include <linux/elf.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -39,30 +40,34 @@ static void sim_notify_exec(const char *binary_name)
 
 static int notify_exec(struct mm_struct *mm)
 {
+       int ret = 0;
        char *buf, *path;
        struct vm_area_struct *vma;
+       struct file *exe_file;
 
        if (!sim_is_simulator())
                return 1;
 
-       if (mm->exe_file == NULL)
-               return 0;
-
-       for (vma = current->mm->mmap; ; vma = vma->vm_next) {
-               if (vma == NULL)
-                       return 0;
-               if (vma->vm_file == mm->exe_file)
-                       break;
-       }
-
        buf = (char *) __get_free_page(GFP_KERNEL);
        if (buf == NULL)
                return 0;
 
-       path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE);
-       if (IS_ERR(path)) {
-               free_page((unsigned long)buf);
-               return 0;
+       exe_file = get_mm_exe_file(mm);
+       if (exe_file == NULL)
+               goto done_free;
+
+       path = file_path(exe_file, buf, PAGE_SIZE);
+       if (IS_ERR(path))
+               goto done_put;
+
+       down_read(&mm->mmap_sem);
+       for (vma = current->mm->mmap; ; vma = vma->vm_next) {
+               if (vma == NULL) {
+                       up_read(&mm->mmap_sem);
+                       goto done_put;
+               }
+               if (vma->vm_file == exe_file)
+                       break;
        }
 
        /*
@@ -80,14 +85,20 @@ static int notify_exec(struct mm_struct *mm)
                        __insn_mtspr(SPR_SIM_CONTROL,
                                     (SIM_CONTROL_DLOPEN
                                      | (c << _SIM_CONTROL_OPERATOR_BITS)));
-                       if (c == '\0')
+                       if (c == '\0') {
+                               ret = 1; /* success */
                                break;
+                       }
                }
        }
+       up_read(&mm->mmap_sem);
 
        sim_notify_exec(path);
+done_put:
+       fput(exe_file);
+done_free:
        free_page((unsigned long)buf);
-       return 1;
+       return ret;
 }
 
 /* Notify a running simulator, if any, that we loaded an interpreter. */
@@ -109,8 +120,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        struct mm_struct *mm = current->mm;
        int retval = 0;
 
-       down_write(&mm->mmap_sem);
-
        /*
         * Notify the simulator that an exec just occurred.
         * If we can't find the filename of the mapping, just use
@@ -119,6 +128,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        if (!notify_exec(mm))
                sim_notify_exec(bprm->filename);
 
+       down_write(&mm->mmap_sem);
+
        retval = setup_vdso_pages();
 
 #ifndef __tilegx__
@@ -132,7 +143,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
                unsigned long addr = MEM_USER_INTRPT;
                addr = mmap_region(NULL, addr, INTRPT_SIZE,
                                   VM_READ|VM_EXEC|
-                                  VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, 0);
+                                  VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, 0, NULL);
                if (addr > (unsigned long) -PAGE_SIZE)
                        retval = (int) addr;
        }