--- crash-7.0.9/defs.h.orig +++ crash-7.0.9/defs.h @@ -5180,14 +5180,15 @@ struct x86_64_pt_regs_offsets { }; #define MAX_EXCEPTION_STACKS 7 -#define NMI_STACK 2 /* ebase[] index to NMI exception stack */ -#define DEBUG_STACK 3 /* ebase[] index to DEBUG exception stack */ +#define NMI_STACK (machdep->machspec->stkinfo.NMI_stack_index) struct x86_64_stkinfo { ulong ebase[NR_CPUS][MAX_EXCEPTION_STACKS]; int esize[MAX_EXCEPTION_STACKS]; ulong ibase[NR_CPUS]; int isize; + int NMI_stack_index; + char *exception_stacks[MAX_EXCEPTION_STACKS]; }; struct machine_specific { --- crash-7.0.9/x86_64.c.orig +++ crash-7.0.9/x86_64.c @@ -114,6 +114,7 @@ static void x86_64_get_active_set(void); static int x86_64_get_kvaddr_ranges(struct vaddr_range *); static int x86_64_verify_paddr(uint64_t); static void GART_init(void); +static void x86_64_exception_stacks_init(void); struct machine_specific x86_64_machine_specific = { 0 }; @@ -798,6 +799,14 @@ x86_64_dump_machdep_table(ulong arg) ms->stkinfo.esize[5], ms->stkinfo.esize[6], machdep->flags & NO_TSS ? " (NO TSS) " : " "); + + fprintf(fp, " NMI_stack_index: %d\n", + ms->stkinfo.NMI_stack_index); + fprintf(fp, " exception_stacks:\n"); + for (i = 0; i < MAX_EXCEPTION_STACKS; i++) + fprintf(fp, " [%d]: %s\n", i, + ms->stkinfo.exception_stacks[i]); + fprintf(fp, " ebase[%s][%d]:", arg ? "NR_CPUS" : "cpus", MAX_EXCEPTION_STACKS); cpus = arg ? NR_CPUS : kt->cpus; @@ -1059,17 +1068,6 @@ x86_64_per_cpu_init(void) verify_spinlock(); } -static char * -x86_64_exception_stacks[MAX_EXCEPTION_STACKS] = { - "STACKFAULT", - "DOUBLEFAULT", - "NMI", - "DEBUG", - "MCE", - "(unknown)", - "(unknown)" -}; - /* * Gather the ist addresses for each CPU. */ @@ -1086,6 +1084,8 @@ x86_64_ist_init(void) tss_sp = per_cpu_symbol_search("per_cpu__init_tss"); ist_sp = per_cpu_symbol_search("per_cpu__orig_ist"); + x86_64_exception_stacks_init(); + if (!tss_sp && symbol_exists("init_tss")) { init_tss = symbol_value("init_tss"); @@ -1135,7 +1135,7 @@ x86_64_ist_init(void) if (ms->stkinfo.ebase[c][i] != estacks[i]) error(WARNING, "cpu %d %s stack: init_tss: %lx orig_ist: %lx\n", c, - x86_64_exception_stacks[i], + ms->stkinfo.exception_stacks[i], ms->stkinfo.ebase[c][i], estacks[i]); ms->stkinfo.ebase[c][i] = estacks[i]; } @@ -1165,22 +1165,12 @@ x86_64_ist_init(void) break; cnt++; if ((THIS_KERNEL_VERSION >= LINUX(2,6,18)) && - (i == DEBUG_STACK)) + STREQ(ms->stkinfo.exception_stacks[i], "DEBUG")) ms->stkinfo.esize[i] = esize*2; else ms->stkinfo.esize[i] = esize; ms->stkinfo.ebase[c][i] -= ms->stkinfo.esize[i]; } - /* - * RT kernel only uses 3 exception stacks for the 5 types. - */ - if ((c == 0) && (cnt == 3)) { - x86_64_exception_stacks[0] = "RT"; - x86_64_exception_stacks[1] = "RT"; - x86_64_exception_stacks[2] = "RT"; - x86_64_exception_stacks[3] = "(unknown)"; - x86_64_exception_stacks[4] = "(unknown)"; - } } /* @@ -2351,7 +2341,7 @@ x86_64_eframe_search(struct bt_info *bt) break; bt->hp->esp = ms->stkinfo.ebase[c][i]; fprintf(fp, "CPU %d %s EXCEPTION STACK:", - c, x86_64_exception_stacks[i]); + c, ms->stkinfo.exception_stacks[i]); if (hide_offline_cpu(c)) { fprintf(fp, " [OFFLINE]\n\n"); @@ -3084,7 +3074,7 @@ in_exception_stack: if (!BT_REFERENCE_CHECK(bt)) fprintf(fp, "--- <%s exception stack> ---\n", - x86_64_exception_stacks[estack_index]); + ms->stkinfo.exception_stacks[estack_index]); /* * Find the CPU-saved, or handler-saved registers @@ -3133,7 +3123,7 @@ in_exception_stack: fprintf(ofp, " [ %s exception stack recursion: " "prior stack location overwritten ]\n", - x86_64_exception_stacks[estack_index]); + ms->stkinfo.exception_stacks[estack_index]); return; } @@ -4540,12 +4530,12 @@ skip_stage: bt->stacktop = ms->stkinfo.ebase[bt->tc->processor][estack] + ms->stkinfo.esize[estack]; console("x86_64_get_dumpfile_stack_frame: searching %s estack at %lx\n", - x86_64_exception_stacks[estack], bt->stackbase); + ms->stkinfo.exception_stacks[estack], bt->stackbase); if (!(bt->stackbase)) goto skip_stage; bt->stackbuf = ms->irqstack; alter_stackbuf(bt); - in_nmi_stack = STREQ(x86_64_exception_stacks[estack], "NMI"); + in_nmi_stack = STREQ(ms->stkinfo.exception_stacks[estack], "NMI"); goto next_stack; } @@ -4772,6 +4762,69 @@ x86_64_display_idt_table(void) FREEBUF(idt_table_buf); } +static void +x86_64_exception_stacks_init(void) +{ + char *idt_table_buf; + char buf[BUFSIZE]; + int i; + ulong *ip, ist; + long size; + struct machine_specific *ms; + + ms = machdep->machspec; + + ms->stkinfo.NMI_stack_index = -1; + for (i = 0; i < MAX_EXCEPTION_STACKS; i++) + ms->stkinfo.exception_stacks[i] = "(unknown)"; + + if (!kernel_symbol_exists("idt_table")) + return; + + if (INVALID_SIZE(gate_struct)) + size = 16; + else + size = SIZE(gate_struct); + + idt_table_buf = GETBUF(size * 256); + readmem(symbol_value("idt_table"), KVADDR, idt_table_buf, + size * 256, "idt_table", FAULT_ON_ERROR); + ip = (ulong *)idt_table_buf; + + if (CRASHDEBUG(1)) + fprintf(fp, "exception IST:\n"); + + for (i = 0; i < 256; i++, ip += 2) { + ist = ((*ip) >> 32) & 0x7; + if (ist) { + x86_64_extract_idt_function(ip, buf, NULL); + if (CRASHDEBUG(1)) + fprintf(fp, " %ld: %s\n", ist, buf); + if (strstr(buf, "nmi")) { + ms->stkinfo.NMI_stack_index = ist-1; + ms->stkinfo.exception_stacks[ist-1] = "NMI"; + } + if (strstr(buf, "debug")) + ms->stkinfo.exception_stacks[ist-1] = "DEBUG"; + if (strstr(buf, "stack")) + ms->stkinfo.exception_stacks[ist-1] = "STACKFAULT"; + if (strstr(buf, "double")) + ms->stkinfo.exception_stacks[ist-1] = "DOUBLEFAULT"; + if (strstr(buf, "machine")) + ms->stkinfo.exception_stacks[ist-1] = "MCE"; + } + } + + if (CRASHDEBUG(1)) { + fprintf(fp, "exception stacks:\n"); + for (i = 0; i < MAX_EXCEPTION_STACKS; i++) + fprintf(fp, " [%d]: %s\n", i, ms->stkinfo.exception_stacks[i]); + } + + FREEBUF(idt_table_buf); +} + + /* * Extract the function name out of the IDT entry. */ @@ -5103,9 +5156,9 @@ x86_64_display_machine_stats(void) if (machdep->machspec->stkinfo.ebase[0][i] == 0) break; fprintf(fp, "%11s STACK SIZE: %d\n", - x86_64_exception_stacks[i], + machdep->machspec->stkinfo.exception_stacks[i], machdep->machspec->stkinfo.esize[i]); - sprintf(buf, "%s STACKS:\n", x86_64_exception_stacks[i]); + sprintf(buf, "%s STACKS:\n", machdep->machspec->stkinfo.exception_stacks[i]); fprintf(fp, "%24s", buf); for (c = 0; c < kt->cpus; c++) { if (machdep->machspec->stkinfo.ebase[c][i] == 0) --- crash-7.0.9/memory.c.orig +++ crash-7.0.9/memory.c @@ -8632,8 +8632,7 @@ static char * vaddr_to_kmem_cache(ulong vaddr, char *buf, int verbose) { physaddr_t paddr; - ulong page; - ulong cache; + ulong page, cache, page_flags; if (!kvtop(NULL, vaddr, &paddr, 0)) { if (verbose) @@ -8651,6 +8650,14 @@ vaddr_to_kmem_cache(ulong vaddr, char *b return NULL; } + if (vt->PG_slab) { + readmem(page+OFFSET(page_flags), KVADDR, + &page_flags, sizeof(ulong), "page.flags", + FAULT_ON_ERROR); + if (!(page_flags & (1 << vt->PG_slab))) + return NULL; + } + if ((vt->flags & KMALLOC_SLUB) || ((vt->flags & KMALLOC_COMMON) && VALID_MEMBER(page_slab) && VALID_MEMBER(page_first_page))) {