Skip to content

Commit 5456ffd

Browse files
Christoph HellwigAl Viro
authored andcommitted
powerpc/spufs: simplify spufs core dumping
Replace the coredump ->read method with a ->dump method that must call dump_emit itself. That way we avoid a buffer allocation an messing with set_fs() to call into code that is intended to deal with user buffers. For the ->get case we can now use a small on-stack buffer and avoid memory allocations as well. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Arnd Bergmann <[email protected]> Reviewed-by: Jeremy Kerr <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 6904d3d commit 5456ffd

File tree

3 files changed

+117
-176
lines changed

3 files changed

+117
-176
lines changed

arch/powerpc/platforms/cell/spufs/coredump.c

Lines changed: 28 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,6 @@
2121

2222
#include "spufs.h"
2323

24-
static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
25-
size_t size, loff_t *off)
26-
{
27-
u64 data;
28-
int ret;
29-
30-
if (spufs_coredump_read[num].read)
31-
return spufs_coredump_read[num].read(ctx, buffer, size, off);
32-
33-
data = spufs_coredump_read[num].get(ctx);
34-
ret = snprintf(buffer, size, "0x%.16llx", data);
35-
if (ret >= size)
36-
return size;
37-
return ++ret; /* count trailing NULL */
38-
}
39-
4024
static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
4125
{
4226
int i, sz, total = 0;
@@ -118,58 +102,43 @@ int spufs_coredump_extra_notes_size(void)
118102
static int spufs_arch_write_note(struct spu_context *ctx, int i,
119103
struct coredump_params *cprm, int dfd)
120104
{
121-
loff_t pos = 0;
122-
int sz, rc, total = 0;
123-
const int bufsz = PAGE_SIZE;
124-
char *name;
125-
char fullname[80], *buf;
105+
size_t sz = spufs_coredump_read[i].size;
106+
char fullname[80];
126107
struct elf_note en;
127-
size_t skip;
128-
129-
buf = (void *)get_zeroed_page(GFP_KERNEL);
130-
if (!buf)
131-
return -ENOMEM;
108+
size_t ret;
132109

133-
name = spufs_coredump_read[i].name;
134-
sz = spufs_coredump_read[i].size;
135-
136-
sprintf(fullname, "SPU/%d/%s", dfd, name);
110+
sprintf(fullname, "SPU/%d/%s", dfd, spufs_coredump_read[i].name);
137111
en.n_namesz = strlen(fullname) + 1;
138112
en.n_descsz = sz;
139113
en.n_type = NT_SPU;
140114

141115
if (!dump_emit(cprm, &en, sizeof(en)))
142-
goto Eio;
143-
116+
return -EIO;
144117
if (!dump_emit(cprm, fullname, en.n_namesz))
145-
goto Eio;
146-
118+
return -EIO;
147119
if (!dump_align(cprm, 4))
148-
goto Eio;
149-
150-
do {
151-
rc = do_coredump_read(i, ctx, buf, bufsz, &pos);
152-
if (rc > 0) {
153-
if (!dump_emit(cprm, buf, rc))
154-
goto Eio;
155-
total += rc;
156-
}
157-
} while (rc == bufsz && total < sz);
158-
159-
if (rc < 0)
160-
goto out;
161-
162-
skip = roundup(cprm->pos - total + sz, 4) - cprm->pos;
163-
if (!dump_skip(cprm, skip))
164-
goto Eio;
165-
166-
rc = 0;
167-
out:
168-
free_page((unsigned long)buf);
169-
return rc;
170-
Eio:
171-
free_page((unsigned long)buf);
172-
return -EIO;
120+
return -EIO;
121+
122+
if (spufs_coredump_read[i].dump) {
123+
ret = spufs_coredump_read[i].dump(ctx, cprm);
124+
if (ret < 0)
125+
return ret;
126+
} else {
127+
char buf[32];
128+
129+
ret = snprintf(buf, sizeof(buf), "0x%.16llx",
130+
spufs_coredump_read[i].get(ctx));
131+
if (ret >= sizeof(buf))
132+
return sizeof(buf);
133+
134+
/* count trailing the NULL: */
135+
if (!dump_emit(cprm, buf, ret + 1))
136+
return -EIO;
137+
}
138+
139+
if (!dump_skip(cprm, roundup(cprm->pos - ret + sz, 4) - cprm->pos))
140+
return -EIO;
141+
return 0;
173142
}
174143

175144
int spufs_coredump_extra_notes_write(struct coredump_params *cprm)

0 commit comments

Comments
 (0)