Subject: Write some SPU coredump values as ASCII From: Michael Ellerman Unfortunately GDB expects some of the SPU coredump values to be identical in format to what is found in spufs. This means we need to dump some of the values as ASCII strings, not the actual values. Because we don't know what the values will be, we always print the values with the format "0x%.16lx", that way we know the result will be 19 bytes. do_coredump_read() doesn't take a __user buffer, so remove the annotation, and because we know that it's safe to just snprintf() directly to it. The spufs_coredump_reader array contains the size of the data that will be returned by the read routine. Currently these are specified as literals, and though some are obvious, sizeof(u32) == 4, others are not, 69 * 8 == ??? Instead, use sizeof() whatever type is returned by each routine, or in the case of spufs_mem_read() the #define LS_SIZE. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann Index: linux-2.6/arch/powerpc/platforms/cell/spufs/coredump.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/coredump.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/coredump.c @@ -31,7 +31,7 @@ #include "spufs.h" -static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer, +static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer, size_t size, loff_t *off) { u64 data; @@ -41,8 +41,10 @@ static ssize_t do_coredump_read(int num, return spufs_coredump_read[num].read(ctx, buffer, size, off); data = spufs_coredump_read[num].get(ctx); - ret = copy_to_user(buffer, &data, 8); - return ret ? -EFAULT : 8; + ret = snprintf(buffer, size, "0x%.16lx", data); + if (ret >= size) + return size; + return ++ret; /* count trailing NULL */ } /* @@ -64,11 +66,6 @@ static int spufs_dump_seek(struct file * return 1; } -static u64 ctx_ls_size(struct spu_context *ctx) -{ - return ctx->csa.priv2.spu_lslr_RW + 1; -} - static int spufs_ctx_note_size(struct spu_context *ctx, int dfd) { int i, sz, total = 0; @@ -83,10 +80,7 @@ static int spufs_ctx_note_size(struct sp total += sizeof(struct elf_note); total += roundup(strlen(fullname) + 1, 4); - if (!strcmp(name, "mem")) - total += roundup(ctx_ls_size(ctx), 4); - else - total += roundup(sz, 4); + total += roundup(sz, 4); } return total; @@ -162,11 +156,7 @@ static void spufs_arch_write_note(struct return; name = spufs_coredump_read[i].name; - - if (!strcmp(name, "mem")) - sz = ctx_ls_size(ctx); - else - sz = spufs_coredump_read[i].size; + sz = spufs_coredump_read[i].size; sprintf(fullname, "SPU/%d/%s", dfd, name); en.n_namesz = strlen(fullname) + 1; Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c +++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c @@ -2210,23 +2210,24 @@ struct tree_descr spufs_dir_nosched_cont }; struct spufs_coredump_reader spufs_coredump_read[] = { - { "regs", __spufs_regs_read, NULL, 128 * 16 }, - { "fpcr", __spufs_fpcr_read, NULL, 16 }, - { "lslr", NULL, __spufs_lslr_get, 11 }, - { "decr", NULL, __spufs_decr_get, 11 }, - { "decr_status", NULL, __spufs_decr_status_get, 11 }, - { "mem", __spufs_mem_read, NULL, 256 * 1024, }, - { "signal1", __spufs_signal1_read, NULL, 4 }, - { "signal1_type", NULL, __spufs_signal1_type_get, 2 }, - { "signal2", __spufs_signal2_read, NULL, 4 }, - { "signal2_type", NULL, __spufs_signal2_type_get, 2 }, - { "event_mask", NULL, __spufs_event_mask_get, 8 }, - { "event_status", NULL, __spufs_event_status_get, 8 }, - { "mbox_info", __spufs_mbox_info_read, NULL, 4 }, - { "ibox_info", __spufs_ibox_info_read, NULL, 4 }, - { "wbox_info", __spufs_wbox_info_read, NULL, 16 }, - { "dma_info", __spufs_dma_info_read, NULL, 69 * 8 }, - { "proxydma_info", __spufs_proxydma_info_read, NULL, 35 * 8 }, + { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])}, + { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) }, + { "lslr", NULL, __spufs_lslr_get, 19 }, + { "decr", NULL, __spufs_decr_get, 19 }, + { "decr_status", NULL, __spufs_decr_status_get, 19 }, + { "mem", __spufs_mem_read, NULL, LS_SIZE, }, + { "signal1", __spufs_signal1_read, NULL, sizeof(u32) }, + { "signal1_type", NULL, __spufs_signal1_type_get, 19 }, + { "signal2", __spufs_signal2_read, NULL, sizeof(u32) }, + { "signal2_type", NULL, __spufs_signal2_type_get, 19 }, + { "event_mask", NULL, __spufs_event_mask_get, 19 }, + { "event_status", NULL, __spufs_event_status_get, 19 }, + { "mbox_info", __spufs_mbox_info_read, NULL, sizeof(u32) }, + { "ibox_info", __spufs_ibox_info_read, NULL, sizeof(u32) }, + { "wbox_info", __spufs_wbox_info_read, NULL, 4 * sizeof(u32)}, + { "dma_info", __spufs_dma_info_read, NULL, sizeof(struct spu_dma_info)}, + { "proxydma_info", __spufs_proxydma_info_read, + NULL, sizeof(struct spu_proxydma_info)}, { "object-id", NULL, __spufs_object_id_get, 19 }, { }, };