[Crash-utility] some updates of xencrash

Itsuro ODA oda at valinux.co.jp
Fri Apr 18 00:13:55 UTC 2008


Hi,

The attached is some fixes which are necessary for xencrash to use
for the newer version of xen (after 3.1.0, ex. 3.1.2, 3.2.0).

* x86
  - add some symbols which are used to know the boundary
    condition at the tracing in 'bt'.
  - fix for the symbol 'idle_pg_table_l3' going away.

* x86_64
  - fix for the virtual address area of xen code/data is added.
  - fix for the symbol 'idle_pg_table_l4' going away.
  - add the option '--xen_phys_start_mfn='
    newer version of xen (ex. RHEL5.2, 3.2.0) moves the
    physical(machine) address of xen code/data area after 
    the system started up.
    The relocated physical(machine) address of xen code/data
    area is necessary to use xencrash.
    The value can be got by 'cat /proc/iomem' under dom0.
    -------------------------------------------------------
    # cat /proc/iomem
    ...
      7e600000-7f5fffff : Hypervisor code and data  *** this line
    ...
    -------------------------------------------------------
    ex. to use xencrash:
    # crash --xen_phys_start_mfn=0x7e600 xen-syms vmcore
  - extract 'xen_phys_start_mfn' from the XEN_ELFNOTE_CRASH_INFO
    ElfNote.
    This is experimental code because it is necessary to modify
    the xen to add the xen_phys_start_mfn value in the ElfNote
    at crash time. (the patch is also attached in this mail.)
    A sample dump is availavle in the following URL:
    http://people.valinux.co.jp/~oda/x86_64_dump_080417.tar.gz

This patch is for crash-4.0-6.2.

Thanks.
Itsuro Oda

=== for x86 ===
--- lkcd_x86_trace.c.org	2008-04-17 10:13:05.000000000 +0900
+++ lkcd_x86_trace.c	2008-04-17 10:13:17.000000000 +0900
@@ -1423,6 +1423,7 @@
 		if (XEN_HYPER_MODE()) {
 			func_name = kl_funcname(pc);
 			if (STREQ(func_name, "idle_loop") || STREQ(func_name, "hypercall")
+				|| STREQ(func_name, "tracing_off")
 				|| STREQ(func_name, "handle_exception")) {
 				UPDATE_FRAME(func_name, pc, 0, sp, bp, asp, 0, 0, bp - sp, 0);
 				return(trace->nframes);
@@ -1682,6 +1683,7 @@
 		if (func_name && XEN_HYPER_MODE()) {
 			if (STREQ(func_name, "continue_nmi") ||
 			    STREQ(func_name, "vmx_asm_vmexit_handler") ||
+			    STREQ(func_name, "handle_nmi_mce") ||
 			    STREQ(func_name, "deferred_nmi")) {
 				/* Interrupt frame */
 				sp = curframe->fp + 4;
--- x86.c.org	2008-04-17 10:29:21.000000000 +0900
+++ x86.c	2008-04-17 10:31:51.000000000 +0900
@@ -2846,7 +2846,10 @@
 			*paddr = kvaddr - DIRECTMAP_VIRT_START;
 			return TRUE;
 		}
-		pgd = (ulonglong *)symbol_value("idle_pg_table_l3");
+		if (symbol_exists("idle_pg_table_l3"))
+			pgd = (ulonglong *)symbol_value("idle_pg_table_l3");
+		else
+			pgd = (ulonglong *)symbol_value("idle_pg_table");
 	} else {
 		if (!vt->vmalloc_start) {
 			*paddr = VTOP(kvaddr);
@@ -4965,7 +4968,8 @@
 		break;
 
 	case PRE_GDB:
-		if (symbol_exists("idle_pg_table_l3")) {
+		if (symbol_exists("create_pae_xen_mappings") ||
+		    symbol_exists("idle_pg_table_l3")) {
                 	machdep->flags |= PAE;
 			PGDIR_SHIFT = PGDIR_SHIFT_3LEVEL;
 			PTRS_PER_PTE = PTRS_PER_PTE_3LEVEL;

=== for x86_64 ===
--- defs.h.org	2008-04-17 15:03:14.000000000 +0900
+++ defs.h	2008-04-17 15:41:10.000000000 +0900
@@ -2162,10 +2162,13 @@
 
 #define FILL_PML4_HYPER() { \
 	if (!machdep->machspec->last_pml4_read) { \
-		readmem(symbol_value("idle_pg_table_4"), KVADDR, \
-			machdep->machspec->pml4, PAGESIZE(), "idle_pg_table_4", \
+		unsigned long idle_pg_table = \
+		    symbol_exists("idle_pg_table_4") ? symbol_value("idle_pg_table_4") : \
+			symbol_value("idle_pg_table"); \
+		readmem(idle_pg_table, KVADDR, \
+			machdep->machspec->pml4, PAGESIZE(), "idle_pg_table", \
 			FAULT_ON_ERROR); \
-		machdep->machspec->last_pml4_read = symbol_value("idle_pg_table_4"); \
+		machdep->machspec->last_pml4_read = idle_pg_table; \
 	}\
 }
 
@@ -4081,6 +4084,8 @@
 void get_kdump_regs(struct bt_info *, ulong *, ulong *);
 void xen_kdump_p2m_mfn(char *);
 int is_sadump_xen(void);
+void set_xen_phys_start_mfn(char *);
+ulong xen_phys_start_mfn(void);
 
 /*
  *  diskdump.c
--- main.c.org	2008-04-17 15:26:37.000000000 +0900
+++ main.c	2008-04-17 15:45:18.000000000 +0900
@@ -48,6 +48,7 @@
         {"no_ikconfig", 0, 0, 0},
         {"hyper", 0, 0, 0},
 	{"p2m_mfn", required_argument, 0, 0},
+	{"xen_phys_start_mfn", required_argument, 0, 0},
 	{"zero_excluded", 0, 0, 0},
 	{"no_panic", 0, 0, 0},
         {"more", 0, 0, 0},
@@ -155,6 +156,9 @@
 		        else if (STREQ(long_options[option_index].name, "p2m_mfn")) 
 				xen_kdump_p2m_mfn(optarg);
 
+		        else if (STREQ(long_options[option_index].name, "xen_phys_start_mfn")) 
+				set_xen_phys_start_mfn(optarg);
+
 		        else if (STREQ(long_options[option_index].name, "zero_excluded")) 
 				*diskdump_flags |= ZERO_EXCLUDED;
 
--- netdump.c.org	2008-04-17 15:09:06.000000000 +0900
+++ netdump.c	2008-04-17 15:48:44.000000000 +0900
@@ -1521,6 +1521,8 @@
 				 */
 				if (!nd->xen_kdump_data->p2m_mfn)
 					nd->xen_kdump_data->p2m_mfn = *(uptr+(words-1));
+				if (words > 9 && !nd->xen_kdump_data->xen_phys_start_mfn)
+					nd->xen_kdump_data->xen_phys_start_mfn = *(uptr+(words-2));
 			}
 		}
 		break;
@@ -1724,6 +1726,8 @@
 				 */
 	                        if (!nd->xen_kdump_data->p2m_mfn)
 	                        	nd->xen_kdump_data->p2m_mfn = *(up+(words-1));
+				if (words > 9 && !nd->xen_kdump_data->xen_phys_start_mfn)
+					nd->xen_kdump_data->xen_phys_start_mfn = *(up+(words-2));
 			}
 		}
                 break;
@@ -2312,3 +2316,22 @@
 
 	return FALSE;
 }
+
+void
+set_xen_phys_start_mfn(char *arg)
+{
+	ulong value;
+	int errflag = 0;
+
+	value = htol(arg, RETURN_ON_ERROR|QUIET, &errflag);
+	if (!errflag)
+		xen_kdump_data.xen_phys_start_mfn = value;
+	else 
+		error(WARNING, "invalid xen_phys_start_mfn argument: %s\n", arg);
+}
+
+ulong
+xen_phys_start_mfn(void)
+{
+	return nd->xen_kdump_data->xen_phys_start_mfn;
+}
--- netdump.h.org	2008-04-17 15:38:59.000000000 +0900
+++ netdump.h	2008-04-17 15:39:38.000000000 +0900
@@ -109,6 +109,7 @@
 	ulong accesses;
 	int p2m_frames;
         ulong *p2m_mfn_frame_list;
+	ulong xen_phys_start_mfn;
 };
 
 #define KDUMP_P2M_INIT  (0x1)
