diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-05 22:24:29 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-09 00:16:24 -0500 |
commit | cdc3d5627d5f7c4e6b6372b9fb39cba0fe6a9b2a (patch) | |
tree | a171558a3396fbcf89a82a065d4f0742ddc22076 | |
parent | e6c1baa9b562ca296d57178c44f3894795d13d32 (diff) |
switch elf_coredump_extra_notes_write() to dump_emit()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/powerpc/include/asm/spu.h | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spu_syscalls.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/coredump.c | 44 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 3 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 7 | ||||
-rw-r--r-- | include/linux/elf.h | 6 |
6 files changed, 30 insertions, 38 deletions
diff --git a/arch/powerpc/include/asm/spu.h b/arch/powerpc/include/asm/spu.h index 93f280e23279..37b7ca39ec9f 100644 --- a/arch/powerpc/include/asm/spu.h +++ b/arch/powerpc/include/asm/spu.h | |||
@@ -235,6 +235,7 @@ extern long spu_sys_callback(struct spu_syscall_block *s); | |||
235 | 235 | ||
236 | /* syscalls implemented in spufs */ | 236 | /* syscalls implemented in spufs */ |
237 | struct file; | 237 | struct file; |
238 | struct coredump_params; | ||
238 | struct spufs_calls { | 239 | struct spufs_calls { |
239 | long (*create_thread)(const char __user *name, | 240 | long (*create_thread)(const char __user *name, |
240 | unsigned int flags, umode_t mode, | 241 | unsigned int flags, umode_t mode, |
@@ -242,7 +243,7 @@ struct spufs_calls { | |||
242 | long (*spu_run)(struct file *filp, __u32 __user *unpc, | 243 | long (*spu_run)(struct file *filp, __u32 __user *unpc, |
243 | __u32 __user *ustatus); | 244 | __u32 __user *ustatus); |
244 | int (*coredump_extra_notes_size)(void); | 245 | int (*coredump_extra_notes_size)(void); |
245 | int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset); | 246 | int (*coredump_extra_notes_write)(struct coredump_params *cprm); |
246 | void (*notify_spus_active)(void); | 247 | void (*notify_spus_active)(void); |
247 | struct module *owner; | 248 | struct module *owner; |
248 | }; | 249 | }; |
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c index db4e638cf408..3844f1397fc3 100644 --- a/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/arch/powerpc/platforms/cell/spu_syscalls.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/syscalls.h> | 26 | #include <linux/syscalls.h> |
27 | #include <linux/rcupdate.h> | 27 | #include <linux/rcupdate.h> |
28 | #include <linux/binfmts.h> | ||
28 | 29 | ||
29 | #include <asm/spu.h> | 30 | #include <asm/spu.h> |
30 | 31 | ||
@@ -126,7 +127,7 @@ int elf_coredump_extra_notes_size(void) | |||
126 | return ret; | 127 | return ret; |
127 | } | 128 | } |
128 | 129 | ||
129 | int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) | 130 | int elf_coredump_extra_notes_write(struct coredump_params *cprm) |
130 | { | 131 | { |
131 | struct spufs_calls *calls; | 132 | struct spufs_calls *calls; |
132 | int ret; | 133 | int ret; |
@@ -135,7 +136,7 @@ int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) | |||
135 | if (!calls) | 136 | if (!calls) |
136 | return 0; | 137 | return 0; |
137 | 138 | ||
138 | ret = calls->coredump_extra_notes_write(file, foffset); | 139 | ret = calls->coredump_extra_notes_write(cprm); |
139 | 140 | ||
140 | spufs_calls_put(calls); | 141 | spufs_calls_put(calls); |
141 | 142 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index c9500ea7be2f..5d9b0a288f36 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/gfp.h> | 27 | #include <linux/gfp.h> |
28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/coredump.h> | ||
31 | #include <linux/binfmts.h> | ||
30 | 32 | ||
31 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
32 | 34 | ||
@@ -52,35 +54,24 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer, | |||
52 | * These are the only things you should do on a core-file: use only these | 54 | * These are the only things you should do on a core-file: use only these |
53 | * functions to write out all the necessary info. | 55 | * functions to write out all the necessary info. |
54 | */ | 56 | */ |
55 | static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset) | 57 | static int spufs_dump_write(struct coredump_params *cprm, const void *addr, int nr) |
56 | { | 58 | { |
57 | unsigned long limit = rlimit(RLIMIT_CORE); | 59 | if (!dump_emit(cprm, addr, nr)) |
58 | ssize_t written; | ||
59 | |||
60 | if (*foffset + nr > limit) | ||
61 | return -EIO; | 60 | return -EIO; |
62 | |||
63 | written = file->f_op->write(file, addr, nr, &file->f_pos); | ||
64 | *foffset += written; | ||
65 | |||
66 | if (written != nr) | ||
67 | return -EIO; | ||
68 | |||
69 | return 0; | 61 | return 0; |
70 | } | 62 | } |
71 | 63 | ||
72 | static int spufs_dump_align(struct file *file, char *buf, loff_t new_off, | 64 | static int spufs_dump_align(struct coredump_params *cprm, char *buf, loff_t new_off) |
73 | loff_t *foffset) | ||
74 | { | 65 | { |
75 | int rc, size; | 66 | int rc, size; |
76 | 67 | ||
77 | size = min((loff_t)PAGE_SIZE, new_off - *foffset); | 68 | size = min((loff_t)PAGE_SIZE, new_off - cprm->written); |
78 | memset(buf, 0, size); | 69 | memset(buf, 0, size); |
79 | 70 | ||
80 | rc = 0; | 71 | rc = 0; |
81 | while (rc == 0 && new_off > *foffset) { | 72 | while (rc == 0 && new_off > cprm->written) { |
82 | size = min((loff_t)PAGE_SIZE, new_off - *foffset); | 73 | size = min((loff_t)PAGE_SIZE, new_off - cprm->written); |
83 | rc = spufs_dump_write(file, buf, size, foffset); | 74 | rc = spufs_dump_write(cprm, buf, size); |
84 | } | 75 | } |
85 | 76 | ||
86 | return rc; | 77 | return rc; |
@@ -165,7 +156,7 @@ int spufs_coredump_extra_notes_size(void) | |||
165 | } | 156 | } |
166 | 157 | ||
167 | static int spufs_arch_write_note(struct spu_context *ctx, int i, | 158 | static int spufs_arch_write_note(struct spu_context *ctx, int i, |
168 | struct file *file, int dfd, loff_t *foffset) | 159 | struct coredump_params *cprm, int dfd) |
169 | { | 160 | { |
170 | loff_t pos = 0; | 161 | loff_t pos = 0; |
171 | int sz, rc, nread, total = 0; | 162 | int sz, rc, nread, total = 0; |
@@ -186,22 +177,22 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i, | |||
186 | en.n_descsz = sz; | 177 | en.n_descsz = sz; |
187 | en.n_type = NT_SPU; | 178 | en.n_type = NT_SPU; |
188 | 179 | ||
189 | rc = spufs_dump_write(file, &en, sizeof(en), foffset); | 180 | rc = spufs_dump_write(cprm, &en, sizeof(en)); |
190 | if (rc) | 181 | if (rc) |
191 | goto out; | 182 | goto out; |
192 | 183 | ||
193 | rc = spufs_dump_write(file, fullname, en.n_namesz, foffset); | 184 | rc = spufs_dump_write(cprm, fullname, en.n_namesz); |
194 | if (rc) | 185 | if (rc) |
195 | goto out; | 186 | goto out; |
196 | 187 | ||
197 | rc = spufs_dump_align(file, buf, roundup(*foffset, 4), foffset); | 188 | rc = spufs_dump_align(cprm, buf, roundup(cprm->written, 4)); |
198 | if (rc) | 189 | if (rc) |
199 | goto out; | 190 | goto out; |
200 | 191 | ||
201 | do { | 192 | do { |
202 | nread = do_coredump_read(i, ctx, buf, bufsz, &pos); | 193 | nread = do_coredump_read(i, ctx, buf, bufsz, &pos); |
203 | if (nread > 0) { | 194 | if (nread > 0) { |
204 | rc = spufs_dump_write(file, buf, nread, foffset); | 195 | rc = spufs_dump_write(cprm, buf, nread); |
205 | if (rc) | 196 | if (rc) |
206 | goto out; | 197 | goto out; |
207 | total += nread; | 198 | total += nread; |
@@ -213,15 +204,14 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i, | |||
213 | goto out; | 204 | goto out; |
214 | } | 205 | } |
215 | 206 | ||
216 | rc = spufs_dump_align(file, buf, roundup(*foffset - total + sz, 4), | 207 | rc = spufs_dump_align(cprm, buf, roundup(cprm->written - total + sz, 4)); |
217 | foffset); | ||
218 | 208 | ||
219 | out: | 209 | out: |
220 | free_page((unsigned long)buf); | 210 | free_page((unsigned long)buf); |
221 | return rc; | 211 | return rc; |
222 | } | 212 | } |
223 | 213 | ||
224 | int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) | 214 | int spufs_coredump_extra_notes_write(struct coredump_params *cprm) |
225 | { | 215 | { |
226 | struct spu_context *ctx; | 216 | struct spu_context *ctx; |
227 | int fd, j, rc; | 217 | int fd, j, rc; |
@@ -233,7 +223,7 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) | |||
233 | return rc; | 223 | return rc; |
234 | 224 | ||
235 | for (j = 0; spufs_coredump_read[j].name != NULL; j++) { | 225 | for (j = 0; spufs_coredump_read[j].name != NULL; j++) { |
236 | rc = spufs_arch_write_note(ctx, j, file, fd, foffset); | 226 | rc = spufs_arch_write_note(ctx, j, cprm, fd); |
237 | if (rc) { | 227 | if (rc) { |
238 | spu_release_saved(ctx); | 228 | spu_release_saved(ctx); |
239 | return rc; | 229 | return rc; |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 67852ade4c01..0ba3c9598358 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -247,12 +247,13 @@ extern const struct spufs_tree_descr spufs_dir_debug_contents[]; | |||
247 | 247 | ||
248 | /* system call implementation */ | 248 | /* system call implementation */ |
249 | extern struct spufs_calls spufs_calls; | 249 | extern struct spufs_calls spufs_calls; |
250 | struct coredump_params; | ||
250 | long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); | 251 | long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); |
251 | long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, | 252 | long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, |
252 | umode_t mode, struct file *filp); | 253 | umode_t mode, struct file *filp); |
253 | /* ELF coredump callbacks for writing SPU ELF notes */ | 254 | /* ELF coredump callbacks for writing SPU ELF notes */ |
254 | extern int spufs_coredump_extra_notes_size(void); | 255 | extern int spufs_coredump_extra_notes_size(void); |
255 | extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset); | 256 | extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm); |
256 | 257 | ||
257 | extern const struct file_operations spufs_context_fops; | 258 | extern const struct file_operations spufs_context_fops; |
258 | 259 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ddab40d3d828..3bf75d767a4a 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -2037,7 +2037,7 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
2037 | size_t size = 0; | 2037 | size_t size = 0; |
2038 | struct vm_area_struct *vma, *gate_vma; | 2038 | struct vm_area_struct *vma, *gate_vma; |
2039 | struct elfhdr *elf = NULL; | 2039 | struct elfhdr *elf = NULL; |
2040 | loff_t offset = 0, dataoff, foffset; | 2040 | loff_t offset = 0, dataoff; |
2041 | struct elf_note_info info = { }; | 2041 | struct elf_note_info info = { }; |
2042 | struct elf_phdr *phdr4note = NULL; | 2042 | struct elf_phdr *phdr4note = NULL; |
2043 | struct elf_shdr *shdr4extnum = NULL; | 2043 | struct elf_shdr *shdr4extnum = NULL; |
@@ -2160,12 +2160,11 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
2160 | if (!write_note_info(&info, cprm)) | 2160 | if (!write_note_info(&info, cprm)) |
2161 | goto end_coredump; | 2161 | goto end_coredump; |
2162 | 2162 | ||
2163 | foffset = cprm->written; | 2163 | if (elf_coredump_extra_notes_write(cprm)) |
2164 | if (elf_coredump_extra_notes_write(cprm->file, &foffset)) | ||
2165 | goto end_coredump; | 2164 | goto end_coredump; |
2166 | 2165 | ||
2167 | /* Align to page */ | 2166 | /* Align to page */ |
2168 | if (!dump_seek(cprm->file, dataoff - foffset)) | 2167 | if (!dump_seek(cprm->file, dataoff - cprm->written)) |
2169 | goto end_coredump; | 2168 | goto end_coredump; |
2170 | 2169 | ||
2171 | cprm->written = size; | 2170 | cprm->written = size; |
diff --git a/include/linux/elf.h b/include/linux/elf.h index 40a3c0e01b2b..67a5fa7830c4 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h | |||
@@ -39,13 +39,13 @@ extern Elf64_Dyn _DYNAMIC []; | |||
39 | 39 | ||
40 | /* Optional callbacks to write extra ELF notes. */ | 40 | /* Optional callbacks to write extra ELF notes. */ |
41 | struct file; | 41 | struct file; |
42 | struct coredump_params; | ||
42 | 43 | ||
43 | #ifndef ARCH_HAVE_EXTRA_ELF_NOTES | 44 | #ifndef ARCH_HAVE_EXTRA_ELF_NOTES |
44 | static inline int elf_coredump_extra_notes_size(void) { return 0; } | 45 | static inline int elf_coredump_extra_notes_size(void) { return 0; } |
45 | static inline int elf_coredump_extra_notes_write(struct file *file, | 46 | static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) { return 0; } |
46 | loff_t *foffset) { return 0; } | ||
47 | #else | 47 | #else |
48 | extern int elf_coredump_extra_notes_size(void); | 48 | extern int elf_coredump_extra_notes_size(void); |
49 | extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset); | 49 | extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); |
50 | #endif | 50 | #endif |
51 | #endif /* _LINUX_ELF_H */ | 51 | #endif /* _LINUX_ELF_H */ |