On Wed, Feb 01, 2006 at 08:47:07AM -0500, Dave Anderson wrote:
That should do it.
Minor nits: for clarity's sake, I'd make the local variable have the
same name as the kernel symbol it's representing (i.e. _cpu_data
instead of __cpu_data), just check it as a boolean instead of it
being == 1, and increment cpu_pda by sizeof(void *).
Hi Dave
Incorporating the suggested changes and resending the
patch. Kindly review.
Thanks
Rachita
Signed-off-by: Rachita Kothiyal <rachita(a)in.ibm.com>
---
defs.h | 9 +++++++
x86_64.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 67 insertions(+), 19 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-02-01 20:08:14.000000000 +0530
+++ crash-4.0-2.19-rachita/x86_64.c 2006-02-01 20:59:59.033113672 +0530
@@ -365,9 +365,9 @@ x86_64_dump_machdep_table(ulong arg)
static void
x86_64_cpu_pda_init(void)
{
- int i, cpus, nr_pda, cpunumber;
+ int i, cpus, nr_pda, cpunumber, _cpu_pda;
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,12 +383,26 @@ 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;
+ if (symbol_exists("_cpu_pda")) {
+ if (!(nr_pda = get_array_length("_cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ _cpu_pda = TRUE;
+ } else {
+ if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ _cpu_pda = FALSE;
+ }
for (i = cpus = 0; i < nr_pda; i++) {
- if (!CPU_PDA_READ(i, cpu_pda_buf))
- break;
+ if (_cpu_pda) {
+ cpu_pda_addr = 0;
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
+ break;
+ } else {
+ 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))
@@ -2716,22 +2730,33 @@ x86_64_dis_filter(ulong vaddr, char *inb
int
x86_64_get_smp_cpus(void)
{
- int i, cpus, nr_pda, cpunumber;
+ int i, cpus, nr_pda, cpunumber, _cpu_pda;
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 = TRUE;
+ } else {
+ if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ _cpu_pda = FALSE;
+ }
for (i = cpus = 0; i < nr_pda; i++) {
- if (!CPU_PDA_READ(i, cpu_pda_buf))
- break;
-
+ if (_cpu_pda) {
+ cpu_pda_addr = 0;
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
+ break;
+ } else {
+ 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))
@@ -2815,9 +2840,9 @@ x86_64_display_machine_stats(void)
static void
x86_64_display_cpu_data(void)
{
- int cpu, cpus, boot_cpu;
+ int cpu, cpus, boot_cpu, _cpu_pda;
ulong cpu_data;
- ulong cpu_pda;
+ ulong cpu_pda, cpu_pda_addr;
if (symbol_exists("cpu_data")) {
cpu_data = symbol_value("cpu_data");
@@ -2828,7 +2853,13 @@ 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");
+ _cpu_pda = TRUE;
+ } else if (symbol_exists("cpu_pda")) {
+ cpu_pda = symbol_value("cpu_pda");
+ _cpu_pda = FALSE;
+ }
for (cpu = 0; cpu < cpus; cpu++) {
if (boot_cpu)
@@ -2838,10 +2869,18 @@ x86_64_display_cpu_data(void)
dump_struct("cpuinfo_x86", cpu_data, 0);
fprintf(fp, "\n");
- dump_struct("x8664_pda", cpu_pda, 0);
+ if (_cpu_pda) {
+ cpu_pda_addr = 0;
+ readmem(cpu_pda, KVADDR, &cpu_pda_addr,
+ sizeof(unsigned long), "_cpu_pda addr", FAULT_ON_ERROR);
+ dump_struct("x8664_pda", cpu_pda_addr, 0);
+ cpu_pda += sizeof(void *);
+ } else {
+ dump_struct("x8664_pda", cpu_pda, 0);
+ cpu_pda += SIZE(x8664_pda);
+ }
cpu_data += SIZE(cpuinfo_x86);
- cpu_pda += SIZE(x8664_pda);
}
}
diff -puN defs.h~crash-fix-cpu-pda defs.h
--- crash-4.0-2.19/defs.h~crash-fix-cpu-pda 2006-02-01 20:17:35.312817936 +0530
+++ crash-4.0-2.19-rachita/defs.h 2006-02-01 20:26:26.707033736 +0530
@@ -1840,6 +1840,15 @@ 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(void *)), \
+ 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))))) && \
_