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