--- crash-4.0-4.5/main.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/main.c 2007-08-21 16:02:46.000000000 -0400 @@ -70,7 +70,7 @@ */ opterr = 0; optind = 0; - while((c = getopt_long(argc, argv, "Lgh::e:i:sSvc:d:tfp:m:", + while((c = getopt_long(argc, argv, "Lkgh::e:i:sSvc:d:tfp:m:", long_options, &option_index)) != -1) { switch (c) { @@ -223,6 +223,10 @@ program_usage(LONG_FORM); clean_exit(0); + case 'k': + pc->flags |= KERNTYPES; + break; + case 'e': if (STREQ(optarg, "vi")) pc->editing_mode = "vi"; --- crash-4.0-4.5/task.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/task.c 2007-07-31 16:09:39.000000000 -0400 @@ -50,6 +50,15 @@ static void dump_runq(void); static void dump_runqueues(void); static void dump_prio_array(int, ulong, char *); +struct rb_root; +static struct rb_node *rb_first(struct rb_root *); +struct rb_node; +static struct rb_node *rb_next(struct rb_node *); +static struct rb_node *rb_parent(struct rb_node *, struct rb_node *); +static struct rb_node *rb_right(struct rb_node *, struct rb_node *); +static struct rb_node *rb_left(struct rb_node *, struct rb_node *); +static void dump_CFS_runqueues(void); +static void dump_RT_prio_array(int, ulong, char *); static void task_struct_member(struct task_context *,ulong,struct reference *); static void signal_reference(struct task_context *, ulong, struct reference *); static void do_sig_thread_group(ulong); @@ -5834,6 +5843,11 @@ ulong *tlist; struct task_context *tc; + if (VALID_MEMBER(rq_cfs)) { + dump_CFS_runqueues(); + return; + } + if (VALID_MEMBER(runqueue_arrays)) { dump_runqueues(); return; @@ -6006,6 +6020,222 @@ } } +/* + * CFS scheduler uses Red-Black trees to maintain run queue. + */ +struct rb_node +{ + unsigned long rb_parent_color; +#define RB_RED 0 +#define RB_BLACK 1 + struct rb_node *rb_right; + struct rb_node *rb_left; +}; + +struct rb_root +{ + struct rb_node *rb_node; +}; + +static struct rb_node * +rb_first(struct rb_root *root) +{ + struct rb_root rloc; + struct rb_node *n; + struct rb_node nloc; + + readmem((ulong)root, KVADDR, &rloc, sizeof(struct rb_root), + "rb_root", FAULT_ON_ERROR); + + n = rloc.rb_node; + if (!n) + return NULL; + while (rb_left(n, &nloc)) + n = nloc.rb_left; + + return n; +} + +static struct rb_node * +rb_parent(struct rb_node *node, struct rb_node *nloc) +{ + readmem((ulong)node, KVADDR, nloc, sizeof(struct rb_node), + "rb_node", FAULT_ON_ERROR); + + return (struct rb_node *)(nloc->rb_parent_color & ~3); +} + +static struct rb_node * +rb_right(struct rb_node *node, struct rb_node *nloc) +{ + readmem((ulong)node, KVADDR, nloc, sizeof(struct rb_node), + "rb_node", FAULT_ON_ERROR); + + return nloc->rb_right; +} + +static struct rb_node * +rb_left(struct rb_node *node, struct rb_node *nloc) +{ + readmem((ulong)node, KVADDR, nloc, sizeof(struct rb_node), + "rb_node", FAULT_ON_ERROR); + + return nloc->rb_left; +} + +static struct rb_node * +rb_next(struct rb_node *node) +{ + struct rb_node nloc; + struct rb_node *parent; + + parent = rb_parent(node, &nloc); + + if (parent == node) + return NULL; + + if (nloc.rb_right) { + node = nloc.rb_right; + while (rb_left(node, &nloc)) + node = nloc.rb_left; + return node; + } + + while ((parent = rb_parent(node, &nloc)) && (node == rb_right(parent, &nloc))) + node = parent; + + return parent; +} + +static void +dump_CFS_runqueues(void) +{ + int cpu; + ulong runq; + char *runqbuf; + ulong leftmost, tasks_timeline; + struct task_context *tc; + long nr_running, cfs_rq_nr_running; + struct rb_root *root; + struct rb_node *node; + + if (INVALID_MEMBER(rq_rt)) { + MEMBER_OFFSET_INIT(rq_rt, "rq", "rt"); + MEMBER_OFFSET_INIT(rq_nr_running, "rq", "nr_running"); + MEMBER_OFFSET_INIT(task_struct_se, "task_struct", "se"); + MEMBER_OFFSET_INIT(sched_entity_run_node, "sched_entity", + "run_node"); + MEMBER_OFFSET_INIT(cfs_rq_rb_leftmost, "cfs_rq", "rb_leftmost"); + MEMBER_OFFSET_INIT(cfs_rq_nr_running, "cfs_rq", "nr_running"); + MEMBER_OFFSET_INIT(cfs_rq_tasks_timeline, "cfs_rq", + "tasks_timeline"); + MEMBER_OFFSET_INIT(rt_rq_active, "rt_rq", "active"); + MEMBER_OFFSET_INIT(task_struct_run_list, "task_struct", + "run_list"); + } + + if (!symbol_exists("per_cpu__runqueues")) + error(FATAL, "per_cpu__runqueues does not exist\n"); + + runq = symbol_value("per_cpu__runqueues"); + + runqbuf = GETBUF(SIZE(runqueue)); + + for (cpu = 0; cpu < kt->cpus; cpu++) { + if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) { + runq = symbol_value("per_cpu__runqueues") + + kt->__per_cpu_offset[cpu]; + } else + runq = symbol_value("per_cpu__runqueues"); + + fprintf(fp, "RUNQUEUES[%d]: %lx\n", cpu, runq); + + readmem(runq, KVADDR, runqbuf, SIZE(runqueue), + "per-cpu rq", FAULT_ON_ERROR); + leftmost = ULONG(runqbuf + OFFSET(rq_cfs) + + OFFSET(cfs_rq_rb_leftmost)); + tasks_timeline = ULONG(runqbuf + OFFSET(rq_cfs) + + OFFSET(cfs_rq_tasks_timeline)); + nr_running = LONG(runqbuf + OFFSET(rq_nr_running)); + cfs_rq_nr_running = ULONG(runqbuf + OFFSET(rq_cfs) + + OFFSET(cfs_rq_nr_running)); + + dump_RT_prio_array(nr_running != cfs_rq_nr_running, + runq + OFFSET(rq_rt) + OFFSET(rt_rq_active), + &runqbuf[OFFSET(rq_rt) + OFFSET(rt_rq_active)]); + + root = (struct rb_root *)(runq + OFFSET(rq_cfs) + OFFSET(cfs_rq_tasks_timeline)); + fprintf(fp, " CFS RB_ROOT: %lx\n", (ulong)root); + + if (!leftmost) + continue; + + for (node = rb_first(root); node; node = rb_next(node)) { + tc = task_to_context((ulong)node - OFFSET(task_struct_se) - + OFFSET(sched_entity_run_node)); + if (!tc) + continue; + INDENT(2); + print_task_header(fp, tc, FALSE); + } + } +} + +static void +dump_RT_prio_array(int active, ulong k_prio_array, char *u_prio_array) +{ + int i, c, cnt, qheads; + ulong offset, kvaddr, uvaddr; + ulong list_head[2]; + struct list_data list_data, *ld; + struct task_context *tc; + ulong *tlist; + + fprintf(fp, " RT PRIO_ARRAY: %lx\n", k_prio_array); + + if (!active) + return; + + qheads = (i = ARRAY_LENGTH(prio_array_queue)) ? + i : get_array_length("prio_array.queue", NULL, SIZE(list_head)); + + ld = &list_data; + + for (i = 0; i < qheads; i++) { + offset = OFFSET(prio_array_queue) + (i * SIZE(list_head)); + kvaddr = k_prio_array + offset; + uvaddr = (ulong)u_prio_array + offset; + BCOPY((char *)uvaddr, (char *)&list_head[0], sizeof(ulong)*2); + + if (CRASHDEBUG(1)) + fprintf(fp, "prio_array[%d] @ %lx => %lx/%lx\n", + i, kvaddr, list_head[0], list_head[1]); + + if ((list_head[0] == kvaddr) && (list_head[1] == kvaddr)) + continue; + + fprintf(fp, " [%3d] ", i); + + BZERO(ld, sizeof(struct list_data)); + ld->start = list_head[0]; + ld->list_head_offset = OFFSET(task_struct_run_list); + ld->end = kvaddr; + hq_open(); + cnt = do_list(ld); + hq_close(); + tlist = (ulong *)GETBUF((cnt) * sizeof(ulong)); + cnt = retrieve_list(tlist, cnt); + for (c = 0; c < cnt; c++) { + if (!(tc = task_to_context(tlist[c]))) + continue; + if (c) + INDENT(8); + print_task_header(fp, tc, FALSE); + } + FREEBUF(tlist); + } +} + #undef _NSIG #define _NSIG 64 #define _NSIG_BPW machdep->bits --- crash-4.0-4.5/kernel.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/kernel.c 2007-07-31 16:05:45.000000000 -0400 @@ -219,6 +219,8 @@ STRUCT_SIZE_INIT(runqueue, rqstruct); STRUCT_SIZE_INIT(prio_array, "prio_array"); + MEMBER_OFFSET_INIT(rq_cfs, "rq", "cfs"); + /* * In 2.4, smp_send_stop() sets smp_num_cpus back to 1 * in some, but not all, architectures. So if a count --- crash-4.0-4.5/gdb_interface.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/gdb_interface.c 2007-07-31 16:05:22.000000000 -0400 @@ -647,7 +647,7 @@ }; #define RESTRICTED_GDB_COMMAND \ - "restricted gdb command: %s\n%s\"%s\" may only be used in a .gdbinit file or in a command file.\n%sThe .gdbinit file is read automatically during %s initialization.\n%sOther user-defined command files may be read interactively during\n%s%s runtime by using the gdb \"source\" command." + "restricted gdb command: %s\n%s\"%s\" may only be used in a .gdbinit file or in a command file.\n%sThe .gdbinit file is read automatically during %s initialization.\n%sOther user-defined command files may be read interactively during\n%s%s runtime by using the gdb \"source\" command.\n" static int is_restricted_command(char *cmd, ulong flags) --- crash-4.0-4.5/ia64.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/ia64.c 2007-08-23 17:02:53.000000000 -0400 @@ -4063,7 +4063,7 @@ } /* frametable virtual address */ - addr = kvaddr - VIRT_FRAME_TABLE_ADDR; + addr = kvaddr - xhmachdep->frame_table; dirp = symbol_value("frametable_pg_dir"); dirp += ((addr >> PGDIR_SHIFT_3L) & (PTRS_PER_PGD - 1)) * sizeof(ulong); @@ -4095,6 +4095,7 @@ ia64_post_init_hyper(void) { struct machine_specific *ms; + ulong frame_table; ms = &ia64_machine_specific; @@ -4127,6 +4128,14 @@ ms->unwind = ia64_old_unwind; } ms->unwind_init(); + + if (symbol_exists("frame_table")) { + frame_table = symbol_value("frame_table"); + readmem(frame_table, KVADDR, &xhmachdep->frame_table, sizeof(ulong), + "frame_table virtual address", FAULT_ON_ERROR); + } else { + error(FATAL, "cannot find frame_table virtual address."); + } } int --- crash-4.0-4.5/x86_64.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/x86_64.c 2007-08-23 17:02:54.000000000 -0400 @@ -5417,7 +5417,7 @@ case POST_GDB: XEN_HYPER_STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86"); XEN_HYPER_STRUCT_SIZE_INIT(tss_struct, "tss_struct"); - XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_rsp0, "tss_struct", "rsp0"); + XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "__blh") + sizeof(short unsigned int); XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_ist, "tss_struct", "ist"); if (symbol_exists("cpu_data")) { xht->cpu_data_address = symbol_value("cpu_data"); --- crash-4.0-4.5/symbols.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/symbols.c 2007-07-31 16:05:08.000000000 -0400 @@ -6768,6 +6768,25 @@ fprintf(fp, " unwind_table_name: %ld\n", OFFSET(unwind_table_name)); + fprintf(fp, " rq_cfs: %ld\n", + OFFSET(rq_cfs)); + fprintf(fp, " rq_rt: %ld\n", + OFFSET(rq_rt)); + fprintf(fp, " rq_nr_running: %ld\n", + OFFSET(rq_nr_running)); + fprintf(fp, " task_struct_se: %ld\n", + OFFSET(task_struct_se)); + fprintf(fp, " sched_entity_run_node: %ld\n", + OFFSET(sched_entity_run_node)); + fprintf(fp, " cfs_rq_nr_running: %ld\n", + OFFSET(cfs_rq_nr_running)); + fprintf(fp, " cfs_rq_rb_leftmost: %ld\n", + OFFSET(cfs_rq_rb_leftmost)); + fprintf(fp, " cfs_rq_tasks_timeline: %ld\n", + OFFSET(cfs_rq_tasks_timeline)); + fprintf(fp, " rt_rq_active: %ld\n", + OFFSET(rt_rq_active)); + fprintf(fp, "\n size_table:\n"); fprintf(fp, " page: %ld\n", SIZE(page)); fprintf(fp, " free_area_struct: %ld\n", --- crash-4.0-4.5/lkcd_x86_trace.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/lkcd_x86_trace.c 2007-08-23 17:02:54.000000000 -0400 @@ -1424,7 +1424,8 @@ #ifdef REDHAT if (XEN_HYPER_MODE()) { func_name = kl_funcname(pc); - if (STREQ(func_name, "idle_loop") || STREQ(func_name, "hypercall")) { + if (STREQ(func_name, "idle_loop") || STREQ(func_name, "hypercall") + || STREQ(func_name, "handle_exception")) { UPDATE_FRAME(func_name, pc, 0, sp, bp, asp, 0, 0, bp - sp, 0); return(trace->nframes); } @@ -1681,7 +1682,9 @@ } } if (func_name && XEN_HYPER_MODE()) { - if (STREQ(func_name, "continue_nmi")) { + if (STREQ(func_name, "continue_nmi") || + STREQ(func_name, "vmx_asm_vmexit_handler") || + STREQ(func_name, "deferred_nmi")) { /* Interrupt frame */ sp = curframe->fp + 4; asp = (uaddr_t*)((uaddr_t)sbp + (STACK_SIZE - @@ -1697,6 +1700,8 @@ sp = curframe->fp + 4; bp = sp + get_framesize(pc, bt); func_name = kl_funcname(pc); + if (!func_name) + return trace->nframes; continue; } } --- crash-4.0-4.5/xen_hyper.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/xen_hyper.c 2007-08-23 17:02:54.000000000 -0400 @@ -51,13 +51,16 @@ machdep->memory_size(); #ifdef IA64 - if((xht->__per_cpu_offset = malloc(sizeof(ulong) * XEN_HYPER_MAX_CPUS())) == NULL) { - error(FATAL, "cannot malloc __per_cpu_offset space.\n"); - } - if (!readmem(symbol_value("__per_cpu_offset"), KVADDR, - xht->__per_cpu_offset, sizeof(ulong) * XEN_HYPER_MAX_CPUS(), - "__per_cpu_offset", RETURN_ON_ERROR)) { - error(FATAL, "cannot read __per_cpu_offset.\n"); + if (symbol_exists("__per_cpu_offset")) { + xht->flags |= XEN_HYPER_SMP; + if((xht->__per_cpu_offset = malloc(sizeof(ulong) * XEN_HYPER_MAX_CPUS())) == NULL) { + error(FATAL, "cannot malloc __per_cpu_offset space.\n"); + } + if (!readmem(symbol_value("__per_cpu_offset"), KVADDR, + xht->__per_cpu_offset, sizeof(ulong) * XEN_HYPER_MAX_CPUS(), + "__per_cpu_offset", RETURN_ON_ERROR)) { + error(FATAL, "cannot read __per_cpu_offset.\n"); + } } #endif @@ -169,6 +172,14 @@ XEN_HYPER_MEMBER_OFFSET_INIT(domain_next_in_list, "domain", "next_in_list"); XEN_HYPER_MEMBER_OFFSET_INIT(domain_domain_flags, "domain", "domain_flags"); XEN_HYPER_MEMBER_OFFSET_INIT(domain_evtchn, "domain", "evtchn"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_hvm, "domain", "is_hvm"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_privileged, "domain", "is_privileged"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_debugger_attached, "domain", "debugger_attached"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_polling, "domain", "is_polling"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_dying, "domain", "is_dying"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_paused_by_controller, "domain", "is_paused_by_controller"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_shutting_down, "domain", "is_shutting_down"); + XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_shut_down, "domain", "is_shut_down"); XEN_HYPER_MEMBER_OFFSET_INIT(domain_vcpu, "domain", "vcpu"); XEN_HYPER_MEMBER_OFFSET_INIT(domain_arch, "domain", "arch"); @@ -533,9 +544,10 @@ { Elf32_Nhdr *note; char *buf, *bp, *np, *upp; + char *nccp, *xccp; ulong addr; long size; - int i, cpuid; + int i, cpuid, samp_cpuid; /* * NOTE kakuma: It is not clear that what kind of @@ -546,10 +558,13 @@ xhdit->note_ver = XEN_HYPER_ELF_NOTE_V1; else if (STRUCT_EXISTS("crash_note_xen_t")) xhdit->note_ver = XEN_HYPER_ELF_NOTE_V2; - else if (STRUCT_EXISTS("crash_note_xen_core_t")) - xhdit->note_ver = XEN_HYPER_ELF_NOTE_V3; - else { - error(WARNING, "unsupported elf note format.\n"); + else if (STRUCT_EXISTS("crash_xen_core_t")) { + if (STRUCT_EXISTS("crash_note_xen_core_t")) + xhdit->note_ver = XEN_HYPER_ELF_NOTE_V3; + else + xhdit->note_ver = XEN_HYPER_ELF_NOTE_V4; + } else { + error(WARNING, "found unsupported elf note format while checking of xen dumpinfo.\n"); return; } if (!xen_hyper_test_pcpu_id(XEN_HYPER_CRASHING_CPU())) { @@ -557,30 +572,55 @@ return; } + /* allocate a context area */ size = sizeof(struct xen_hyper_dumpinfo_context) * XEN_HYPER_MAX_CPUS(); if((xhdit->context_array = malloc(size)) == NULL) { error(FATAL, "cannot malloc dumpinfo table context space.\n"); } BZERO(xhdit->context_array, size); + size = sizeof(struct xen_hyper_dumpinfo_context_xen_core) * XEN_HYPER_MAX_CPUS(); + if((xhdit->context_xen_core_array = malloc(size)) == NULL) { + error(FATAL, "cannot malloc dumpinfo table context_xen_core_array space.\n"); + } + BZERO(xhdit->context_xen_core_array, size); addr = symbol_value("per_cpu__crash_notes"); for (i = 0; i < XEN_HYPER_MAX_CPUS(); i++) { - xhdit->context_array[i].note = xen_hyper_per_cpu(addr, i); + ulong addr_notes; + + addr_notes = xen_hyper_per_cpu(addr, i); + if (xhdit->note_ver == XEN_HYPER_ELF_NOTE_V4) { + if (!readmem(addr_notes, KVADDR, &(xhdit->context_array[i].note), + sizeof(ulong), "per_cpu__crash_notes", RETURN_ON_ERROR)) { + error(WARNING, "cannot read per_cpu__crash_notes.\n"); + return; + } + } else { + xhdit->context_array[i].note = addr_notes; + } } if (xhdit->note_ver == XEN_HYPER_ELF_NOTE_V1) { xhdit->note_size = XEN_HYPER_SIZE(note_buf_t); + } else if (xhdit->note_ver == XEN_HYPER_ELF_NOTE_V4) { + xhdit->note_size = XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE; } else { xhdit->note_size = XEN_HYPER_SIZE(crash_note_t); } - + /* read a sample note */ buf = GETBUF(xhdit->note_size); - if (!xen_hyper_fill_elf_notes(xhdit->context_array[XEN_HYPER_CRASHING_CPU()].note, + if (xhdit->note_ver == XEN_HYPER_ELF_NOTE_V4) + samp_cpuid = xht->cpu_idxs[0]; + else + samp_cpuid = XEN_HYPER_CRASHING_CPU(); + xhdit->xen_info_cpu = samp_cpuid; + if (!xen_hyper_fill_elf_notes(xhdit->context_array[samp_cpuid].note, buf, XEN_HYPER_ELF_NOTE_FILL_T_NOTE)) { error(FATAL, "cannot read per_cpu__crash_notes.\n"); } bp = buf; + /* Get elf format information for each version. */ switch (xhdit->note_ver) { case XEN_HYPER_ELF_NOTE_V1: /* core data */ @@ -604,19 +644,6 @@ /* xen core */ xhdit->xen_info_offset = XEN_HYPER_OFFSET(crash_note_xen_t_desc); xhdit->xen_info_size = XEN_HYPER_SIZE(crash_note_xen_t); - if((xhdit->crash_note_xen_info_ptr = - malloc(xhdit->xen_info_size)) == NULL) { - error(FATAL, "cannot malloc dumpinfo table " - "crash_note_xen_info_ptr space.\n"); - } - memcpy(xhdit->crash_note_xen_info_ptr, - bp + xhdit->core_size, xhdit->xen_info_size); - xhdit->context_xen_info.note = - xhdit->context_array[XEN_HYPER_CRASHING_CPU()].note + - xhdit->core_size; - xhdit->context_xen_info.pcpu_id = XEN_HYPER_CRASHING_CPU(); - xhdit->context_xen_info.crash_xen_info_ptr = - xhdit->crash_note_xen_info_ptr + xhdit->xen_info_offset; break; case XEN_HYPER_ELF_NOTE_V3: /* core data */ @@ -625,22 +652,57 @@ /* xen core */ xhdit->xen_core_offset = XEN_HYPER_OFFSET(crash_note_xen_core_t_desc); xhdit->xen_core_size = XEN_HYPER_SIZE(crash_note_xen_core_t); - if((xhdit->crash_note_xen_core_ptr = - malloc(xhdit->xen_core_size)) == NULL) { - error(FATAL, "cannot malloc dumpinfo table " - "crash_note_xen_core_ptr space.\n"); - } - memcpy(xhdit->crash_note_xen_core_ptr, - bp + xhdit->core_size, xhdit->xen_core_size); - xhdit->context_xen_core.note = - xhdit->context_array[XEN_HYPER_CRASHING_CPU()].note + - xhdit->core_size; - xhdit->context_xen_core.pcpu_id = XEN_HYPER_CRASHING_CPU(); - xhdit->context_xen_core.crash_xen_core_ptr = - xhdit->crash_note_xen_core_ptr + xhdit->xen_core_offset; /* xen info */ xhdit->xen_info_offset = XEN_HYPER_OFFSET(crash_note_xen_info_t_desc); xhdit->xen_info_size = XEN_HYPER_SIZE(crash_note_xen_info_t); + break; + case XEN_HYPER_ELF_NOTE_V4: + /* core data */ + note = (Elf32_Nhdr *)bp; + np = bp + sizeof(Elf32_Nhdr); + upp = np + note->n_namesz; + upp = (char *)roundup((ulong)upp, 4); + xhdit->core_offset = (Elf_Word)((ulong)upp - (ulong)note); + upp = upp + note->n_descsz; + xhdit->core_size = (Elf_Word)((ulong)upp - (ulong)note); + if (XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE < xhdit->core_size + 32) { + error(WARNING, "note size is assumed on crash is incorrect.(core data)\n"); + return; + } + /* xen core */ + note = (Elf32_Nhdr *)upp; + np = (char *)note + sizeof(Elf32_Nhdr); + upp = np + note->n_namesz; + upp = (char *)roundup((ulong)upp, 4); + xhdit->xen_core_offset = (Elf_Word)((ulong)upp - (ulong)note); + upp = upp + note->n_descsz; + xhdit->xen_core_size = (Elf_Word)((ulong)upp - (ulong)note); + if (XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE < + xhdit->core_size + xhdit->xen_core_size + 32) { + error(WARNING, "note size is assumed on crash is incorrect.(xen core)\n"); + return; + } + /* xen info */ + note = (Elf32_Nhdr *)upp; + np = (char *)note + sizeof(Elf32_Nhdr); + upp = np + note->n_namesz; + upp = (char *)roundup((ulong)upp, 4); + xhdit->xen_info_offset = (Elf_Word)((ulong)upp - (ulong)note); + upp = upp + note->n_descsz; + xhdit->xen_info_size = (Elf_Word)((ulong)upp - (ulong)note); + if (XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE < + xhdit->core_size + xhdit->xen_core_size + xhdit->xen_info_size) { + error(WARNING, "note size is assumed on crash is incorrect.(xen info)\n"); + return; + } + xhdit->note_size = xhdit->core_size + xhdit->xen_core_size + xhdit->xen_info_size; + break; + default: + error(FATAL, "logic error in cheking elf note format occurs.\n"); + } + + /* fill xen info context. */ + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V3) { if((xhdit->crash_note_xen_info_ptr = malloc(xhdit->xen_info_size)) == NULL) { error(FATAL, "cannot malloc dumpinfo table " @@ -650,37 +712,75 @@ bp + xhdit->core_size + xhdit->xen_core_size, xhdit->xen_info_size); xhdit->context_xen_info.note = - xhdit->context_array[XEN_HYPER_CRASHING_CPU()].note + + xhdit->context_array[samp_cpuid].note + xhdit->core_size + xhdit->xen_core_size; - xhdit->context_xen_info.pcpu_id = XEN_HYPER_CRASHING_CPU(); + xhdit->context_xen_info.pcpu_id = samp_cpuid; xhdit->context_xen_info.crash_xen_info_ptr = xhdit->crash_note_xen_info_ptr + xhdit->xen_info_offset; - break; - default: - error(FATAL, "logic error in cheking elf note format occurs.\n"); } - + + /* allocate note core */ size = xhdit->core_size * XEN_HYPER_NR_PCPUS(); if(!(xhdit->crash_note_core_array = malloc(size))) { - error(FATAL, "cannot malloc note_buf_t struct space.\n"); + error(FATAL, "cannot malloc crash_note_core_array space.\n"); } - bp = xhdit->crash_note_core_array; - BZERO(bp, size); + nccp = xhdit->crash_note_core_array; + BZERO(nccp, size); + + /* allocate xen core */ + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V2) { + size = xhdit->xen_core_size * XEN_HYPER_NR_PCPUS(); + if(!(xhdit->crash_note_xen_core_array = malloc(size))) { + error(FATAL, "cannot malloc dumpinfo table " + "crash_note_xen_core_array space.\n"); + } + xccp = xhdit->crash_note_xen_core_array; + BZERO(xccp, size); + } + + /* fill a context. */ for_cpu_indexes(i, cpuid) { + /* fill core context. */ addr = xhdit->context_array[cpuid].note; - if (!xen_hyper_fill_elf_notes(addr, bp, + if (!xen_hyper_fill_elf_notes(addr, nccp, XEN_HYPER_ELF_NOTE_FILL_T_CORE)) { - error(FATAL, "cannot read ELF_Prstatus.\n"); + error(FATAL, "cannot read elf note core.\n"); } xhdit->context_array[cpuid].pcpu_id = cpuid; xhdit->context_array[cpuid].ELF_Prstatus_ptr = - bp + xhdit->core_offset; + nccp + xhdit->core_offset; xhdit->context_array[cpuid].pr_reg_ptr = - bp + xhdit->core_offset + + nccp + xhdit->core_offset + XEN_HYPER_OFFSET(ELF_Prstatus_pr_reg); - bp += xhdit->core_size; + + /* Is there xen core data? */ + if (xhdit->note_ver < XEN_HYPER_ELF_NOTE_V2) { + nccp += xhdit->core_size; + continue; + } + if (xhdit->note_ver == XEN_HYPER_ELF_NOTE_V2 && + cpuid != samp_cpuid) { + xccp += xhdit->xen_core_size; + nccp += xhdit->core_size; + continue; + } + + /* fill xen core context, in case of more elf note V2. */ + xhdit->context_xen_core_array[cpuid].note = + xhdit->context_array[cpuid].note + + xhdit->core_size; + xhdit->context_xen_core_array[cpuid].pcpu_id = cpuid; + xhdit->context_xen_core_array[cpuid].crash_xen_core_ptr = + xccp + xhdit->xen_core_offset; + if (!xen_hyper_fill_elf_notes(xhdit->context_xen_core_array[cpuid].note, + xccp, XEN_HYPER_ELF_NOTE_FILL_T_XEN_CORE)) { + error(FATAL, "cannot read elf note xen core.\n"); + } + xccp += xhdit->xen_core_size; + nccp += xhdit->core_size; } + FREEBUF(buf); } @@ -713,11 +813,14 @@ /* * Fill ELF Notes header here. + * This assume that variable note has a top address of an area for + * specified type. */ char * xen_hyper_fill_elf_notes(ulong note, char *note_buf, int type) { long size; + ulong rp = note; if (type == XEN_HYPER_ELF_NOTE_FILL_T_NOTE) size = xhdit->note_size; @@ -725,6 +828,8 @@ size = xhdit->core_size; else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_CORE) size = xhdit->xen_core_size; + else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_CORE_M) + size = xhdit->core_size + xhdit->xen_core_size; else if (type == XEN_HYPER_ELF_NOTE_FILL_T_PRS) size = XEN_HYPER_SIZE(ELF_Prstatus); else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_REGS) @@ -732,7 +837,7 @@ else return NULL; - if (!readmem(note, KVADDR, note_buf, size, + if (!readmem(rp, KVADDR, note_buf, size, "note_buf_t or crash_note_t", RETURN_ON_ERROR)) { if (type == XEN_HYPER_ELF_NOTE_FILL_T_NOTE) error(WARNING, "cannot fill note_buf_t or crash_note_t.\n"); @@ -740,6 +845,8 @@ error(WARNING, "cannot fill note core.\n"); else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_CORE) error(WARNING, "cannot fill note xen core.\n"); + else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_CORE_M) + error(WARNING, "cannot fill note core & xen core.\n"); else if (type == XEN_HYPER_ELF_NOTE_FILL_T_PRS) error(WARNING, "cannot fill ELF_Prstatus.\n"); else if (type == XEN_HYPER_ELF_NOTE_FILL_T_XEN_REGS) @@ -1051,8 +1158,28 @@ dc->next_in_list = ULONG(dp + XEN_HYPER_OFFSET(domain_next_in_list)); if (XEN_HYPER_VALID_MEMBER(domain_domain_flags)) dc->domain_flags = ULONG(dp + XEN_HYPER_OFFSET(domain_domain_flags)); - else + else if (XEN_HYPER_VALID_MEMBER(domain_is_shut_down)) { + dc->domain_flags = 0; + if (*(dp + XEN_HYPER_OFFSET(domain_is_hvm))) { + dc->domain_flags |= XEN_HYPER_DOMS_HVM; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_privileged))) { + dc->domain_flags |= XEN_HYPER_DOMS_privileged; + } else if (*(dp + XEN_HYPER_OFFSET(domain_debugger_attached))) { + dc->domain_flags |= XEN_HYPER_DOMS_debugging; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_polling))) { + dc->domain_flags |= XEN_HYPER_DOMS_polling; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_paused_by_controller))) { + dc->domain_flags |= XEN_HYPER_DOMS_ctrl_pause; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_dying))) { + dc->domain_flags |= XEN_HYPER_DOMS_dying; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_shutting_down))) { + dc->domain_flags |= XEN_HYPER_DOMS_shuttingdown; + } else if (*(dp + XEN_HYPER_OFFSET(domain_is_shut_down))) { + dc->domain_flags |= XEN_HYPER_DOMS_shutdown; + } + } else { dc->domain_flags = XEN_HYPER_DOMF_ERROR; + } dc->evtchn = ULONG(dp + XEN_HYPER_OFFSET(domain_evtchn)); for (i = 0; i < XEN_HYPER_MAX_VIRT_CPUS; i++) { dc->vcpu[i] = ULONG(dp + XEN_HYPER_OFFSET(domain_vcpu) + i*sizeof(void *)); --- crash-4.0-4.5/xen_hyper_command.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/xen_hyper_command.c 2007-08-23 17:02:54.000000000 -0400 @@ -429,7 +429,17 @@ } sprintf(buf, " PCID "); mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|RJUST, "ENOTE"); - sprintf(&buf[strlen(buf)], " PID PPID PGRP SID"); +// sprintf(&buf[strlen(buf)], " PID PPID PGRP SID"); + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|RJUST, "CORE"); + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V2) { + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|RJUST, "XEN_CORE"); + } + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V3) { + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|RJUST, "XEN_INFO"); + } fprintf(fp, "%s\n", buf); } if (dia->cnt) { @@ -449,7 +459,7 @@ ulong addr; ulong *regs; long tv_sec, tv_usec; - int pid, i, regcnt; + int i, regcnt; if (!dic || !dic->note) { return; @@ -460,6 +470,7 @@ mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|LONG_HEX|RJUST, MKSTR(dic->note)); +#if 0 pid = INT(note_buf + XEN_HYPER_OFFSET(ELF_Prstatus_pr_pid)); sprintf(&buf[strlen(buf)], " %5d ", pid); pid = INT(note_buf + XEN_HYPER_OFFSET(ELF_Prstatus_pr_ppid)); @@ -468,6 +479,24 @@ sprintf(&buf[strlen(buf)], "%5d ", pid); pid = INT(note_buf + XEN_HYPER_OFFSET(ELF_Prstatus_pr_sid)); sprintf(&buf[strlen(buf)], "%5d", pid); +#endif + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|LONG_HEX|RJUST, + MKSTR(dic->note)); + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V2) { + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|LONG_HEX|RJUST, + MKSTR(dic->note + xhdit->core_size)); + } + if (xhdit->note_ver >= XEN_HYPER_ELF_NOTE_V3) { + strncat(buf, " ", XEN_HYPER_CMD_BUFSIZE-strlen(buf)-1); + if (xhdit->xen_info_cpu == dic->pcpu_id) + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|LONG_HEX|RJUST, + MKSTR(dic->note + xhdit->core_size + xhdit->xen_core_size)); + else + mkstring(&buf[strlen(buf)], VADDR_PRLEN, CENTER|RJUST, "--"); + + } fprintf(fp, "%s\n", buf); @@ -515,7 +544,8 @@ addr = (ulong)note_buf + XEN_HYPER_OFFSET(ELF_Prstatus_pr_reg); regs = (ulong *)addr; - fprintf(fp, "Register information:\n"); + fprintf(fp, "Register information(%lx):\n", + dic->note + xhdit->core_offset + XEN_HYPER_OFFSET(ELF_Prstatus_pr_reg)); for (i = 0; i < regcnt; i++, regs++) { if (xhregt[i] == NULL) { break; @@ -1256,18 +1286,34 @@ if (stat == XEN_HYPER_DOMF_ERROR) { sprintf(buf, verbose ? "(unknown)" : "??"); - } else if (stat & XEN_HYPER_DOMF_shutdown) { - sprintf(buf, verbose ? "DOMAIN_SHUTDOWN" : "SH"); - } else if (stat & XEN_HYPER_DOMF_dying) { - sprintf(buf, verbose ? "DOMAIN_DYING" : "DY"); - } else if (stat & XEN_HYPER_DOMF_ctrl_pause) { - sprintf(buf, verbose ? "DOMAIN_CTRL_PAUSE" : "CP"); - } else if (stat & XEN_HYPER_DOMF_polling) { - sprintf(buf, verbose ? "DOMAIN_POLLING" : "PO"); - } else if (stat & XEN_HYPER_DOMF_paused) { - sprintf(buf, verbose ? "DOMAIN_PAUSED" : "PA"); + } else if (XEN_HYPER_VALID_MEMBER(domain_domain_flags)) { + if (stat & XEN_HYPER_DOMF_shutdown) { + sprintf(buf, verbose ? "DOMAIN_SHUTDOWN" : "SF"); + } else if (stat & XEN_HYPER_DOMF_dying) { + sprintf(buf, verbose ? "DOMAIN_DYING" : "DY"); + } else if (stat & XEN_HYPER_DOMF_ctrl_pause) { + sprintf(buf, verbose ? "DOMAIN_CTRL_PAUSE" : "CP"); + } else if (stat & XEN_HYPER_DOMF_polling) { + sprintf(buf, verbose ? "DOMAIN_POLLING" : "PO"); + } else if (stat & XEN_HYPER_DOMF_paused) { + sprintf(buf, verbose ? "DOMAIN_PAUSED" : "PA"); + } else { + sprintf(buf, verbose ? "DOMAIN_RUNNING" : "RU"); + } } else { - sprintf(buf, verbose ? "DOMAIN_RUNNING" : "RU"); + if (stat & XEN_HYPER_DOMS_shutdown) { + sprintf(buf, verbose ? "DOMAIN_SHUTDOWN" : "SF"); + } else if (stat & XEN_HYPER_DOMS_shuttingdown) { + sprintf(buf, verbose ? "DOMAIN_SHUTTINGDOWN" : "SH"); + } else if (stat & XEN_HYPER_DOMS_dying) { + sprintf(buf, verbose ? "DOMAIN_DYING" : "DY"); + } else if (stat & XEN_HYPER_DOMS_ctrl_pause) { + sprintf(buf, verbose ? "DOMAIN_CTRL_PAUSE" : "CP"); + } else if (stat & XEN_HYPER_DOMS_polling) { + sprintf(buf, verbose ? "DOMAIN_POLLING" : "PO"); + } else { + sprintf(buf, verbose ? "DOMAIN_RUNNING" : "RU"); + } } return buf; --- crash-4.0-4.5/xen_hyper_global_data.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/xen_hyper_global_data.c 2007-08-23 17:02:54.000000000 -0400 @@ -130,8 +130,11 @@ " ", " 1. the DOMAIN-ID.", " 2. the struct domain pointer.", -" 3. the domain state (SH, DY, CP, PO, PA, RU).", -" 4. the TYPE of domain.", +" 3. the domain state", +" (SF:fully shut down, SH:shutting down, DY:dying,", +" CP:pause by controller software, PO:polling event channels,", +" PA:pause by the hypervisor, RU:running).", +" 4. the TYPE of domain", " (O:dom_io, X:dom_xen, I:idle domain, 0:domain 0, U:domain U).", " 5. displays max_pages member of domain.", " 6. displays tot_pages member of domain.", --- crash-4.0-4.5/xen_hyper_dump_tables.c 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/xen_hyper_dump_tables.c 2007-08-23 17:02:54.000000000 -0400 @@ -262,13 +262,13 @@ sizeof(struct xen_hyper_dumpinfo_context) * XEN_HYPER_MAX_CPUS(), sizeof(long)); } - XEN_HYPER_PRI_CONST(fp, len, "context_xen_core: ", flag|XEN_HYPER_PRI_LF); - XEN_HYPER_PRI(fp, len, "note: ", buf, flag, - (buf, "%lx\n", xhdit->context_xen_core.note)); - XEN_HYPER_PRI(fp, len, "pcpu_id: ", buf, flag, - (buf, "%u\n", xhdit->context_xen_core.pcpu_id)); - XEN_HYPER_PRI(fp, len, "crash_xen_core_ptr: ", buf, flag, - (buf, "%p\n", xhdit->context_xen_core.crash_xen_core_ptr)); + XEN_HYPER_PRI(fp, len, "context_xen_core_array: ", buf, flag, + (buf, "%p\n", xhdit->context_xen_core_array)); + if (verbose && xhdit->context_xen_core_array) { + xen_hyper_dump_mem((long *)xhdit->context_xen_core_array, + sizeof(struct xen_hyper_dumpinfo_context_xen_core) * + XEN_HYPER_MAX_CPUS(), sizeof(long)); + } XEN_HYPER_PRI_CONST(fp, len, "context_xen_info: ", flag|XEN_HYPER_PRI_LF); XEN_HYPER_PRI(fp, len, "note: ", buf, flag, (buf, "%lx\n", xhdit->context_xen_info.note)); @@ -283,12 +283,13 @@ xhdit->core_size * XEN_HYPER_NR_PCPUS(), sizeof(long)); } - XEN_HYPER_PRI(fp, len, "crash_note_xen_core_ptr: ", buf, flag, - (buf, "%p\n", xhdit->crash_note_xen_core_ptr)); - if (verbose && xhdit->crash_note_xen_core_ptr) { + XEN_HYPER_PRI(fp, len, "crash_note_xen_core_array: ", buf, flag, + (buf, "%p\n", xhdit->crash_note_xen_core_array)); + if (verbose && xhdit->crash_note_xen_core_array) { xen_hyper_dump_mem( - xhdit->crash_note_xen_core_ptr, - xhdit->xen_core_size, sizeof(long)); + xhdit->crash_note_xen_core_array, + xhdit->xen_core_size * XEN_HYPER_NR_PCPUS(), + sizeof(long)); } XEN_HYPER_PRI(fp, len, "crash_note_xen_info_ptr: ", buf, flag, (buf, "%p\n", xhdit->crash_note_xen_info_ptr)); @@ -297,6 +298,8 @@ xhdit->crash_note_xen_info_ptr, xhdit->xen_info_size, sizeof(long)); } + XEN_HYPER_PRI(fp, len, "xen_info_cpu: ", buf, flag, + (buf, "%u\n", xhdit->xen_info_cpu)); XEN_HYPER_PRI(fp, len, "note_size: ", buf, flag, (buf, "%u\n", xhdit->note_size)); XEN_HYPER_PRI(fp, len, "core_offset: ", buf, flag, @@ -320,13 +323,52 @@ xen_hyper_dump_xen_hyper_domain_table(int verbose) { char buf[XEN_HYPER_CMD_BUFSIZE]; - int len, flag; + struct xen_hyper_domain_context *dcca; + int len, flag, i; len = 22; flag = XEN_HYPER_PRI_R; XEN_HYPER_PRI(fp, len, "context_array: ", buf, flag, (buf, "%p\n", xhdt->context_array)); + if (verbose) { + char buf1[XEN_HYPER_CMD_BUFSIZE]; + int j; + for (i = 0, dcca = xhdt->context_array; + i < xhdt->context_array_cnt; i++, dcca++) { + snprintf(buf, XEN_HYPER_CMD_BUFSIZE, "context_array[%d]: ", i); + XEN_HYPER_PRI_CONST(fp, len, buf, flag|XEN_HYPER_PRI_LF); + XEN_HYPER_PRI(fp, len, "domain: ", buf, flag, + (buf, "%lx\n", dcca->domain)); + XEN_HYPER_PRI(fp, len, "domain_id: ", buf, flag, + (buf, "%d\n", dcca->domain_id)); + XEN_HYPER_PRI(fp, len, "tot_pages: ", buf, flag, + (buf, "%x\n", dcca->tot_pages)); + XEN_HYPER_PRI(fp, len, "max_pages: ", buf, flag, + (buf, "%x\n", dcca->max_pages)); + XEN_HYPER_PRI(fp, len, "xenheap_pages: ", buf, flag, + (buf, "%x\n", dcca->xenheap_pages)); + XEN_HYPER_PRI(fp, len, "shared_info: ", buf, flag, + (buf, "%lx\n", dcca->shared_info)); + XEN_HYPER_PRI(fp, len, "sched_priv: ", buf, flag, + (buf, "%lx\n", dcca->sched_priv)); + XEN_HYPER_PRI(fp, len, "next_in_list: ", buf, flag, + (buf, "%lx\n", dcca->next_in_list)); + XEN_HYPER_PRI(fp, len, "domain_flags: ", buf, flag, + (buf, "%lx\n", dcca->domain_flags)); + XEN_HYPER_PRI(fp, len, "evtchn: ", buf, flag, + (buf, "%lx\n", dcca->evtchn)); + XEN_HYPER_PRI(fp, len, "vcpu_cnt: ", buf, flag, + (buf, "%d\n", dcca->vcpu_cnt)); + for (j = 0; j < XEN_HYPER_MAX_VIRT_CPUS; j++) { + snprintf(buf1, XEN_HYPER_CMD_BUFSIZE, "vcpu[%d]: ", j); + XEN_HYPER_PRI(fp, len, buf1, buf, flag, + (buf, "%lx\n", dcca->vcpu[j])); + } + XEN_HYPER_PRI(fp, len, "vcpu_context_array: ", buf, flag, + (buf, "%p\n", dcca->vcpu_context_array)); + } + } XEN_HYPER_PRI(fp, len, "context_array_cnt: ", buf, flag, (buf, "%d\n", xhdt->context_array_cnt)); XEN_HYPER_PRI(fp, len, "running_domains: ", buf, flag, @@ -365,6 +407,57 @@ (buf, "%p\n", xhvct->vcpu_context_arrays)); XEN_HYPER_PRI(fp, len, "vcpu_context_arrays_cnt: ", buf, flag, (buf, "%d\n", xhvct->vcpu_context_arrays_cnt)); + if (verbose) { + struct xen_hyper_vcpu_context_array *vcca; + struct xen_hyper_vcpu_context *vca; + int i, j; + + for (i = 0, vcca = xhvct->vcpu_context_arrays; + i < xhvct->vcpu_context_arrays_cnt; i++, vcca++) { + snprintf(buf, XEN_HYPER_CMD_BUFSIZE, "vcpu_context_arrays[%d]: ", i); + XEN_HYPER_PRI_CONST(fp, len, buf, flag|XEN_HYPER_PRI_LF); + if (vcca->context_array) { + XEN_HYPER_PRI(fp, len, "context_array: ", buf, flag, + (buf, "%p\n", vcca->context_array)); + } else { + XEN_HYPER_PRI(fp, len, "context_array: ", buf, flag, + (buf, "NULL\n")); + } + XEN_HYPER_PRI(fp, len, "context_array_cnt: ", buf, flag, + (buf, "%d\n", vcca->context_array_cnt)); + XEN_HYPER_PRI(fp, len, "context_array_valid: ", buf, flag, + (buf, "%d\n", vcca->context_array_valid)); + for (j = 0, vca = vcca->context_array; + j < vcca->context_array_cnt; j++, vca++) { + snprintf(buf, XEN_HYPER_CMD_BUFSIZE, "context_array[%d]: ", j); + XEN_HYPER_PRI_CONST(fp, len, buf, flag|XEN_HYPER_PRI_LF); + XEN_HYPER_PRI(fp, len, "vcpu: ", buf, flag, + (buf, "%lx\n", vca->vcpu)); + XEN_HYPER_PRI(fp, len, "vcpu_id: ", buf, flag, + (buf, "%d\n", vca->vcpu_id)); + XEN_HYPER_PRI(fp, len, "processor: ", buf, flag, + (buf, "%d\n", vca->processor)); + XEN_HYPER_PRI(fp, len, "vcpu_info: ", buf, flag, + (buf, "%lx\n", vca->vcpu_info)); + XEN_HYPER_PRI(fp, len, "domain: ", buf, flag, + (buf, "%lx\n", vca->domain)); + XEN_HYPER_PRI(fp, len, "next_in_list: ", buf, flag, + (buf, "%lx\n", vca->next_in_list)); + XEN_HYPER_PRI(fp, len, "sleep_tick: ", buf, flag, + (buf, "%lx\n", vca->sleep_tick)); + XEN_HYPER_PRI(fp, len, "sched_priv: ", buf, flag, + (buf, "%lx\n", vca->sched_priv)); + XEN_HYPER_PRI(fp, len, "state: ", buf, flag, + (buf, "%d\n", vca->state)); + XEN_HYPER_PRI(fp, len, "state_entry_time: ", buf, flag, + (buf, "%llux\n", (unsigned long long)(vca->state_entry_time))); + XEN_HYPER_PRI(fp, len, "runstate_guest: ", buf, flag, + (buf, "%lx\n", vca->runstate_guest)); + XEN_HYPER_PRI(fp, len, "vcpu_flags: ", buf, flag, + (buf, "%lx\n", vca->vcpu_flags)); + } + } + } XEN_HYPER_PRI(fp, len, "idle_vcpu: ", buf, flag, (buf, "%lx\n", xhvct->idle_vcpu)); XEN_HYPER_PRI(fp, len, "idle_vcpu_context_array: ", buf, flag, @@ -673,11 +766,29 @@ XEN_HYPER_PRI(fp, len, "domain_next_in_list: ", buf, flag, (buf, "%ld\n", xen_hyper_offset_table.domain_next_in_list)); XEN_HYPER_PRI(fp, len, "domain_domain_flags: ", buf, flag, - (buf, "%ld\n", xen_hyper_offset_table.domain_domain_flags)); + (buf, "%lx\n", xen_hyper_offset_table.domain_domain_flags)); XEN_HYPER_PRI(fp, len, "domain_evtchn: ", buf, flag, (buf, "%ld\n", xen_hyper_offset_table.domain_evtchn)); + XEN_HYPER_PRI(fp, len, "domain_is_hvm: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_hvm)); + XEN_HYPER_PRI(fp, len, "domain_is_privileged: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_privileged)); + XEN_HYPER_PRI(fp, len, "domain_debugger_attached: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_debugger_attached)); + XEN_HYPER_PRI(fp, len, "domain_is_polling: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_polling)); + XEN_HYPER_PRI(fp, len, "domain_is_dying: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_dying)); + XEN_HYPER_PRI(fp, len, "domain_is_paused_by_controller: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_paused_by_controller)); + XEN_HYPER_PRI(fp, len, "domain_is_shutting_down: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_shutting_down)); + XEN_HYPER_PRI(fp, len, "domain_is_shut_down: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_is_shut_down)); XEN_HYPER_PRI(fp, len, "domain_vcpu: ", buf, flag, (buf, "%ld\n", xen_hyper_offset_table.domain_vcpu)); + XEN_HYPER_PRI(fp, len, "domain_arch: ", buf, flag, + (buf, "%ld\n", xen_hyper_offset_table.domain_arch)); #ifdef IA64 XEN_HYPER_PRI(fp, len, "mm_struct_pgd: ", buf, flag, --- crash-4.0-4.5/defs.h 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/defs.h 2007-08-27 11:50:30.000000000 -0400 @@ -1386,6 +1386,15 @@ long unwind_table_size; long unwind_table_link; long unwind_table_name; + long rq_cfs; + long rq_rt; + long rq_nr_running; + long cfs_rq_rb_leftmost; + long cfs_rq_nr_running; + long cfs_rq_tasks_timeline; + long task_struct_se; + long sched_entity_run_node; + long rt_rq_active; }; struct size_table { /* stash of commonly-used sizes */ --- crash-4.0-4.5/xen_hyper_defs.h 2007-08-27 11:57:19.000000000 -0400 +++ crash-4.0-4.6/xen_hyper_defs.h 2007-08-23 17:02:54.000000000 -0400 @@ -74,14 +74,13 @@ #define PERCPU_ADDR (DEFAULT_SHAREDINFO_ADDR - PERCPU_PAGE_SIZE) #define DIRECTMAP_VIRT_START (0xf000000000000000) #define DIRECTMAP_VIRT_END PERCPU_ADDR -#define VIRT_FRAME_TABLE_ADDR (0xf300000000000000) -#define VIRT_FRAME_TABLE_END (0xf400000000000000) +#define VIRT_FRAME_TABLE_SIZE (0x0100000000000000) #define PERCPU_VIRT_ADDR(vaddr) \ (((vaddr) >= PERCPU_ADDR) && ((vaddr) < PERCPU_ADDR + PERCPU_PAGE_SIZE)) #define FRAME_TABLE_VIRT_ADDR(vaddr) \ - ((vaddr) >= VIRT_FRAME_TABLE_ADDR && (vaddr) < VIRT_FRAME_TABLE_END) + ((vaddr) >= xhmachdep->frame_table && (vaddr) < xhmachdep->frame_table + VIRT_FRAME_TABLE_SIZE) #undef IA64_RBS_OFFSET #define IA64_RBS_OFFSET ((XEN_HYPER_SIZE(vcpu) + 15) & ~15) @@ -101,6 +100,14 @@ #define XEN_HYPER_ELF_NOTE_V1 1 #define XEN_HYPER_ELF_NOTE_V2 2 #define XEN_HYPER_ELF_NOTE_V3 3 +#define XEN_HYPER_ELF_NOTE_V4 4 + +#ifdef X86 +#define XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE 0x100 +#endif +#if defined(X86_64) || defined(IA64) +#define XEN_HYPER_ELF_NOTE_V4_NOTE_SIZE 0x200 +#endif /* * Xen Hyper @@ -129,7 +136,9 @@ ((ulong)(var) + (((ulong)(cpu))<__per_cpu_offset[cpu])) + ((xht->flags & XEN_HYPER_SMP) ? \ + (ulong)(var) + (xht->__per_cpu_offset[cpu]) : \ + (ulong)(var)) #endif #if defined(X86) || defined(X86_64) @@ -155,6 +164,7 @@ /* Prepared domain ID. */ #define XEN_HYPER_DOMID_IO (0x7FF1U) #define XEN_HYPER_DOMID_XEN (0x7FF2U) + /* Domain flags (domain_flags). */ /* Is this domain privileged? */ #define XEN_HYPER__DOMF_privileged 0 @@ -180,6 +190,32 @@ /* Domain flag error */ #define XEN_HYPER_DOMF_ERROR ((ulong)(-1)) +/* Domain status. */ + /* Is this an HVM guest? */ +#define XEN_HYPER__DOMS_HVM 0 +#define XEN_HYPER_DOMS_HVM (1UL<