Rachita Kothiyal wrote:
Hi Dave,Hi Rachita,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 for handling this. I haven't looked at this, and correct
me
if I'm wrong, but the kernel (what version exactly?) now has contains
a _cpu_pda[NR_CPUS] array containing pointers to the actual per-cpu
x8664_pda structures. Given that, there's really no reason
to GETBUF()
the storage location of the single per-cpu pointer. When
I compile
with "make Warn", I get this:
# make Warn
...
cc -c -g -DX86_64 x86_64.c -Wall -Wstrict-prototypes -Wmissing-prototypes
-Werror
x86_64.c: In function `x86_64_cpu_pda_init':
x86_64.c:389: warning: assignment from incompatible pointer type
x86_64.c:391: warning: assignment makes integer from pointer without
a cast
x86_64.c: In function `x86_64_get_smp_cpus':
x86_64.c:2763: warning: assignment from incompatible pointer type
x86_64.c:2765: warning: assignment makes integer from pointer without
a cast
make[3]: *** [x86_64.o] Error 1
make[2]: *** [gdb] Error 2
make[1]: *** [gdb_merge] Error 2
make: *** [Warn] Error 2
#
which is complaining about the cpu_pda pointer and its use:
389
cpu_pda_addr = GETBUF(sizeof(unsigned long));
390
for (i = cpus = 0; i < nr_pda; i++) {
391
*cpu_pda_addr = NULL;
2763
cpu_pda_addr = GETBUF(sizeof(unsigned long));
2764
for (i = cpus = 0; i < nr_pda; i++) {
2765
*cpu_pda_addr = NULL;
I'd just make cpu_pda_addr a ulong stack variable, zero it out on
lines
389 and 2765, and change the _CPU_PDA_READ() macro to look
like this:
#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)))
Unless I'm missing something, that simplifies things and should
work
just fine. But I can't test it here other than to verify that it's
backwards compatible. Can you verify that?
Thanks again,
Dave
Thanks
RachitaSigned-off-by: Rachita Kothiyal <rachita@in.ibm.com>
---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))))) && \
_