--- x86_64.c.org	2008-04-17 15:34:32.000000000 +0900
+++ x86_64.c	2008-04-17 15:36:53.000000000 +0900
@@ -1401,6 +1401,10 @@
                 return FALSE;
 
 	if (XEN_HYPER_MODE()) {
+		if (XENTEXT_VIRT_ADDR(kvaddr)) {
+			*paddr = kvaddr - __XEN_VIRT_START + (xen_phys_start_mfn() << PAGESHIFT());
+			return TRUE;
+		}
 		if (DIRECTMAP_VIRT_ADDR(kvaddr)) {
 			*paddr = kvaddr - DIRECTMAP_VIRT_START;
 			return TRUE;
--- xen_hyper_defs.h.org	2008-04-17 15:31:23.000000000 +0900
+++ xen_hyper_defs.h	2008-04-17 15:34:15.000000000 +0900
@@ -64,6 +64,9 @@
 #define DIRECTMAP_VIRT_START  (0xffff830000000000)
 #define DIRECTMAP_VIRT_END    (0xffff840000000000)
 #define PAGE_OFFSET_XEN_HYPER DIRECTMAP_VIRT_START
+#define __XEN_VIRT_START        (0xFFFF828C80000000)
+#define XENTEXT_VIRT_ADDR(vaddr) \
+    (((vaddr) >= __XEN_VIRT_START) && ((vaddr) < DIRECTMAP_VIRT_START))
 #endif
 
 #ifdef IA64

=== Xen (explanation purpose) ===
--- include/xen/elfcore.h.org	2008-04-17 14:11:41.000000000 +0900
+++ include/xen/elfcore.h	2008-04-17 14:11:57.000000000 +0900
@@ -66,6 +66,7 @@
     unsigned long xen_compile_time;
     unsigned long tainted;
 #ifdef CONFIG_X86
+    unsigned long xen_phys_start_mfn;
     unsigned long dom0_pfn_to_mfn_frame_list_list;
 #endif
 } crash_xen_info_t;
--- arch/x86/crash.c.org	2008-04-17 14:12:51.000000000 +0900
+++ arch/x86/crash.c	2008-04-17 14:13:13.000000000 +0900
@@ -102,6 +102,7 @@
     hvm_disable();
 
     info = kexec_crash_save_info();
+    info->xen_phys_start_mfn = xen_phys_start >> PAGE_SHIFT;
     info->dom0_pfn_to_mfn_frame_list_list =
         arch_get_pfn_to_mfn_frame_list_list(dom0);
 }
-- 
Itsuro ODA <oda at valinux.co.jp>




More information about the Crash-utility mailing list