Hi,
Since linux-2.6.27 of x86_64, _cpu_pda has been changed to **_cpu_pda
from *_cpu_pda[NR_CPUS].
This patch catches up this change.
I tested it on linux-2.6.27-rc5, and it works fine.
Thanks
Ken'ichi Ohmichi
Signed-off-by: Ken'ichi Ohmichi <oomichi(a)mxs.nes.nec.co.jp>
---
diff -rpuN crash-4.0-7.1.orig/defs.h crash-4.0-7.1/defs.h
--- crash-4.0-7.1.orig/defs.h 2008-09-02 11:14:45.000000000 +0900
+++ crash-4.0-7.1/defs.h 2008-09-02 11:16:50.000000000 +0900
@@ -2223,6 +2223,17 @@ struct load_module {
#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
+#define _CPU_PDA_READ2(CPU, BUFFER) \
+ ((readmem(symbol_value("_cpu_pda"), \
+ KVADDR, &cpu_pda_addr, sizeof(unsigned long), \
+ "_cpu_pda addr", FAULT_ON_ERROR)) && \
+ (readmem(cpu_pda_addr + ((CPU) * sizeof(void *)), \
+ KVADDR, &cpu_pda_addr, sizeof(unsigned long), \
+ "_cpu_pda addr", FAULT_ON_ERROR)) && \
+ (cpu_pda_addr) && \
+ (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) * sizeof(unsigned long)))))) && \
diff -rpuN crash-4.0-7.1.orig/x86_64.c crash-4.0-7.1/x86_64.c
--- crash-4.0-7.1.orig/x86_64.c 2008-09-02 11:14:45.000000000 +0900
+++ crash-4.0-7.1/x86_64.c 2008-09-02 11:14:55.000000000 +0900
@@ -540,7 +540,7 @@ x86_64_dump_machdep_table(ulong arg)
static void
x86_64_cpu_pda_init(void)
{
- int i, cpus, nr_pda, cpunumber, _cpu_pda;
+ int i, cpus, nr_pda, cpunumber, _cpu_pda, _boot_cpu_pda;
char *cpu_pda_buf;
ulong level4_pgt, data_offset, cpu_pda_addr;
struct syment *sp, *nsp;
@@ -575,11 +575,21 @@ x86_64_cpu_pda_init(void)
_cpu_pda = FALSE;
}
}
-
+ if (_cpu_pda) {
+ if (symbol_exists("_boot_cpu_pda"))
+ _boot_cpu_pda = TRUE;
+ else
+ _boot_cpu_pda = FALSE;
+ }
for (i = cpus = 0; i < nr_pda; i++) {
if (_cpu_pda) {
- if (!_CPU_PDA_READ(i, cpu_pda_buf))
- break;
+ if (_boot_cpu_pda) {
+ if (!_CPU_PDA_READ2(i, cpu_pda_buf))
+ break;
+ } else {
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
+ break;
+ }
} else {
if (!CPU_PDA_READ(i, cpu_pda_buf))
break;
@@ -3920,7 +3930,7 @@ x86_64_dis_filter(ulong vaddr, char *inb
int
x86_64_get_smp_cpus(void)
{
- int i, cpus, nr_pda, cpunumber, _cpu_pda;
+ int i, cpus, nr_pda, cpunumber, _cpu_pda, _boot_cpu_pda;
char *cpu_pda_buf;
ulong level4_pgt, cpu_pda_addr;
@@ -3946,10 +3956,21 @@ x86_64_get_smp_cpus(void)
_cpu_pda = FALSE;
}
}
+ if (_cpu_pda) {
+ if (symbol_exists("_boot_cpu_pda"))
+ _boot_cpu_pda = TRUE;
+ else
+ _boot_cpu_pda = FALSE;
+ }
for (i = cpus = 0; i < nr_pda; i++) {
if (_cpu_pda) {
- if (!_CPU_PDA_READ(i, cpu_pda_buf))
- break;
+ if (_boot_cpu_pda) {
+ if (!_CPU_PDA_READ2(i, cpu_pda_buf))
+ break;
+ } else {
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
+ break;
+ }
} else {
if (!CPU_PDA_READ(i, cpu_pda_buf))
break;
---