aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorDavidlohr Bueso <dave@stgolabs.net>2015-02-25 16:58:35 -0500
committerChris Metcalf <cmetcalf@ezchip.com>2015-04-17 12:58:31 -0400
commit5a3b4e8000c1ce476f5e8babd62c580457561f34 (patch)
tree9ee106a764964508ce11beff4b06b9727a7e8381 /arch/tile
parent89067c2daf3d9e0ce51c768589e79e845e6fda42 (diff)
tile/elf: reorganize notify_exec()
In the future mm->exe_file will be done without mmap_sem serialization, thus isolate and reorganize the tile elf code to make the transition easier. Good users will, make use of the more standard get_mm_exe_file(), requiring only holding the mmap_sem to read the value, and relying on reference counting to make sure that the exe file won't dissappear underneath us. The visible effects of this patch are: o We now take and drop the mmap_sem more often. Instead of just in arch_setup_additional_pages(), we also do it in: 1) get_mm_exe_file() 2) to get the mm->vm_file and notify the simulator. [Note that 1) will disappear once we change the locking rules for exe_file.] o We avoid getting a free page and doing d_path() while holding the mmap_sem. This requires reordering the checks. Signed-off-by: Davidlohr Bueso <dbueso@suse.de> Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/mm/elf.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
index 23f044e8a7ab..f7ddae3725a4 100644
--- a/arch/tile/mm/elf.c
+++ b/arch/tile/mm/elf.c
@@ -17,6 +17,7 @@
17#include <linux/binfmts.h> 17#include <linux/binfmts.h>
18#include <linux/compat.h> 18#include <linux/compat.h>
19#include <linux/mman.h> 19#include <linux/mman.h>
20#include <linux/file.h>
20#include <linux/elf.h> 21#include <linux/elf.h>
21#include <asm/pgtable.h> 22#include <asm/pgtable.h>
22#include <asm/pgalloc.h> 23#include <asm/pgalloc.h>
@@ -39,30 +40,34 @@ static void sim_notify_exec(const char *binary_name)
39 40
40static int notify_exec(struct mm_struct *mm) 41static int notify_exec(struct mm_struct *mm)
41{ 42{
43 int ret = 0;
42 char *buf, *path; 44 char *buf, *path;
43 struct vm_area_struct *vma; 45 struct vm_area_struct *vma;
46 struct file *exe_file;
44 47
45 if (!sim_is_simulator()) 48 if (!sim_is_simulator())
46 return 1; 49 return 1;
47 50
48 if (mm->exe_file == NULL)
49 return 0;
50
51 for (vma = current->mm->mmap; ; vma = vma->vm_next) {
52 if (vma == NULL)
53 return 0;
54 if (vma->vm_file == mm->exe_file)
55 break;
56 }
57
58 buf = (char *) __get_free_page(GFP_KERNEL); 51 buf = (char *) __get_free_page(GFP_KERNEL);
59 if (buf == NULL) 52 if (buf == NULL)
60 return 0; 53 return 0;
61 54
62 path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE); 55 exe_file = get_mm_exe_file(mm);
63 if (IS_ERR(path)) { 56 if (exe_file == NULL)
64 free_page((unsigned long)buf); 57 goto done_free;
65 return 0; 58
59 path = d_path(&exe_file->f_path, buf, PAGE_SIZE);
60 if (IS_ERR(path))
61 goto done_put;
62
63 down_read(&mm->mmap_sem);
64 for (vma = current->mm->mmap; ; vma = vma->vm_next) {
65 if (vma == NULL) {
66 up_read(&mm->mmap_sem);
67 goto done_put;
68 }
69 if (vma->vm_file == exe_file)
70 break;
66 } 71 }
67 72
68 /* 73 /*
@@ -80,14 +85,20 @@ static int notify_exec(struct mm_struct *mm)
80 __insn_mtspr(SPR_SIM_CONTROL, 85 __insn_mtspr(SPR_SIM_CONTROL,
81 (SIM_CONTROL_DLOPEN 86 (SIM_CONTROL_DLOPEN
82 | (c << _SIM_CONTROL_OPERATOR_BITS))); 87 | (c << _SIM_CONTROL_OPERATOR_BITS)));
83 if (c == '\0') 88 if (c == '\0') {
89 ret = 1; /* success */
84 break; 90 break;
91 }
85 } 92 }
86 } 93 }
94 up_read(&mm->mmap_sem);
87 95
88 sim_notify_exec(path); 96 sim_notify_exec(path);
97done_put:
98 fput(exe_file);
99done_free:
89 free_page((unsigned long)buf); 100 free_page((unsigned long)buf);
90 return 1; 101 return ret;
91} 102}
92 103
93/* Notify a running simulator, if any, that we loaded an interpreter. */ 104/* Notify a running simulator, if any, that we loaded an interpreter. */
@@ -109,8 +120,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
109 struct mm_struct *mm = current->mm; 120 struct mm_struct *mm = current->mm;
110 int retval = 0; 121 int retval = 0;
111 122
112 down_write(&mm->mmap_sem);
113
114 /* 123 /*
115 * Notify the simulator that an exec just occurred. 124 * Notify the simulator that an exec just occurred.
116 * If we can't find the filename of the mapping, just use 125 * 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,
119 if (!notify_exec(mm)) 128 if (!notify_exec(mm))
120 sim_notify_exec(bprm->filename); 129 sim_notify_exec(bprm->filename);
121 130
131 down_write(&mm->mmap_sem);
132
122 retval = setup_vdso_pages(); 133 retval = setup_vdso_pages();
123 134
124#ifndef __tilegx__ 135#ifndef __tilegx__