[Crash-utility] [RFC]Patch to accomodate cpu_pda changes in x86_64 kernels

Rachita Kothiyal rachita at in.ibm.com
Tue Jan 31 12:56:27 UTC 2006


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 at 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))))) &&				\
_




More information about the Crash-utility mailing list