[Crash-utility] ppc64 specific changes to support kdump vmcore

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reposting this patch as it did not made to crash mailing list. Dave, Thanks for adding my different e-mail address to subscriber list.

Dave,

Attaching a patch which contains ppc64 specific changes to read kdump vmcore. As we are saving pt_regs for all cpus, it reads them from vmcore instead of looking for specific symbols, used for PPC64 netdump/diskdump vmcore. Also, prints regs before any active backtrace. Whereas for netdump vmcore, regs will be displayed anyway as part of exception frame since the 'bt' command displays from the top frame.
Verified with "Make Warn"

Please let me know if you have any comments.

As Badari mentioned, when the sparsemem is enabled, pg_dat->node_mem_map member does not exists. mem_map for each node is scattered across multiple sections and is not contiguous. Therefore, some detailed changes are needed. Until we fix this issue, can we include some hack so that users can use other commands for vmcore analysis.
The fix will be:
  if (MEMBER_EXISTS("pglist_data", "node_mem_map"))
     readmem(pgdat+OFFSET(pglist_data_node_mem_map), KVADDR,
                   &node_mem_map, sizeof(ulong),
                   "node_mem_map", FAULT_ON_ERROR);

[I noticed your response to Badari's posting. Since the sparsemem is effected only for powerpc at this point, we thought, user can use the limited functionality with the above change. (Ex: bt) until we have the complete fix. At least we will be having crash tool available for kdump vmore on ppc64. The sparsemem issue will be fixed soon. Ok, please ignore this if you prefer to wait for the complete fix]

Thanks
Haren



diff -Naurp crash-4.0-2.20.orig/netdump.c crash-4.0-2.20/netdump.c
--- crash-4.0-2.20.orig/netdump.c	2006-02-11 16:50:28.000000000 -0800
+++ crash-4.0-2.20/netdump.c	2006-02-11 16:50:58.000000000 -0800
@@ -1680,7 +1680,13 @@ get_netdump_regs_ppc64(struct bt_info *b
 	Elf64_Nhdr *note;
 	size_t len;
 
-	if (bt->task == tt->panic_task) {
+	if ((bt->task == tt->panic_task) ||
+		(is_task_active(bt->task) && nd->num_prstatus_notes > 1)) {
+		/*	
+		 * Registers are saved during the dump process for the 
+		 * panic task. Whereas in kdump, regs are captured for all 
+		 * CPUs if they responded to an IPI.
+		 */
                 if (nd->num_prstatus_notes > 1)
                         note = (Elf64_Nhdr *)
                                 nd->nt_prstatus_percpu[bt->tc->processor];
diff -Naurp crash-4.0-2.20.orig/ppc64.c crash-4.0-2.20/ppc64.c
--- crash-4.0-2.20.orig/ppc64.c	2006-02-11 16:50:32.000000000 -0800
+++ crash-4.0-2.20/ppc64.c	2006-02-13 16:10:56.000000000 -0800
@@ -1420,20 +1420,11 @@ ppc64_check_eframe(struct ppc64_pt_regs 
 	return NULL;
 }
 
-/*
- *  Print exception frame information for ppc64
- */
 static void
-ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
-		struct bt_info *bt)
+ppc64_print_regs(struct ppc64_pt_regs *regs)
 {
 	int i;
 
-	if (BT_REFERENCE_CHECK(bt))
-		return;
-
-        fprintf(fp, " %s  [%lx] exception frame:", efrm_str, regs->trap);
-
         /* print out the gprs... */
         for(i=0; i<32; i++) {
                 if(!(i % 3))
@@ -1465,9 +1456,66 @@ ppc64_print_eframe(char *efrm_str, struc
         fprintf(fp, "DAR: %016lx\n", regs->dar);
         fprintf(fp, " DSISR: %016lx ", regs->dsisr);
         fprintf(fp, "    Syscall Result: %016lx\n", regs->result);
+}
+
+/*
+ * Print the exception frame information
+ */
+static void
+ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
+			struct bt_info *bt)
+{
+	if (BT_REFERENCE_CHECK(bt))
+		return;
+
+	fprintf(fp, " %s  [%lx] exception frame:", efrm_str, regs->trap);
+	ppc64_print_regs(regs);
 	fprintf(fp, "\n");
 }
 
+/*
+ * get SP and IP from the saved ptregs.
+ */
+static int
+ppc64_kdump_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+{
+	struct ppc64_pt_regs *pt_regs;
+	unsigned long unip;
+
+	pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+	if (!pt_regs->gpr[1]) {
+		/*
+		 * Not collected regs. May be the corresponding CPU not
+		 * responded to an IPI.
+		 */
+		fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
+			bt_in->task);
+		return FALSE;
+	}
+	*ksp = pt_regs->gpr[1];
+	readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+		FAULT_ON_ERROR);
+	*nip = unip;
+
+	if (bt_in->flags && 
+	((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT))) 
+		return TRUE;
+
+	/*
+	 * Print the collected regs for the active task
+	 */
+	ppc64_print_regs(pt_regs);
+
+	fprintf(fp, " NIP [%016lx] %s\n", pt_regs->nip,
+		closest_symbol(pt_regs->nip));
+	if (unip != pt_regs->link)
+		fprintf(fp, " LR  [%016lx] %s\n", pt_regs->link,
+			closest_symbol(pt_regs->link));
+
+	fprintf(fp, "\n");
+
+	return TRUE;
+}
 
 /*
  *  Get the starting point for the active cpus in a diskdump/netdump.
@@ -1485,12 +1533,18 @@ ppc64_get_dumpfile_stack_frame(struct bt
         ulong ur_ksp = 0;
 	int check_hardirq, check_softirq;
 	int check_intrstack = TRUE;
+	struct ppc64_pt_regs *pt_regs;
+
+	/* 
+	 * For the kdump vmcore, Use SP and IP values that are saved in ptregs.
+	 */ 
+	if (pc->flags && KDUMP)
+		return ppc64_kdump_stack_frame(bt_in, nip, ksp);
 
         bt = &bt_local;
         BCOPY(bt_in, bt, sizeof(struct bt_info));
         ms = machdep->machspec;
         ur_nip = ur_ksp = 0;
-	struct ppc64_pt_regs *pt_regs;
 	
 	panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
 

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux