----- "Dave Anderson" <anderson@xxxxxxxxxx> wrote: > If you're happy with the changes above, I can do it here, make sure > it compiles, and queue it for the next release. Here's my proposed patch, along with cleanups for these compiler warnings: s390x.c: In function 's390x_cpu_get': s390x.c:91: warning: unused variable 'nt_prefix' s390x.c: In function 's390x_back_trace_cmd': s390x.c:762: warning: unused variable 'cpu' s390x.c: In function 's390x_cpu_get' s390x.c:104: warning: control reaches end of non-void function s390x.c:650: warning: ‘s390x_cpu_of_task’ defined but not used BTW, the second stanza in the patch to s390x.c may require hand-patching -- your original didn't apply on my current tree. Anyway, does this work for you? Dave
Index: defs.h =================================================================== RCS file: /nfs/projects/cvs/crash/defs.h,v retrieving revision 1.410 diff -u -r1.410 defs.h --- defs.h 4 Feb 2010 21:04:36 -0000 1.410 +++ defs.h 12 Feb 2010 15:31:27 -0000 @@ -792,6 +792,7 @@ void (*clear_machdep_cache)(void); int (*xen_kdump_p2m_create)(struct xen_kdump_data *); int (*in_alternate_stack)(int, ulong); + void (*elf_note_add)(int, void *); }; /* @@ -2728,6 +2729,8 @@ #endif /* S390 */ #ifdef S390X +#include "elf.h" + #define _64BIT_ #define MACHINE_TYPE "S390X" @@ -2750,6 +2753,86 @@ #define _SECTION_SIZE_BITS 28 #define _MAX_PHYSMEM_BITS 42 +/* + * S390 CPU timer ELF note + */ +#ifndef NT_S390_TIMER +#define NT_S390_TIMER 0x301 +#endif + +/* + * S390 TOD clock comparator ELF note + */ +#ifndef NT_S390_TODCMP +#define NT_S390_TODCMP 0x302 +#endif + +/* + * S390 TOD programmable register ELF note + */ +#ifndef NT_S390_TODPREG +#define NT_S390_TODPREG 0x303 +#endif + +/* + * S390 control registers ELF note + */ +#ifndef NT_S390_CTRS +#define NT_S390_CTRS 0x304 +#endif + +/* + * S390 prefix ELF note + */ +#ifndef NT_S390_PREFIX +#define NT_S390_PREFIX 0x305 +#endif + +/* + * s390x prstatus ELF Note + */ +struct s390x_nt_prstatus { + uint8_t pad1[32]; + uint32_t pr_pid; + uint8_t pad2[76]; + uint64_t psw[2]; + uint64_t gprs[16]; + uint32_t acrs[16]; + uint64_t orig_gpr2; + uint32_t pr_fpvalid; + uint8_t pad3[4]; +} __attribute__ ((packed)); + +/* + * S390x floating point register ELF Note + */ +#ifndef NT_FPREGSET +#define NT_FPREGSET 0x2 +#endif + +struct s390x_nt_fpregset { + uint32_t fpc; + uint32_t pad; + uint64_t fprs[16]; +} __attribute__ ((packed)); + +/* + * s390x CPU info + */ +struct s390x_cpu +{ + uint64_t gprs[16]; + uint64_t ctrs[16]; + uint32_t acrs[16]; + uint64_t fprs[16]; + uint32_t fpc; + uint64_t psw[2]; + uint32_t prefix; + uint64_t timer; + uint64_t todcmp; + uint32_t todpreg; +}; + #endif /* S390X */ #ifdef PLATFORM Index: netdump.c =================================================================== RCS file: /nfs/projects/cvs/crash/netdump.c,v retrieving revision 1.95 diff -u -r1.95 netdump.c --- netdump.c 3 Dec 2009 15:36:42 -0000 1.95 +++ netdump.c 12 Feb 2010 15:32:07 -0000 @@ -213,6 +213,11 @@ goto bailout; break; + case EM_S390: + if (machine_type_mismatch(file, "S390X", NULL, + source_query)) + goto bailout; + break; case EM_386: if (machine_type_mismatch(file, "X86", NULL, source_query)) @@ -1990,6 +1995,9 @@ break; } + if (store && machine_type("S390X") && machdep->elf_note_add) + machdep->elf_note_add(nd->num_prstatus_notes, (void *)note); + uptr = (ulonglong *)(ptr + note->n_namesz); /* @@ -2082,6 +2090,9 @@ return get_netdump_regs_x86_64(bt, eip, esp); break; + case EM_S390: + machdep->get_stack_frame(bt, eip, esp); + break; default: error(FATAL, "support for ELF machine type %d not available\n", Index: s390x.c =================================================================== RCS file: /nfs/projects/cvs/crash/s390x.c,v retrieving revision 1.41 diff -u -r1.41 s390x.c --- s390x.c 10 Feb 2010 20:07:38 -0000 1.41 +++ s390x.c 12 Feb 2010 15:30:58 -0000 @@ -56,7 +56,6 @@ static int s390x_eframe_search(struct bt_info *); static void s390x_back_trace_cmd(struct bt_info *); static void s390x_dump_irq(int); -static void s390x_get_stack_frame(struct bt_info *, ulong *, ulong *); static int s390x_dis_filter(ulong, char *); static void s390x_cmd_mach(void); static int s390x_get_smp_cpus(void); @@ -64,7 +63,10 @@ static void s390x_dump_line_number(ulong); static struct line_number_hook s390x_line_number_hooks[]; static int s390x_is_uvaddr(ulong, struct task_context *); +static void s390x_get_stack_frame(struct bt_info *, ulong *, ulong *); +static struct s390x_cpu *s390x_cpu_vec; +static int s390x_cpu_cnt; /* * Initialize member offsets @@ -79,6 +81,116 @@ "psw_save_area"); } +/* + * Return s390x CPU data for backtrace + */ +static struct s390x_cpu *s390x_cpu_get(struct bt_info *bt) +{ + unsigned int cpu = bt->tc->processor; + unsigned long lowcore_ptr, prefix; + unsigned int i; + + lowcore_ptr = symbol_value("lowcore_ptr"); + readmem(lowcore_ptr + cpu * sizeof(long), KVADDR, + &prefix, sizeof(long), "lowcore_ptr", FAULT_ON_ERROR); + for (i = 0; i < s390x_cpu_cnt; i++) { + if (s390x_cpu_vec[i].prefix == prefix) { + fprintf(fp, "GOT: %i\n", i); + return &s390x_cpu_vec[i]; + } + } + error(FATAL, "cannot determine CPU for task: %lx\n", bt->task); + return NULL; +} + +/* + * ELF core dump fuctions for storing CPU data + */ +static void s390x_elf_nt_prstatus_add(struct s390x_cpu *cpu, + struct s390x_nt_prstatus *prstatus) +{ + memcpy(&cpu->psw, &prstatus->psw, sizeof(cpu->psw)); + memcpy(&cpu->gprs, &prstatus->gprs, sizeof(cpu->gprs)); + memcpy(&cpu->acrs, &prstatus->acrs, sizeof(cpu->acrs)); +} + +static void s390x_elf_nt_fpregset_add(struct s390x_cpu *cpu, + struct s390x_nt_fpregset *fpregset) +{ + memcpy(&cpu->fpc, &fpregset->fpc, sizeof(cpu->fpc)); + memcpy(&cpu->fprs, &fpregset->fprs, sizeof(cpu->fprs)); +} + +static void s390x_elf_nt_timer_add(struct s390x_cpu *cpu, void *desc) +{ + memcpy(&cpu->timer, desc, sizeof(cpu->timer)); +} + +static void s390x_elf_nt_todcmp_add(struct s390x_cpu *cpu, void *desc) +{ + memcpy(&cpu->todcmp, desc, sizeof(cpu->todcmp)); +} + +static void s390x_elf_nt_todpreg_add(struct s390x_cpu *cpu, void *desc) +{ + memcpy(&cpu->todpreg, desc, sizeof(cpu->todpreg)); +} + +static void s390x_elf_nt_ctrs_add(struct s390x_cpu *cpu, void *desc) +{ + memcpy(&cpu->ctrs, desc, sizeof(cpu->ctrs)); +} + +static void s390x_elf_nt_prefix_add(struct s390x_cpu *cpu, void *desc) +{ + memcpy(&cpu->prefix, desc, sizeof(cpu->prefix)); +} + +static void *get_elf_note_desc(Elf64_Nhdr *note) +{ + void *ptr = note; + + return ptr + roundup(sizeof(*note) + note->n_namesz, 4); +} + +static void s390x_elf_note_add(int elf_cpu_nr, void *noteptr) +{ + Elf64_Nhdr *note = (Elf64_Nhdr *)noteptr; + void *desc = get_elf_note_desc(note); + struct s390x_cpu *cpu; + + if (elf_cpu_nr != s390x_cpu_cnt) { + s390x_cpu_cnt++; + s390x_cpu_vec = realloc(s390x_cpu_vec, + s390x_cpu_cnt * sizeof(*s390x_cpu_vec)); + if (!s390x_cpu_vec) + error(FATAL, "cannot malloc cpu space."); + } + cpu = &s390x_cpu_vec[s390x_cpu_cnt - 1]; + switch (note->n_type) { + case NT_PRSTATUS: + s390x_elf_nt_prstatus_add(cpu, desc); + break; + case NT_FPREGSET: + s390x_elf_nt_fpregset_add(cpu, desc); + break; + case NT_S390_TIMER: + s390x_elf_nt_timer_add(cpu, desc); + break; + case NT_S390_TODCMP: + s390x_elf_nt_todcmp_add(cpu, desc); + break; + case NT_S390_TODPREG: + s390x_elf_nt_todpreg_add(cpu, desc); + break; + case NT_S390_CTRS: + s390x_elf_nt_ctrs_add(cpu, desc); + break; + case NT_S390_PREFIX: + s390x_elf_nt_prefix_add(cpu, desc); + break; + } +} /* * Do all necessary machine-specific setup here. This is called several @@ -89,6 +201,9 @@ { switch (when) { + case SETUP_ENV: + machdep->elf_note_add = s390x_elf_note_add; + break; case PRE_SYMTAB: machdep->verify_symbol = s390x_verify_symbol; if (pc->flags & KERNEL_DEBUG_QUERY) @@ -203,6 +318,7 @@ fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); fprintf(fp, " init_kernel_pgd: NULL\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); + fprintf(fp, " elf_note_add: s390x_elf_note_add()\n"); fprintf(fp, " line_number_hooks: s390x_line_number_hooks\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read); @@ -526,6 +642,7 @@ "Option '-e' is not implemented for this architecture\n")); } +#ifdef NOT_USED /* * returns cpu number of task */ @@ -552,6 +669,7 @@ } return cpu; } +#endif /* * returns true, if task of bt currently is executed by a cpu @@ -571,15 +689,37 @@ * read lowcore for cpu */ static void -s390x_get_lowcore(int cpu, char* lowcore) +s390x_get_lowcore(struct bt_info *bt, char* lowcore) { unsigned long lowcore_array,lowcore_ptr; + struct s390x_cpu *s390x_cpu; + int cpu = bt->tc->processor; lowcore_array = symbol_value("lowcore_ptr"); readmem(lowcore_array + cpu * S390X_WORD_SIZE,KVADDR, - &lowcore_ptr, sizeof(long), "lowcore_ptr", FAULT_ON_ERROR); - readmem(lowcore_ptr, KVADDR, lowcore, LOWCORE_SIZE, "lowcore", + &lowcore_ptr, sizeof(long), "lowcore_ptr", FAULT_ON_ERROR); + readmem(lowcore_ptr, KVADDR, lowcore, LOWCORE_SIZE, "lowcore", FAULT_ON_ERROR); + + if (!s390x_cpu_vec) + return; + + /* Copy register information to defined places in lowcore */ + s390x_cpu = s390x_cpu_get(bt); + + memcpy(lowcore + 4864, &s390x_cpu->psw, sizeof(s390x_cpu->psw)); + memcpy(lowcore + 4736, &s390x_cpu->gprs, sizeof(s390x_cpu->gprs)); + memcpy(lowcore + 4928, &s390x_cpu->acrs, sizeof(s390x_cpu->acrs)); + + memcpy(lowcore + 4892, &s390x_cpu->fpc, sizeof(s390x_cpu->fpc)); + memcpy(lowcore + 4608, &s390x_cpu->fprs, sizeof(s390x_cpu->fprs)); + + memcpy(lowcore + 4888, &s390x_cpu->prefix, sizeof(s390x_cpu->prefix)); + memcpy(lowcore + 4992, &s390x_cpu->ctrs, sizeof(s390x_cpu->ctrs)); + + memcpy(lowcore + 4900, &s390x_cpu->todpreg, sizeof(s390x_cpu->todpreg)); + memcpy(lowcore + 4904, &s390x_cpu->timer, sizeof(s390x_cpu->timer)); + memcpy(lowcore + 4912, &s390x_cpu->todcmp, sizeof(s390x_cpu->todcmp)); } /* @@ -621,13 +761,12 @@ if(s390x_has_cpu(bt)){ char lowcore[LOWCORE_SIZE]; unsigned long psw_flags; - int cpu = s390x_cpu_of_task(bt->task); if (ACTIVE()) { fprintf(fp,"(active)\n"); return; } - s390x_get_lowcore(cpu,lowcore); + s390x_get_lowcore(bt, lowcore); psw_flags = ULONG(lowcore + OFFSET(s390_lowcore_psw_save_area)); if(psw_flags & 0x1000000000000ULL){ @@ -908,7 +1047,7 @@ char lowcore[LOWCORE_SIZE]; if(s390x_has_cpu(bt)) - s390x_get_lowcore(s390x_cpu_of_task(bt->task),lowcore); + s390x_get_lowcore(bt, lowcore); /* get the stack pointer */ if(esp){ @@ -1139,5 +1278,4 @@ } } } - #endif
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility