Hi Dave, Following the changes in the way cpu_pda is accessed on x86_64 kernels, running crash to analyse kdump based crash dumps gave the following error: crash: cannot resolve "cpu_pda" The following patch fixes this. Kindly review. Thanks Rachita Signed-off-by: Rachita Kothiyal <rachita@xxxxxxxxxx> --- defs.h | 10 ++++ x86_64.c | 139 ++++++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 41 deletions(-) diff -puN x86_64.c~crash-fix-cpu-pda x86_64.c --- crash-4.0-2.19/x86_64.c~crash-fix-cpu-pda 2006-01-31 17:21:35.430960480 +0530 +++ crash-4.0-2.19-rachita/x86_64.c 2006-01-31 17:23:44.893279216 +0530 @@ -367,7 +367,7 @@ x86_64_cpu_pda_init(void) { int i, cpus, nr_pda, cpunumber; char *cpu_pda_buf; - ulong level4_pgt, data_offset; + ulong level4_pgt, data_offset, *cpu_pda_addr; struct syment *sp, *nsp; ulong offset, istacksize; @@ -383,36 +383,68 @@ x86_64_cpu_pda_init(void) cpu_pda_buf = GETBUF(SIZE(x8664_pda)); - if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) - nr_pda = NR_CPUS; - - for (i = cpus = 0; i < nr_pda; i++) { - if (!CPU_PDA_READ(i, cpu_pda_buf)) - break; - if (VALID_MEMBER(x8664_pda_level4_pgt)) { - level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); - if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + if (symbol_exists("_cpu_pda")) { + if (!(nr_pda = get_array_length("_cpu_pda", NULL, 0))) + nr_pda = NR_CPUS; + cpu_pda_addr = GETBUF(sizeof(unsigned long)); + for (i = cpus = 0; i < nr_pda; i++) { + *cpu_pda_addr = NULL; + if (!_CPU_PDA_READ(i, cpu_pda_buf)) break; - } - cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); - if (cpunumber != cpus) - break; - cpus++; - if (VALID_MEMBER(x8664_pda_data_offset)) { - data_offset = ULONG(cpu_pda_buf + - OFFSET(x8664_pda_data_offset)); - kt->__per_cpu_offset[i] = data_offset; - kt->flags |= PER_CPU_OFF; - } else - data_offset = 0; + if (VALID_MEMBER(x8664_pda_level4_pgt)) { + level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); + if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + break; + } + cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); + if (cpunumber != cpus) + break; + cpus++; - machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf + - OFFSET(x8664_pda_irqstackptr)); + if (VALID_MEMBER(x8664_pda_data_offset)) { + data_offset = ULONG(cpu_pda_buf + + OFFSET(x8664_pda_data_offset)); + kt->__per_cpu_offset[i] = data_offset; + kt->flags |= PER_CPU_OFF; + } else + data_offset = 0; + machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf + + OFFSET(x8664_pda_irqstackptr)); + if (CRASHDEBUG(2)) + fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n", + i, level4_pgt, data_offset); + } + FREEBUF(cpu_pda_addr); + } else if (symbol_exists("cpu_pda")) { + if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) + nr_pda = NR_CPUS; + for (i = cpus = 0; i < nr_pda; i++) { + if (!CPU_PDA_READ(i, cpu_pda_buf)) + break; + if (VALID_MEMBER(x8664_pda_level4_pgt)) { + level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); + if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + break; + } + cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); + if (cpunumber != cpus) + break; + cpus++; - if (CRASHDEBUG(2)) - fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n", - i, level4_pgt, data_offset); + if (VALID_MEMBER(x8664_pda_data_offset)) { + data_offset = ULONG(cpu_pda_buf + + OFFSET(x8664_pda_data_offset)); + kt->__per_cpu_offset[i] = data_offset; + kt->flags |= PER_CPU_OFF; + } else + data_offset = 0; + machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf + + OFFSET(x8664_pda_irqstackptr)); + if (CRASHDEBUG(2)) + fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n", + i, level4_pgt, data_offset); + } } @@ -2718,29 +2750,51 @@ x86_64_get_smp_cpus(void) { int i, cpus, nr_pda, cpunumber; char *cpu_pda_buf; - ulong level4_pgt; + ulong level4_pgt, *cpu_pda_addr; if (!VALID_STRUCT(x8664_pda)) return 1; cpu_pda_buf = GETBUF(SIZE(x8664_pda)); - if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) - nr_pda = NR_CPUS; + if (symbol_exists("_cpu_pda")){ + if (!(nr_pda = get_array_length("_cpu_pda", NULL, 0))) + nr_pda = NR_CPUS; + cpu_pda_addr = GETBUF(sizeof(unsigned long)); + for (i = cpus = 0; i < nr_pda; i++) { + *cpu_pda_addr = NULL; + if (!_CPU_PDA_READ(i, cpu_pda_buf)) + break; - for (i = cpus = 0; i < nr_pda; i++) { - if (!CPU_PDA_READ(i, cpu_pda_buf)) - break; + if (VALID_MEMBER(x8664_pda_level4_pgt)) { + level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); + if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + break; + } + cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); + if (cpunumber != cpus) + break; + cpus++; + } + FREEBUF(cpu_pda_addr); + } + else if (symbol_exists("cpu_pda")){ + if (!(nr_pda = get_array_length("cpu_pda", NULL, 0))) + nr_pda = NR_CPUS; + for (i = cpus = 0; i < nr_pda; i++) { + if (!CPU_PDA_READ(i, cpu_pda_buf)) + break; - if (VALID_MEMBER(x8664_pda_level4_pgt)) { - level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); - if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + if (VALID_MEMBER(x8664_pda_level4_pgt)) { + level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt)); + if (!VALID_LEVEL4_PGT_ADDR(level4_pgt)) + break; + } + cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); + if (cpunumber != cpus) break; + cpus++; } - cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber)); - if (cpunumber != cpus) - break; - cpus++; } FREEBUF(cpu_pda_buf); @@ -2828,7 +2882,10 @@ x86_64_display_cpu_data(void) boot_cpu = TRUE; cpus = 1; } - cpu_pda = symbol_value("cpu_pda"); + if (symbol_exists("_cpu_pda")) + cpu_pda = symbol_value("_cpu_pda"); + else if (symbol_exists("cpu_pda")) + cpu_pda = symbol_value("cpu_pda"); for (cpu = 0; cpu < cpus; cpu++) { if (boot_cpu) diff -puN defs.h~crash-fix-cpu-pda defs.h --- crash-4.0-2.19/defs.h~crash-fix-cpu-pda 2006-01-31 17:25:59.479818952 +0530 +++ crash-4.0-2.19-rachita/defs.h 2006-01-31 17:26:23.969096016 +0530 @@ -1840,6 +1840,16 @@ struct load_module { #define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) +#define _CPU_PDA_READ(CPU, BUFFER) \ + ((STRNEQ("_cpu_pda", closest_symbol((symbol_value("_cpu_pda") + \ + ((CPU) * sizeof(unsigned long)))))) && \ + (readmem(symbol_value("_cpu_pda") + ((CPU) * sizeof(unsigned long)),\ + KVADDR, cpu_pda_addr, sizeof(unsigned long), "_cpu_pda addr", \ + FAULT_ON_ERROR)) && \ + (readmem(*cpu_pda_addr , \ + KVADDR, (BUFFER), SIZE(x8664_pda), "cpu_pda entry", \ + FAULT_ON_ERROR))) + #define CPU_PDA_READ(CPU, BUFFER) \ (STRNEQ("cpu_pda", closest_symbol((symbol_value("cpu_pda") + \ ((CPU) * SIZE(x8664_pda))))) && \ _