aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-05 22:24:29 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:24 -0500
commitcdc3d5627d5f7c4e6b6372b9fb39cba0fe6a9b2a (patch)
treea171558a3396fbcf89a82a065d4f0742ddc22076 /arch
parente6c1baa9b562ca296d57178c44f3894795d13d32 (diff)
switch elf_coredump_extra_notes_write() to dump_emit()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/spu.h3
-rw-r--r--arch/powerpc/platforms/cell/spu_syscalls.c5
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c44
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h3
4 files changed, 24 insertions, 31 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 */
237struct file; 237struct file;
238struct coredump_params;
238struct spufs_calls { 239struct 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
129int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) 130int 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 */
55static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset) 57static 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
72static int spufs_dump_align(struct file *file, char *buf, loff_t new_off, 64static 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
167static int spufs_arch_write_note(struct spu_context *ctx, int i, 158static 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
219out: 209out:
220 free_page((unsigned long)buf); 210 free_page((unsigned long)buf);
221 return rc; 211 return rc;
222} 212}
223 213
224int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) 214int 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 */
249extern struct spufs_calls spufs_calls; 249extern struct spufs_calls spufs_calls;
250struct coredump_params;
250long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); 251long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
251long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, 252long 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 */
254extern int spufs_coredump_extra_notes_size(void); 255extern int spufs_coredump_extra_notes_size(void);
255extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset); 256extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm);
256 257
257extern const struct file_operations spufs_context_fops; 258extern const struct file_operations spufs_context_fops;
258 259