Kexec Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [makedumpfile] Implement memory regions on IA64
@ 2007-04-26 19:37 Bernhard Walle
  2007-05-11  6:59 ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 10+ messages in thread
From: Bernhard Walle @ 2007-04-26 19:37 UTC (permalink / raw)
  To: Kexec Mailing List; +Cc: Ken'ichi Ohmichi

This patch fixes an error in vaddr_to_offset_ia64() which happened on
a SGI machine here while retrieving the utsname from the kernel dump
image. It implements memory region support for IA64.

The code is mainly from crash (http://people.redhat.com/~anderson/).

Signed-off-by: Bernhard Walle <bwalle@suse.de>

---
 ia64.c         |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.c |    4 ++++
 makedumpfile.h |    9 ++++++++-
 3 files changed, 69 insertions(+), 1 deletion(-)

--- a/ia64.c
+++ b/ia64.c
@@ -23,6 +23,8 @@ get_phys_base_ia64(struct DumpInfo *info
 	int i;
 	struct pt_load_segment *pls;
 
+	info->phys_base = 0;
+
 	/*
 	 *  Default to 64MB.
 	 */
@@ -48,5 +50,60 @@ get_machdep_info_ia64(struct DumpInfo *i
 	return TRUE;
 }
 
+/*
+ * Convert Virtual Address to File Offest.
+ */
+off_t
+vaddr_to_offset_ia64(struct DumpInfo *info, unsigned long long vaddr)
+{
+	int i;
+	off_t offset;
+	struct pt_load_segment *pls;
+	unsigned long paddr;
+
+
+	switch (VADDR_REGION(vaddr)) {
+		case KERNEL_CACHED_REGION:
+			paddr = vaddr - (ulong)(KERNEL_CACHED_BASE);
+			break;
+
+		case KERNEL_UNCACHED_REGION:
+			paddr = vaddr - (ulong)(KERNEL_UNCACHED_BASE);
+			break;
+
+		case KERNEL_VMALLOC_REGION:
+			paddr = vaddr - info->kernel_start +
+				(info->phys_base & KERNEL_TR_PAGE_MASK);
+			break;
+
+		default:
+			ERRMSG("Unknown region (%d)\n", VADDR_REGION(vaddr));
+			return 0;
+	}
+
+	for (i = offset = 0; i < info->num_load_memory; i++) {
+		pls = &info->pt_load_segments[i];
+		if ((paddr >= pls->phys_start)
+		    && (paddr < pls->phys_end)) {
+			offset = (off_t)(paddr - pls->phys_start) +
+				pls->file_offset;
+				break;
+		}
+	}
+
+	return offset;
+}
+
+int
+get_machdep_kernel_start_ia64(struct DumpInfo *info)
+{
+	if (SYMBOL(_stext) != NOT_FOUND_SYMBOL)
+		info->kernel_start = SYMBOL(_stext);
+
+	/* TODO: fallback */
+
+	return TRUE;
+}
+
 #endif /* ia64 */
 
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2206,6 +2206,10 @@ initial(struct DumpInfo *info)
 		if (!get_structure_info(info))
 			return FALSE;
 	}
+
+	if (!get_machdep_kernel_start(info))
+		return FALSE;
+
 	if (!check_release(info))
 		return FALSE;
 
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -377,6 +377,7 @@ int get_machdep_info_x86();
 #define get_phys_base(X)	TRUE
 #define get_machdep_info(X)	get_machdep_info_x86(X)
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X,Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif /* x86 */
 
 #ifdef __x86_64__
@@ -386,6 +387,7 @@ off_t vaddr_to_offset_x86_64();
 #define get_phys_base(X)	get_phys_base_x86_64(X)
 #define get_machdep_info(X)	get_machdep_info_x86_64(X)
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_x86_64(X, Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif /* x86_64 */
 
 #ifdef __powerpc__ /* powerpc */
@@ -393,14 +395,18 @@ int get_machdep_info_ppc64();
 #define get_machdep_info(X)	get_machdep_info_ppc64(X)
 #define get_phys_base(X)	TRUE
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X, Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif          /* powerpc */
 
 #ifdef __ia64__ /* ia64 */
 int get_phys_base_ia64();
 int get_machdep_info_ia64();
+int get_machdep_kernel_start_ia64();
+off_t vaddr_to_offset_ia64();
 #define get_machdep_info(X)	get_machdep_info_ia64(X)
 #define get_phys_base(X)	get_phys_base_ia64(X)
-#define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X, Y)
+#define get_machdep_kernel_start(X)	get_machdep_kernel_start_ia64(X)
+#define vaddr_to_offset(X, Y)	vaddr_to_offset_ia64(X, Y)
 #define VADDR_REGION(X)		((X) >> REGION_SHIFT)
 #endif          /* ia64 */
 
@@ -491,6 +497,7 @@ struct DumpInfo {
 	unsigned long   max_physmem_bits;
 	unsigned long   sections_per_root;
 	unsigned long	phys_base;
+	unsigned long   kernel_start;
 
 	/*
 	 * diskdimp info:

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
@ 2007-04-27 10:31 tachibana
  0 siblings, 0 replies; 10+ messages in thread
From: tachibana @ 2007-04-27 10:31 UTC (permalink / raw)
  To: kexec

Hi Bernhard-san,

Sorry, the subject was wrong.
I send my reply again.

2007/04/26 14:21:53 +0200, Bernhard Walle <bwalle@suse.de> wrote:
>
>Hello,
>
>I found in your announcment of makedumpfile 1.1.1:
>
>  Todo:
>     - ia64 DISCONTIGMEM support
>
>Did you already do something in this area? If you have something to
>test, I'd be happy. :)

Thank you for your vaddr_to_offset_ia64() patch.
We are currently investigating ia64 discontigmem, and
your patch will be our help.
I think your patch has problems when translating virtual address into
physical address for ia64 discontigmem if layer 3 (or layer 4)
paging is necessary.

In Japan, we have a vacation on April 28th - May 6th.
Sorry, we will reply again after the vacation.


Thanks
tachibana

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-04-26 19:37 [PATCH] [makedumpfile] Implement memory regions on IA64 Bernhard Walle
@ 2007-05-11  6:59 ` Ken'ichi Ohmichi
  2007-05-14 18:15   ` Bernhard Walle
  0 siblings, 1 reply; 10+ messages in thread
From: Ken'ichi Ohmichi @ 2007-05-11  6:59 UTC (permalink / raw)
  To: Bernhard Walle; +Cc: Jay Lan, Kexec Mailing List

[-- Attachment #1: Type: text/plain, Size: 1165 bytes --]


Hi Bernhard,

2007/04/26 21:37:25 +0200, Bernhard Walle <bwalle@suse.de> wrote:
>This patch fixes an error in vaddr_to_offset_ia64() which happened on
>a SGI machine here while retrieving the utsname from the kernel dump
>image. It implements memory region support for IA64.

Thank you for the patch.

For ia64 DISCONTIGMEM support, I added the translation (virtual address
to physical address) by using layer 3 paging into your patch.
I created 2 attached patches for ia64 DISCONTIGMEM support.

I confirmed makedumpfile with these patches can run on linux-2.6.18 kernel
(made of RHEL5 kernel by changing configs from SPARSEMEM to DISCONTIGMEM).
Could you please test them on SLES10 ?

BTW, the patches don't run on stock linux-2.6.20 w/DISCONTIGMEM
(it works with stock linux-2.6.20 w/SPARSEMEM)
I am trying to resolve the problem and if you have any idea about
kernel changes between 2.6.18-20, please let me know.


The attached patches (for makedumpfile version 1.1.3):
- 01-vaddr_to_offset_ia64.patch
  The translation by using layer 3 paging is added to Bernhard's patch.

- 02-ia64-discontigmem.patch
  ia64 DISCONTIGMEM support.


Thanks
Ken'ichi Ohmichi

[-- Attachment #2: 02-ia64-discontigmem.patch --]
[-- Type: application/octet-stream, Size: 3504 bytes --]

diff -puN makedumpfile.org/makedumpfile.c makedumpfile/makedumpfile.c
--- makedumpfile.org/makedumpfile.c	2007-05-11 23:06:33.000000000 +0900
+++ makedumpfile/makedumpfile.c	2007-05-11 23:55:33.000000000 +0900
@@ -1455,6 +1455,8 @@ get_structure_info(struct DumpInfo *info
 	OFFSET_INIT(pglist_data.node_start_pfn, "pglist_data","node_start_pfn");
 	OFFSET_INIT(pglist_data.node_spanned_pages, "pglist_data",
 	    "node_spanned_pages");
+	OFFSET_INIT(pglist_data.pgdat_next, "pglist_data",
+	    "pgdat_next");
 
 	/*
 	 * Get offsets of the zone's members.
@@ -1502,7 +1504,12 @@ get_mem_type(struct DumpInfo *info)
 	    || (OFFSET(page._count) == NOT_FOUND_STRUCTURE)
 	    || (OFFSET(page.mapping) == NOT_FOUND_STRUCTURE)) {
 		ret = NOT_FOUND_MEMTYPE;
-	} else if ((SYMBOL(node_data) != NOT_FOUND_SYMBOL)
+	} else if ((((SYMBOL(node_data) != NOT_FOUND_SYMBOL)
+	        && (ARRAY_LENGTH(node_data) != NOT_FOUND_STRUCTURE))
+	    || ((SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
+	        && (OFFSET(pglist_data.pgdat_next) != NOT_FOUND_STRUCTURE))
+	    || ((SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
+	        && (ARRAY_LENGTH(pgdat_list) != NOT_FOUND_STRUCTURE)))
 	    && (SIZE(pglist_data) != NOT_FOUND_STRUCTURE)
 	    && (OFFSET(pglist_data.node_mem_map) != NOT_FOUND_STRUCTURE)
 	    && (OFFSET(pglist_data.node_start_pfn) != NOT_FOUND_STRUCTURE)
@@ -1613,6 +1620,8 @@ generate_config(struct DumpInfo *info)
 	    pglist_data.node_start_pfn);
 	WRITE_MEMBER_OFFSET("pglist_data.node_spanned_pages",
 	    pglist_data.node_spanned_pages);
+	WRITE_MEMBER_OFFSET("pglist_data.pgdat_next",
+	    pglist_data.pgdat_next);
 	WRITE_MEMBER_OFFSET("zone.free_pages", zone.free_pages);
 	WRITE_MEMBER_OFFSET("zone.free_area", zone.free_area);
 	WRITE_MEMBER_OFFSET("zone.vm_stat", zone.vm_stat);
@@ -1782,6 +1791,8 @@ read_config(struct DumpInfo *info)
 	    pglist_data.node_start_pfn);
 	READ_MEMBER_OFFSET("pglist_data.node_spanned_pages",
 	    pglist_data.node_spanned_pages);
+	READ_MEMBER_OFFSET("pglist_data.pgdat_next",
+	    pglist_data.pgdat_next);
 	READ_MEMBER_OFFSET("zone.free_pages", zone.free_pages);
 	READ_MEMBER_OFFSET("zone.free_area", zone.free_area);
 	READ_MEMBER_OFFSET("zone.vm_stat", zone.vm_stat);
@@ -1880,6 +1891,7 @@ next_online_node(int first)
 unsigned long
 next_online_pgdat(struct DumpInfo *info, int node)
 {
+	int i;
 	unsigned long pgdat;
 
 	/*
@@ -1926,6 +1938,33 @@ pgdat2:
 
 pgdat3:
 	/*
+	 * linux-2.6.16 or before
+	 */
+	if ((SYMBOL(pgdat_list) == NOT_FOUND_SYMBOL)
+	    || (OFFSET(pglist_data.pgdat_next) == NOT_FOUND_STRUCTURE))
+		goto pgdat4;
+
+	if (!readmem(info, SYMBOL(pgdat_list), &pgdat, sizeof pgdat))
+		goto pgdat4;
+
+	if (!is_kvaddr(pgdat))
+		goto pgdat4;
+
+	if (node == 0)
+		return pgdat;
+
+	for (i = 1; i < node; i++) {
+		if (!readmem(info, pgdat + OFFSET(pglist_data.pgdat_next),
+		    &pgdat, sizeof pgdat))
+			goto pgdat4;
+
+		if (!is_kvaddr(pgdat))
+			goto pgdat4;
+	}
+	return pgdat;
+
+pgdat4:
+	/*
 	 * Get the pglist_data structure from symbol "contig_page_data".
 	 */
 	if (SYMBOL(contig_page_data) == NOT_FOUND_SYMBOL)
diff -puN makedumpfile.org/makedumpfile.h makedumpfile/makedumpfile.h
--- makedumpfile.org/makedumpfile.h	2007-05-11 23:06:33.000000000 +0900
+++ makedumpfile/makedumpfile.h	2007-05-11 23:20:00.000000000 +0900
@@ -612,6 +612,7 @@ struct offset_table {
 		long	node_mem_map;
 		long	node_start_pfn;
 		long	node_spanned_pages;
+		long	pgdat_next;
 	} pglist_data;
 	struct free_area {
 		long	free_list;

[-- Attachment #3: 01-vaddr_to_offset_ia64.patch --]
[-- Type: application/octet-stream, Size: 8580 bytes --]

Signed-off-by: Bernhard Walle <bwalle@suse.de>
Signed-off-by: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
---

diff -puN backup/v1.1.3/ia64.c makedumpfile/ia64.c
--- backup/v1.1.3/ia64.c	2007-04-13 15:44:45.000000000 +0900
+++ makedumpfile/ia64.c	2007-05-11 23:02:25.000000000 +0900
@@ -23,6 +23,8 @@ get_phys_base_ia64(struct DumpInfo *info
 	int i;
 	struct pt_load_segment *pls;
 
+	info->phys_base = 0;
+
 	/*
 	 *  Default to 64MB.
 	 */
@@ -48,5 +50,125 @@ get_machdep_info_ia64(struct DumpInfo *i
 	return TRUE;
 }
 
+unsigned long
+ia64_vtop(struct DumpInfo *info, unsigned long long vaddr)
+{
+	unsigned long paddr = 0, temp, page_dir, pgd_pte, page_middle, pmd_pte;
+	unsigned long page_table, pte;
+
+	if (VADDR_REGION(vaddr) != KERNEL_VMALLOC_REGION) {
+		ERRMSG("vaddr(%llx) is not KERNEL_VMALLOC_REGION.\n", vaddr);
+		return paddr;
+	}
+	paddr = vaddr_to_paddr(info, vaddr);
+	if (paddr)
+		return paddr;
+
+	/*
+	 * Translate a virtual address to a physical address
+	 * by using Layer 3 paging.
+	 */
+	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
+		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
+		return paddr;
+	}
+
+	/*
+	 * Get PGD
+	 */
+	temp = vaddr & MASK_PGD;
+	temp = temp >> (PGDIR_SHIFT - 3);
+	page_dir = SYMBOL(swapper_pg_dir) + temp;
+	if (!readmem(info, page_dir, &pgd_pte, sizeof pgd_pte)) {
+		ERRMSG("Can't get pgd_pte (page_dir:%lx).\n", page_dir);
+		return paddr;
+	}
+
+	/*
+	 * Get PMD
+	 */
+	temp = vaddr & MASK_PMD;
+	temp = temp >> (PMD_SHIFT - 3);
+	page_middle = pgd_pte + temp;
+	/*
+	 * Convert physical address to virtual address
+	 */
+	page_middle = paddr_to_vaddr(info, page_middle);
+	if (!readmem(info, page_middle, &pmd_pte, sizeof pmd_pte)) {
+		ERRMSG("Can't get pmd_pte (page_middle:%lx).\n", page_middle);
+		return paddr;
+	}
+
+	/*
+	 * Get PTE
+	 */
+	temp = vaddr & MASK_PTE;
+	temp = temp >> (PAGE_SHIFT - 3);
+	page_table = pmd_pte + temp;
+	/*
+	 * Convert physical address to virtual address
+	 */
+	page_table = paddr_to_vaddr(info, page_table);
+	if (!readmem(info, page_table, &pte, sizeof pte)) {
+		ERRMSG("Can't get pte (page_table:%lx).\n", page_table);
+		return paddr;
+	}
+
+	/*
+	 * Get physical address
+	 */
+	temp = vaddr & MASK_POFFSET;
+	paddr = (pte & _PAGE_PPN_MASK) + temp;
+	if (info->flag_debug) {
+		MSG("vaddr:%llx -> paddr:%lx\n", vaddr, paddr);
+	}
+
+	return paddr;
+}
+
+
+/*
+ * Convert Virtual Address to File Offest.
+ */
+off_t
+vaddr_to_offset_ia64(struct DumpInfo *info, unsigned long long vaddr)
+{
+	int i;
+	off_t offset;
+	struct pt_load_segment *pls;
+	unsigned long paddr;
+
+
+	switch (VADDR_REGION(vaddr)) {
+		case KERNEL_CACHED_REGION:
+			paddr = vaddr - (ulong)(KERNEL_CACHED_BASE);
+			break;
+
+		case KERNEL_UNCACHED_REGION:
+			paddr = vaddr - (ulong)(KERNEL_UNCACHED_BASE);
+			break;
+
+		case KERNEL_VMALLOC_REGION:
+			paddr = ia64_vtop(info, vaddr);
+			break;
+
+		default:
+			ERRMSG("Unknown region (%ld)\n", VADDR_REGION(vaddr));
+			return 0;
+	}
+
+	for (i = offset = 0; i < info->num_load_memory; i++) {
+		pls = &info->pt_load_segments[i];
+		if ((paddr >= pls->phys_start)
+		    && (paddr < pls->phys_end)) {
+			offset = (off_t)(paddr - pls->phys_start) +
+				pls->file_offset;
+				break;
+		}
+	}
+
+	return offset;
+}
+
 #endif /* ia64 */
 
diff -puN backup/v1.1.3/makedumpfile.c makedumpfile/makedumpfile.c
--- backup/v1.1.3/makedumpfile.c	2007-04-13 15:44:55.000000000 +0900
+++ makedumpfile/makedumpfile.c	2007-05-11 23:02:25.000000000 +0900
@@ -64,6 +64,44 @@ paddr_to_offset(struct DumpInfo *info, u
 	return offset;
 }
 
+unsigned long long
+vaddr_to_paddr(struct DumpInfo *info, unsigned long long vaddr)
+{
+	int i;
+	unsigned long long paddr;
+	struct pt_load_segment *pls;
+
+	for (i = paddr = 0; i < info->num_load_memory; i++) {
+		pls = &info->pt_load_segments[i];
+		if ((vaddr >= pls->virt_start)
+		    && (vaddr < pls->virt_end)) {
+			paddr = (off_t)(vaddr - pls->virt_start) +
+				pls->phys_start;
+				break;
+		}
+	}
+	return paddr;
+}
+
+unsigned long long
+paddr_to_vaddr(struct DumpInfo *info, unsigned long long paddr)
+{
+	int i;
+	unsigned long long vaddr;
+	struct pt_load_segment *pls;
+
+	for (i = vaddr = 0; i < info->num_load_memory; i++) {
+		pls = &info->pt_load_segments[i];
+		if ((paddr >= pls->phys_start)
+		    && (paddr < pls->phys_end)) {
+			vaddr = (off_t)(paddr - pls->phys_start) +
+				pls->virt_start;
+				break;
+		}
+	}
+	return vaddr;
+}
+
 /*
  * Convert Virtual Address to File Offest.
  *  If this function returns 0x0, File Offset isn't found.
@@ -735,6 +773,7 @@ get_elf_info(struct DumpInfo *info)
 	 *   capture(2nd)-kernel, the problem will happen.
 	 */
 	info->page_size = sysconf(_SC_PAGE_SIZE);
+	info->page_shift = ffs(info->page_size) - 1;
 
 	info->max_mapnr = get_max_mapnr(info);
 
@@ -1364,6 +1403,7 @@ get_symbol_info(struct DumpInfo *info)
 	SYMBOL_INIT(system_utsname, "system_utsname");
 	SYMBOL_INIT(init_uts_ns, "init_uts_ns");
 	SYMBOL_INIT(_stext, "_stext");
+	SYMBOL_INIT(swapper_pg_dir, "swapper_pg_dir");
 	SYMBOL_INIT(phys_base, "phys_base");
 	SYMBOL_INIT(node_online_map, "node_online_map");
 	SYMBOL_INIT(node_data, "node_data");
@@ -1539,6 +1579,7 @@ generate_config(struct DumpInfo *info)
 	WRITE_SYMBOL("system_utsname", system_utsname);
 	WRITE_SYMBOL("init_uts_ns", init_uts_ns);
 	WRITE_SYMBOL("_stext", _stext);
+	WRITE_SYMBOL("swapper_pg_dir", swapper_pg_dir);
 	WRITE_SYMBOL("phys_base", phys_base);
 	WRITE_SYMBOL("node_online_map", node_online_map);
 	WRITE_SYMBOL("node_data", node_data);
@@ -1631,6 +1672,7 @@ read_config_basic_info(struct DumpInfo *
 			break;
 	}
 	info->page_size = page_size;
+	info->page_shift = ffs(info->page_size) - 1;
 
 	if (!get_release || !info->page_size) {
 		ERRMSG("Invalid format in %s", info->name_configfile);
@@ -1713,6 +1755,7 @@ read_config(struct DumpInfo *info)
 	READ_SYMBOL("system_utsname", system_utsname);
 	READ_SYMBOL("init_uts_ns", init_uts_ns);
 	READ_SYMBOL("_stext", _stext);
+	READ_SYMBOL("swapper_pg_dir", swapper_pg_dir);
 	READ_SYMBOL("phys_base", phys_base);
 	READ_SYMBOL("node_online_map", node_online_map);
 	READ_SYMBOL("node_data", node_data);
@@ -2206,6 +2249,7 @@ initial(struct DumpInfo *info)
 		if (!get_structure_info(info))
 			return FALSE;
 	}
+
 	if (!check_release(info))
 		return FALSE;
 
diff -puN backup/v1.1.3/makedumpfile.h makedumpfile/makedumpfile.h
--- backup/v1.1.3/makedumpfile.h	2007-04-13 15:44:55.000000000 +0900
+++ makedumpfile/makedumpfile.h	2007-05-11 23:02:25.000000000 +0900
@@ -367,6 +367,22 @@ do { \
 #define _SECTION_SIZE_BITS	(30)
 #define _MAX_PHYSMEM_BITS	(50)
 #define SIZEOF_NODE_ONLINE_MAP	(32)
+
+/*
+ * Layer 3 paging
+ */
+#define _PAGE_PPN_MASK		(((1UL << _MAX_PHYSMEM_BITS) - 1) & ~0xfffUL)
+#define PAGE_SHIFT		(info->page_shift)
+#define PTRS_PER_PTD_SHIFT	(PAGE_SHIFT - 3)
+
+#define PMD_SHIFT		(PAGE_SHIFT + PTRS_PER_PTD_SHIFT)
+#define PGDIR_SHIFT		(PMD_SHIFT  + PTRS_PER_PTD_SHIFT)
+
+#define MASK_POFFSET	((1UL << PAGE_SHIFT) - 1)
+#define MASK_PTE	((1UL << PMD_SHIFT) - 1) &~((1UL << PAGE_SHIFT) - 1)
+#define MASK_PMD	((1UL << PGDIR_SHIFT) - 1) &~((1UL << PMD_SHIFT) - 1)
+#define MASK_PGD	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT) - 1))
+
 #endif          /* ia64 */
 
 /*
@@ -398,10 +414,11 @@ int get_machdep_info_ppc64();
 #ifdef __ia64__ /* ia64 */
 int get_phys_base_ia64();
 int get_machdep_info_ia64();
+off_t vaddr_to_offset_ia64();
 #define get_machdep_info(X)	get_machdep_info_ia64(X)
 #define get_phys_base(X)	get_phys_base_ia64(X)
-#define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X, Y)
-#define VADDR_REGION(X)		((X) >> REGION_SHIFT)
+#define vaddr_to_offset(X, Y)	vaddr_to_offset_ia64(X, Y)
+#define VADDR_REGION(X)		(((unsigned long)(X)) >> REGION_SHIFT)
 #endif          /* ia64 */
 
 #define MSG(x...)	fprintf(stderr, x)
@@ -486,6 +503,7 @@ struct DumpInfo {
 	int		flag_rearrange;      /* flag of creating dumpfile from
 						flattened format */
 	long		page_size;           /* size of page */
+	long		page_shift;
 	unsigned long long	max_mapnr;   /* number of page descriptor */
 	unsigned long   section_size_bits;
 	unsigned long   max_physmem_bits;
@@ -555,6 +573,7 @@ struct symbol_table {
 	unsigned long	system_utsname;
 	unsigned long	init_uts_ns;
 	unsigned long	_stext;
+	unsigned long	swapper_pg_dir;
 	unsigned long	phys_base;
 	unsigned long	node_online_map;
 	unsigned long	node_data;
@@ -651,3 +670,7 @@ struct dwarf_info {
 
 extern struct dwarf_info	dwarf_info;
 
+int readmem();
+unsigned long long vaddr_to_paddr();
+unsigned long long paddr_to_vaddr();
+

[-- Attachment #4: Type: text/plain, Size: 143 bytes --]

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-11  6:59 ` Ken'ichi Ohmichi
@ 2007-05-14 18:15   ` Bernhard Walle
  2007-05-14 21:49     ` Bernhard Walle
  0 siblings, 1 reply; 10+ messages in thread
From: Bernhard Walle @ 2007-05-14 18:15 UTC (permalink / raw)
  To: Ken'ichi Ohmichi; +Cc: Jay Lan, Kexec Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 1304 bytes --]

Hi,

sorry for the late reply, but I was out of office last week.

* Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> [2007-05-11 08:59]:
> 2007/04/26 21:37:25 +0200, Bernhard Walle <bwalle@suse.de> wrote:
> >This patch fixes an error in vaddr_to_offset_ia64() which happened on
> >a SGI machine here while retrieving the utsname from the kernel dump
> >image. It implements memory region support for IA64.
> 
> For ia64 DISCONTIGMEM support, I added the translation (virtual address
> to physical address) by using layer 3 paging into your patch.
> I created 2 attached patches for ia64 DISCONTIGMEM support.
> 
> I confirmed makedumpfile with these patches can run on linux-2.6.18 kernel
> (made of RHEL5 kernel by changing configs from SPARSEMEM to DISCONTIGMEM).
> Could you please test them on SLES10 ?

it doesn't work here. The config file is generated, but at runtime I
get a SEGV which is caused by a endless recusion of ia64_vtop() while
resolving the utsname.

I'm looking into this ...

> BTW, the patches don't run on stock linux-2.6.20 w/DISCONTIGMEM
> (it works with stock linux-2.6.20 w/SPARSEMEM)
> I am trying to resolve the problem and if you have any idea about
> kernel changes between 2.6.18-20, please let me know.

Sorry, no.



Thanks,
   Bernhard

[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 143 bytes --]

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-14 18:15   ` Bernhard Walle
@ 2007-05-14 21:49     ` Bernhard Walle
  2007-05-15 22:08       ` Bernhard Walle
  0 siblings, 1 reply; 10+ messages in thread
From: Bernhard Walle @ 2007-05-14 21:49 UTC (permalink / raw)
  To: Ken'ichi Ohmichi, Kexec Mailing List, Jay Lan


[-- Attachment #1.1: Type: text/plain, Size: 1530 bytes --]

* Bernhard Walle <bwalle@suse.de> [2007-05-14 20:15]:
> * Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> [2007-05-11 08:59]:
> > 2007/04/26 21:37:25 +0200, Bernhard Walle <bwalle@suse.de> wrote:
> > >This patch fixes an error in vaddr_to_offset_ia64() which happened on
> > >a SGI machine here while retrieving the utsname from the kernel dump
> > >image. It implements memory region support for IA64.
> > 
> > For ia64 DISCONTIGMEM support, I added the translation (virtual address
> > to physical address) by using layer 3 paging into your patch.
> > I created 2 attached patches for ia64 DISCONTIGMEM support.
> > 
> > I confirmed makedumpfile with these patches can run on linux-2.6.18 kernel
> > (made of RHEL5 kernel by changing configs from SPARSEMEM to DISCONTIGMEM).
> > Could you please test them on SLES10 ?
> 
> it doesn't work here. The config file is generated, but at runtime I
> get a SEGV which is caused by a endless recusion of ia64_vtop() while
> resolving the utsname.

Because of CONFIG_PGTABLE_4=y in SUSE kernels. Your implementation
assumes a 3-level-pagetable.

> > BTW, the patches don't run on stock linux-2.6.20 w/DISCONTIGMEM
> > (it works with stock linux-2.6.20 w/SPARSEMEM)
> > I am trying to resolve the problem and if you have any idea about
> > kernel changes between 2.6.18-20, please let me know.
> 
> Sorry, no.

And I guess because of the same reason (maybe the default changed?).

I'm working on support for the 4 layer pagetable.



Thanks,
   Bernhard

[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 143 bytes --]

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-14 21:49     ` Bernhard Walle
@ 2007-05-15 22:08       ` Bernhard Walle
  2007-05-16 11:20         ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 10+ messages in thread
From: Bernhard Walle @ 2007-05-15 22:08 UTC (permalink / raw)
  To: Ken'ichi Ohmichi; +Cc: Jay Lan, Kexec Mailing List

Hello,

* Bernhard Walle <bwalle@suse.de> [2007-05-14 23:49]:
> 
> I'm working on support for the 4 layer pagetable.

Here's my first attempt. It works with SLES 10, SP1 on a Tiger4
machine with 16 GiB of memory. (I had still problems with a big
SGI machine when creating the bitmap. I'm investigating this, too.)

The problem is not to implement the 4 layer page table, but to
*detect* it. crash uses the built-in configuration data in the kernel
image, and that's what I used in my patch. If you have a better and
still reliable method, I'm open to suggestions. :-)

Also, I only use the page table translation when the memory is
vmalloc'd. That's the same way crash does it and that should be
well-tested.

The patch requires your two patches. Please give me your feedback!
And I hope I didn't accidentally break the 3 layer page table.


Thanks,
   Bernhard



---
 ia64.c         |  148 +++++++++++++++++++++++++++++++++++++++++++++---
 makedumpfile.c |  174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |   43 +++++++++++++-
 3 files changed, 354 insertions(+), 11 deletions(-)

--- a/ia64.c
+++ b/ia64.c
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 2006  NEC Corporation
  *
+ * Some parts are taken and adapted from the crash-utility,
+ * (c) by RedHat Inc.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -17,6 +20,18 @@
 
 #include "makedumpfile.h"
 
+
+/*
+ *  vmalloc() starting address is either the traditional 0xa000000000000000 or
+ *  bumped up in 2.6 to 0xa000000200000000.
+ */
+int
+is_vmalloc_addr_ia64(struct DumpInfo *info, unsigned long vaddr)
+{
+	return ((vaddr >= info->vmalloc_start) &&
+			(vaddr < (ulong)KERNEL_UNCACHED_BASE));
+}
+
 int
 get_phys_base_ia64(struct DumpInfo *info)
 {
@@ -51,18 +66,80 @@ get_machdep_info_ia64(struct DumpInfo *i
 }
 
 unsigned long
-ia64_vtop(struct DumpInfo *info, unsigned long long vaddr)
+ia64_vtop3(struct DumpInfo *info, unsigned long long vaddr)
 {
 	unsigned long paddr = 0, temp, page_dir, pgd_pte, page_middle, pmd_pte;
 	unsigned long page_table, pte;
 
-	if (VADDR_REGION(vaddr) != KERNEL_VMALLOC_REGION) {
-		ERRMSG("vaddr(%llx) is not KERNEL_VMALLOC_REGION.\n", vaddr);
+
+	/*
+	 * Translate a virtual address to a physical address
+	 * by using Layer 3 paging.
+	 */
+	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
+		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
 		return paddr;
 	}
-	paddr = vaddr_to_paddr(info, vaddr);
-	if (paddr)
+
+	/*
+	 * Get PGD
+	 */
+	temp = vaddr & MASK_PGD_3L;
+	temp = temp >> (PGDIR_SHIFT_3L - 3);
+	page_dir = SYMBOL(swapper_pg_dir) + temp;
+	if (!readmem(info, page_dir, &pgd_pte, sizeof pgd_pte)) {
+		ERRMSG("Can't get pgd_pte (page_dir:%lx).\n", page_dir);
 		return paddr;
+	}
+
+	/*
+	 * Get PMD
+	 */
+	temp = vaddr & MASK_PMD;
+	temp = temp >> (PMD_SHIFT - 3);
+	page_middle = pgd_pte + temp;
+	/*
+	 * Convert physical address to virtual address
+	 */
+	page_middle = paddr_to_vaddr(info, page_middle);
+	if (!readmem(info, page_middle, &pmd_pte, sizeof pmd_pte)) {
+		ERRMSG("Can't get pmd_pte (page_middle:%lx).\n", page_middle);
+		return paddr;
+	}
+
+	/*
+	 * Get PTE
+	 */
+	temp = vaddr & MASK_PTE;
+	temp = temp >> (PAGE_SHIFT - 3);
+	page_table = pmd_pte + temp;
+	/*
+	 * Convert physical address to virtual address
+	 */
+	page_table = paddr_to_vaddr(info, page_table);
+	if (!readmem(info, page_table, &pte, sizeof pte)) {
+		ERRMSG("Can't get pte (page_table:%lx).\n", page_table);
+		return paddr;
+	}
+
+	/*
+	 * Get physical address
+	 */
+	temp = vaddr & MASK_POFFSET;
+	paddr = (pte & _PAGE_PPN_MASK) + temp;
+	if (info->flag_debug) {
+		MSG("vaddr:%llx -> paddr:%lx\n", vaddr, paddr);
+	}
+
+	return paddr;
+}
+
+unsigned long
+ia64_vtop4(struct DumpInfo *info, unsigned long long vaddr)
+{
+	unsigned long paddr = 0, temp, page_dir, pgd_pte, page_upper,
+		      pud_pte, page_middle, pmd_pte;
+	unsigned long page_table, pte;
 
 	/*
 	 * Translate a virtual address to a physical address
@@ -76,8 +153,8 @@ ia64_vtop(struct DumpInfo *info, unsigne
 	/*
 	 * Get PGD
 	 */
-	temp = vaddr & MASK_PGD;
-	temp = temp >> (PGDIR_SHIFT - 3);
+	temp = vaddr & MASK_PGD_4L;
+	temp = temp >> (PGDIR_SHIFT_4L - 3);
 	page_dir = SYMBOL(swapper_pg_dir) + temp;
 	if (!readmem(info, page_dir, &pgd_pte, sizeof pgd_pte)) {
 		ERRMSG("Can't get pgd_pte (page_dir:%lx).\n", page_dir);
@@ -85,11 +162,26 @@ ia64_vtop(struct DumpInfo *info, unsigne
 	}
 
 	/*
+	 * Get PUD
+	 */
+	temp = vaddr & MASK_PUD;
+	temp = temp >> (PUD_SHIFT - 3);
+	page_upper = pgd_pte + temp;
+	/*
+	 * Convert physical address to virtual address
+	 */
+	page_upper = paddr_to_vaddr(info, page_upper);
+	if (!readmem(info, page_upper, &pud_pte, sizeof pud_pte)) {
+		ERRMSG("Can't get pud_pte (page_upper:%lx).\n", page_upper);
+		return paddr;
+	}
+
+	/*
 	 * Get PMD
 	 */
 	temp = vaddr & MASK_PMD;
 	temp = temp >> (PMD_SHIFT - 3);
-	page_middle = pgd_pte + temp;
+	page_middle = pud_pte + temp;
 	/*
 	 * Convert physical address to virtual address
 	 */
@@ -126,6 +218,30 @@ ia64_vtop(struct DumpInfo *info, unsigne
 	return paddr;
 }
 
+unsigned long
+ia64_vtop(struct DumpInfo *info, unsigned long long vaddr)
+{
+	unsigned long paddr = 0;
+
+	if (VADDR_REGION(vaddr) != KERNEL_VMALLOC_REGION) {
+		ERRMSG("vaddr(%llx) is not KERNEL_VMALLOC_REGION.\n", vaddr);
+		return paddr;
+	}
+	paddr = vaddr_to_paddr(info, vaddr);
+	if (paddr)
+		return paddr;
+
+	if (!is_vmalloc_addr_ia64(info, vaddr)) {
+		paddr = vaddr - info->kernel_start +
+			(info->phys_base & KERNEL_TR_PAGE_MASK);
+		return paddr;
+	}
+
+	if (info->mem_flags & MEMORY_4LAYER_PAGETABLE)
+		return ia64_vtop4(info, vaddr);
+	else
+		return ia64_vtop3(info, vaddr);
+}
 
 /*
  * Convert Virtual Address to File Offest.
@@ -170,5 +286,21 @@ vaddr_to_offset_ia64(struct DumpInfo *in
 	return offset;
 }
 
+int
+get_machdep_kernel_start_ia64(struct DumpInfo *info)
+{
+	if (SYMBOL(_stext) == NOT_FOUND_SYMBOL)
+		return FALSE;
+
+	info->kernel_start = SYMBOL(_stext);
+
+	if (VADDR_REGION(info->kernel_start) == KERNEL_VMALLOC_REGION)
+		info->vmalloc_start = info->kernel_start + 4*1024UL*1024UL*1024UL;
+	else
+		info->vmalloc_start = KERNEL_VMALLOC_BASE;
+
+	return TRUE;
+}
+
 #endif /* ia64 */
 
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1420,6 +1420,174 @@ get_symbol_info(struct DumpInfo *info)
 	return TRUE;
 }
 
+
+int
+read_kernel_config(struct DumpInfo *info)
+{
+	int ii, ret, end, found=0;
+	unsigned long size, bufsz;
+	char *pos, *ln, *buf, *head, *tail, *val, *uncomp;
+	char line[512];
+	z_stream stream;
+	unsigned long kernel_config_data;
+
+	kernel_config_data = get_symbol_addr(info, "kernel_config_data");
+	if (kernel_config_data <= 0) {
+		ERRMSG("Can't read kernel cofiguration from kernel binary");
+		return FALSE;
+	}
+
+	/* We don't know how large IKCONFIG is, so we start with
+	 * 32k, if we can't find MAGIC_END assume we didn't read
+	 * enough, double it and try again.
+	 */
+	ii = 32;
+
+again:
+	size = ii * 1024;
+
+	if ((buf = (char *)malloc(size)) == NULL) {
+		MSG("cannot malloc IKCONFIG input buffer\n");
+		return FALSE;
+	}
+
+        if (!readmem(info, kernel_config_data, buf, size)) {
+		MSG("cannot read kernel_config_data\n");
+		goto out2;
+	}
+
+	/* Find the start */
+	if (strstr(buf, MAGIC_START))
+		head = buf + MAGIC_SIZE + 10; /* skip past MAGIC_START and gzip header */
+	else {
+		MSG("could not find MAGIC_START!\n");
+		goto out2;
+	}
+
+	tail = head;
+
+	end = strlen(MAGIC_END);
+
+	/* Find the end*/
+	while (tail < (buf + (size - 1))) {
+
+		if (strncmp(tail, MAGIC_END, end)==0) {
+			found = 1;
+			break;
+		}
+		tail++;
+	}
+
+	if (found) {
+		bufsz = tail - head;
+		size = 10 * bufsz;
+		if ((uncomp = (char *)malloc(size)) == NULL) {
+			MSG("cannot malloc IKCONFIG output buffer\n");
+			goto out2;
+		}
+	} else {
+		if (ii > 512) {
+			MSG("could not find MAGIC_END!\n");
+			goto out2;
+		} else {
+			free(buf);
+			ii *= 2;
+			goto again;
+		}
+	}
+
+
+	/* initialize zlib */
+	stream.next_in = (Bytef *)head;
+	stream.avail_in = (uInt)bufsz;
+
+	stream.next_out = (Bytef *)uncomp;
+	stream.avail_out = (uInt)size;
+
+	stream.zalloc = NULL;
+	stream.zfree = NULL;
+	stream.opaque = NULL;
+
+	ret = inflateInit2(&stream, -MAX_WBITS);
+	if (ret != Z_OK) {
+		ERRMSG("error while reading kernel config, inflateInit2 "
+				"returned %d\n", ret);
+		goto out1;
+	}
+
+	ret = inflate(&stream, Z_FINISH);
+
+	if (ret != Z_STREAM_END) {
+		inflateEnd(&stream);
+		if (ret == Z_NEED_DICT ||
+		   (ret == Z_BUF_ERROR && stream.avail_in == 0)) {
+			ERRMSG("error while reading kernel config, stream.avail_in = 0,"
+					"inflate returned %d\n", ret);
+			goto out1;
+		}
+		ERRMSG("error while reading kernel config, inflate returned"
+				"with %d\n", ret);
+		goto out1;
+	}
+	size = stream.total_out;
+
+	ret = inflateEnd(&stream);
+
+	pos = uncomp;
+
+	do {
+		ret = sscanf(pos, "%511[^\n]\n%n", line, &ii);
+		if (ret > 0) {
+			pos += ii;
+
+			ln = line;
+
+			/* skip leading whitespace */
+			while (is_blank(*ln))
+				ln++;
+
+			/* skip comments */
+			if (*ln == '#')
+				continue;
+
+			/* Find '=' */
+			if ((head = strchr(ln, '=')) != NULL) {
+				*head = '\0';
+				val = head + 1;
+
+				head--;
+
+				/* skip trailing whitespace */
+				while (is_blank(*head)) {
+					*head = '\0';
+					head--;
+				}
+
+				/* skip whitespace */
+				while (is_blank(*val))
+					val++;
+
+			} else /* Bad line, skip it */
+				continue;
+
+			if (strcmp(ln, "CONFIG_PGTABLE_4") == 0)
+				info->mem_flags |= MEMORY_4LAYER_PAGETABLE;
+		}
+	} while (ret > 0);
+
+
+	free(uncomp);
+	free(buf);
+	return TRUE;
+
+out1:
+	free(uncomp);
+out2:
+	free(buf);
+
+	return FALSE;
+}
+
 int
 get_structure_info(struct DumpInfo *info)
 {
@@ -2289,9 +2457,15 @@ initial(struct DumpInfo *info)
 			return FALSE;
 	}
 
+	if (!get_machdep_kernel_start(info))
+		return FALSE;
+
 	if (!check_release(info))
 		return FALSE;
 
+	if (!read_kernel_config(info))
+		return FALSE;
+
 	if (!get_machdep_info(info))
 		return FALSE;
 
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -29,6 +29,7 @@
 #include <libelf.h>
 #include <dwarf.h>
 #include <byteswap.h>
+#include <ctype.h>
 #include "diskdump_mod.h"
 
 /*
@@ -64,6 +65,19 @@ enum {
 #define LSEEKED_PDESC	(2)
 #define LSEEKED_PDATA	(3)
 
+/*
+ * Flags
+ */
+#define MEMORY_4LAYER_PAGETABLE	(1 << 0)
+
+/*
+ * For kernel configuration
+ */
+#define MAGIC_START  "IKCFG_ST"
+#define MAGIC_END    "IKCFG_ED"
+#define MAGIC_SIZE   (sizeof(MAGIC_START) - 1)
+
+
 static inline int
 test_bit(int nr, unsigned long addr)
 {
@@ -73,6 +87,12 @@ test_bit(int nr, unsigned long addr)
 	return ((mask & addr) != 0);
 }
 
+static inline int
+is_blank(int c)
+{
+	return c == ' ' || c == '\t';
+}
+
 #define isLRU(flags)		test_bit(PG_lru, flags)
 #define isPrivate(flags)	test_bit(PG_private, flags)
 #define isSwapCache(flags)	test_bit(PG_swapcache, flags)
@@ -376,12 +396,21 @@ do { \
 #define PTRS_PER_PTD_SHIFT	(PAGE_SHIFT - 3)
 
 #define PMD_SHIFT		(PAGE_SHIFT + PTRS_PER_PTD_SHIFT)
-#define PGDIR_SHIFT		(PMD_SHIFT  + PTRS_PER_PTD_SHIFT)
+#define PGDIR_SHIFT_3L		(PMD_SHIFT  + PTRS_PER_PTD_SHIFT)
 
 #define MASK_POFFSET	((1UL << PAGE_SHIFT) - 1)
 #define MASK_PTE	((1UL << PMD_SHIFT) - 1) &~((1UL << PAGE_SHIFT) - 1)
-#define MASK_PMD	((1UL << PGDIR_SHIFT) - 1) &~((1UL << PMD_SHIFT) - 1)
-#define MASK_PGD	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT) - 1))
+#define MASK_PMD	((1UL << PGDIR_SHIFT_3L) - 1) &~((1UL << PMD_SHIFT) - 1)
+#define MASK_PGD_3L	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT_3L) - 1))
+
+/*
+ * Layer 4 paging
+ */
+#define PUD_SHIFT		(PMD_SHIFT + PTRS_PER_PTD_SHIFT)
+#define PGDIR_SHIFT_4L		(PUD_SHIFT + PTRS_PER_PTD_SHIFT)
+
+#define MASK_PUD   	((1UL << REGION_SHIFT) - 1) & (~((1UL << PUD_SHIFT) - 1))
+#define MASK_PGD_4L	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT_4L) - 1))
 
 #endif          /* ia64 */
 
@@ -393,6 +422,7 @@ int get_machdep_info_x86();
 #define get_phys_base(X)	TRUE
 #define get_machdep_info(X)	get_machdep_info_x86(X)
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X,Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif /* x86 */
 
 #ifdef __x86_64__
@@ -402,6 +432,7 @@ off_t vaddr_to_offset_x86_64();
 #define get_phys_base(X)	get_phys_base_x86_64(X)
 #define get_machdep_info(X)	get_machdep_info_x86_64(X)
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_x86_64(X, Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif /* x86_64 */
 
 #ifdef __powerpc__ /* powerpc */
@@ -409,16 +440,19 @@ int get_machdep_info_ppc64();
 #define get_machdep_info(X)	get_machdep_info_ppc64(X)
 #define get_phys_base(X)	TRUE
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_general(X, Y)
+#define get_machdep_kernel_start(X)	TRUE
 #endif          /* powerpc */
 
 #ifdef __ia64__ /* ia64 */
 int get_phys_base_ia64();
 int get_machdep_info_ia64();
+int get_machdep_kernel_start_ia64();
 off_t vaddr_to_offset_ia64();
 #define get_machdep_info(X)	get_machdep_info_ia64(X)
 #define get_phys_base(X)	get_phys_base_ia64(X)
 #define vaddr_to_offset(X, Y)	vaddr_to_offset_ia64(X, Y)
 #define VADDR_REGION(X)		(((unsigned long)(X)) >> REGION_SHIFT)
+#define get_machdep_kernel_start(X)	get_machdep_kernel_start_ia64(X)
 #endif          /* ia64 */
 
 #define MSG(x...)	fprintf(stderr, x)
@@ -509,6 +543,8 @@ struct DumpInfo {
 	unsigned long   max_physmem_bits;
 	unsigned long   sections_per_root;
 	unsigned long	phys_base;
+	unsigned long   kernel_start;
+	unsigned long   vmalloc_start;
 
 	/*
 	 * diskdimp info:
@@ -532,6 +568,7 @@ struct DumpInfo {
 	 */
 	unsigned int		num_mem_map;
 	struct mem_map_data	*mem_map_data;
+	unsigned int		mem_flags;
 
 	/*
 	 * Dump memory image info:

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-15 22:08       ` Bernhard Walle
@ 2007-05-16 11:20         ` Ken'ichi Ohmichi
  2007-05-16 11:26           ` Bernhard Walle
  2007-05-21  9:32           ` Ken'ichi Ohmichi
  0 siblings, 2 replies; 10+ messages in thread
From: Ken'ichi Ohmichi @ 2007-05-16 11:20 UTC (permalink / raw)
  To: Bernhard Walle; +Cc: Jay Lan, Kexec Mailing List


Hi Bernhard,

2007/05/16 00:08:45 +0200, Bernhard Walle <bwalle@suse.de> wrote:
>Hello,
>
>* Bernhard Walle <bwalle@suse.de> [2007-05-14 23:49]:
>> 
>> I'm working on support for the 4 layer pagetable.
>
>Here's my first attempt. It works with SLES 10, SP1 on a Tiger4
>machine with 16 GiB of memory. (I had still problems with a big
>SGI machine when creating the bitmap. I'm investigating this, too.)
>
>The problem is not to implement the 4 layer page table, but to
>*detect* it. crash uses the built-in configuration data in the kernel
>image, and that's what I used in my patch. If you have a better and
>still reliable method, I'm open to suggestions. :-)

Thank you for the patch.
I tested makedumpfile with your patch on linux-2.6.18 ia64,
and it output the following message and failed.

Error message:
  $ makedumpfile -cd 31 -x vmlinux vmcore dumpfile
  Can't read kernel cofiguration from kernel binary
  makedumpfile Failed.
  $

The reason was that kernel binary file didn't have "kernel_config_data" 
because CONFIG_IKCONFIG was not set in my .config.
It is uncertain that "kernel_config_data" exists in a kernel binary.

I propose that makedumpfile distinguishes the page table (3L or 4L)
by checking the defined file name of pud_t.
I'm trying for the above implementation.
I will send you the patch when it is complete.

All the pud_t(s) of linux-2.6.16 - 2.6.21 are defined in the following files:

CONFIG_PGTABLE_4
  include/asm-ia64/page.h

!CONFIG_PGTABLE_4
  include/asm-generic/pgtable-nopud.h


Thanks
Ken'ichi Ohmichi

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-16 11:20         ` Ken'ichi Ohmichi
@ 2007-05-16 11:26           ` Bernhard Walle
  2007-05-21  9:32           ` Ken'ichi Ohmichi
  1 sibling, 0 replies; 10+ messages in thread
From: Bernhard Walle @ 2007-05-16 11:26 UTC (permalink / raw)
  To: Ken'ichi Ohmichi; +Cc: Jay Lan, Kexec Mailing List

* Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> [2007-05-16 13:20]:
> 
> I propose that makedumpfile distinguishes the page table (3L or 4L)
> by checking the defined file name of pud_t.
> I'm trying for the above implementation.
> I will send you the patch when it is complete.

If that works it's clearly the better approach.


Thanks,
   Bernhard
-- 
SUSE LINUX Products GmbH          Tel. +49 (911) 74053-0
Maxfeldstr. 5                     GF: Markus Rex
90409 Nürnberg, Germany           HRB 16746 (AG Nürnberg)
OpenPGP DDAF6454: F61F 34CC 09CA FB82 C9F6  BA4B 8865 3696 DDAF 6454

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-16 11:20         ` Ken'ichi Ohmichi
  2007-05-16 11:26           ` Bernhard Walle
@ 2007-05-21  9:32           ` Ken'ichi Ohmichi
  2007-05-21  9:54             ` Bernhard Walle
  1 sibling, 1 reply; 10+ messages in thread
From: Ken'ichi Ohmichi @ 2007-05-21  9:32 UTC (permalink / raw)
  To: Bernhard Walle; +Cc: Jay Lan, Kexec Mailing List


Hi Bernhard,

2007/05/16 20:20:00 +0900, "Ken'ichi Ohmichi" <oomichi@mxs.nes.nec.co.jp> wrote:
>I propose that makedumpfile distinguishes the page table (3L or 4L)
>by checking the defined file name of pud_t.
>I'm trying for the above implementation.
>I will send you the patch when it is complete.

The attached patch is for the above implementation.
It works fine with linux-2.6.18.
Could you test it with your environment ?

Please apply the attached patch with the following makedumpfile:

makedumpfile-1.1.3
 + 2007/05/11 by Ken'ichi, 01-vaddr_to_offset_ia64.patch 
 + 2007/05/11 by Ken'ichi, 02-ia64-discontigmem.patch
 + 2007/05/16 by Bernhard, [Re: Implement memory regions on IA64] patch
 + 2007/05/21 by Ken'ichi, [Re: Fix missing last node] patch


Thanks
Ken'ichi Ohmichi

--
diff -puN makedumpfile.org/ia64.c makedumpfile/ia64.c
--- makedumpfile.org/ia64.c	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/ia64.c	2007-05-21 19:34:06.000000000 +0900
@@ -62,6 +62,15 @@ get_machdep_info_ia64(struct DumpInfo *i
 	info->section_size_bits = _SECTION_SIZE_BITS;
 	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
 
+	if (!strncmp(SRCFILE(pud_t), STR_PUD_T_4L, strlen(STR_PUD_T_4L)))
+		info->mem_flags |= MEMORY_4LAYER_PAGETABLE;
+
+	else if (!strncmp(SRCFILE(pud_t), STR_PUD_T_3L, strlen(STR_PUD_T_3L)))
+		info->mem_flags |= MEMORY_3LAYER_PAGETABLE;
+
+	else
+		MSG("Can't distinguish the pgtable.\n");
+
 	return TRUE;
 }
 
diff -puN makedumpfile.org/makedumpfile.c makedumpfile/makedumpfile.c
--- makedumpfile.org/makedumpfile.c	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/makedumpfile.c	2007-05-21 19:28:54.000000000 +0900
@@ -26,6 +26,7 @@ struct symbol_table	symbol_table;
 struct size_table	size_table;
 struct offset_table	offset_table;
 struct array_table	array_table;
+struct srcfile_table	srcfile_table;
 
 struct dwarf_info	dwarf_info;
 struct vm_table		*vt = 0;
@@ -1141,6 +1142,15 @@ is_search_symbol(int cmd)
 		return FALSE;
 }
 
+int
+is_search_srcfile(int cmd)
+{
+	if (cmd == DWARF_INFO_GET_TYPEDEF_SRCNAME)
+		return TRUE;
+	else
+		return FALSE;
+}
+
 static void
 search_structure(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 {
@@ -1190,6 +1200,49 @@ search_structure(Dwarf *dwarfd, Dwarf_Di
 }
 
 static void
+search_srcfile(Dwarf *dwarfd, Dwarf_Die *die, int *found)
+{
+	int tag = 0, rtag = 0;
+	char *src_name = NULL;
+	const char *name;
+
+	switch (dwarf_info.cmd) {
+	case DWARF_INFO_GET_TYPEDEF_SRCNAME:
+		rtag = DW_TAG_typedef;
+		break;
+	}
+
+	/*
+	 * If we get to here then we don't have any more
+	 * children, check to see if this is a relevant tag
+	 */
+	do {
+		tag  = dwarf_tag(die);
+		name = dwarf_diename(die);
+
+		if ((tag != rtag) || (!name)
+		    || strcmp(name, dwarf_info.decl_name))
+			continue;
+
+		src_name = (char *)dwarf_decl_file(die);
+
+		if (!src_name)
+			break;
+
+	} while (!dwarf_siblingof(die, die));
+
+	if (!src_name)
+		return;
+
+	/*
+	 * Found the demanded one.
+	 */
+	strncpy(dwarf_info.src_name, src_name, LEN_SRCFILE);
+
+	*found = TRUE;
+}
+
+static void
 search_symbol(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 {
 	int tag;
@@ -1250,6 +1303,9 @@ search_die_tree(Dwarf *dwarfd, Dwarf_Die
 
 	else if (is_search_symbol(dwarf_info.cmd))
 		search_symbol(dwarfd, die, found);
+
+	else if (is_search_srcfile(dwarf_info.cmd))
+		search_srcfile(dwarfd, die, found);
 }
 
 int
@@ -1390,6 +1446,23 @@ get_array_length(char *name01, char *nam
 	return dwarf_info.array_length;
 }
 
+/*
+ * Get the source filename.
+ */
+int
+get_source_filename(char *decl_name, char *src_name, int cmd)
+{
+	dwarf_info.cmd = cmd;
+	dwarf_info.decl_name = decl_name;
+
+	if (!get_debug_info())
+		return FALSE;
+
+	strncpy(src_name, dwarf_info.src_name, LEN_SRCFILE);
+
+	return TRUE;
+}
+
 int
 get_symbol_info(struct DumpInfo *info)
 {
@@ -1420,174 +1493,6 @@ get_symbol_info(struct DumpInfo *info)
 	return TRUE;
 }
 
-
-int
-read_kernel_config(struct DumpInfo *info)
-{
-	int ii, ret, end, found=0;
-	unsigned long size, bufsz;
-	char *pos, *ln, *buf, *head, *tail, *val, *uncomp;
-	char line[512];
-	z_stream stream;
-	unsigned long kernel_config_data;
-
-	kernel_config_data = get_symbol_addr(info, "kernel_config_data");
-	if (kernel_config_data <= 0) {
-		ERRMSG("Can't read kernel cofiguration from kernel binary");
-		return FALSE;
-	}
-
-	/* We don't know how large IKCONFIG is, so we start with
-	 * 32k, if we can't find MAGIC_END assume we didn't read
-	 * enough, double it and try again.
-	 */
-	ii = 32;
-
-again:
-	size = ii * 1024;
-
-	if ((buf = (char *)malloc(size)) == NULL) {
-		MSG("cannot malloc IKCONFIG input buffer\n");
-		return FALSE;
-	}
-
-        if (!readmem(info, kernel_config_data, buf, size)) {
-		MSG("cannot read kernel_config_data\n");
-		goto out2;
-	}
-
-	/* Find the start */
-	if (strstr(buf, MAGIC_START))
-		head = buf + MAGIC_SIZE + 10; /* skip past MAGIC_START and gzip header */
-	else {
-		MSG("could not find MAGIC_START!\n");
-		goto out2;
-	}
-
-	tail = head;
-
-	end = strlen(MAGIC_END);
-
-	/* Find the end*/
-	while (tail < (buf + (size - 1))) {
-
-		if (strncmp(tail, MAGIC_END, end)==0) {
-			found = 1;
-			break;
-		}
-		tail++;
-	}
-
-	if (found) {
-		bufsz = tail - head;
-		size = 10 * bufsz;
-		if ((uncomp = (char *)malloc(size)) == NULL) {
-			MSG("cannot malloc IKCONFIG output buffer\n");
-			goto out2;
-		}
-	} else {
-		if (ii > 512) {
-			MSG("could not find MAGIC_END!\n");
-			goto out2;
-		} else {
-			free(buf);
-			ii *= 2;
-			goto again;
-		}
-	}
-
-
-	/* initialize zlib */
-	stream.next_in = (Bytef *)head;
-	stream.avail_in = (uInt)bufsz;
-
-	stream.next_out = (Bytef *)uncomp;
-	stream.avail_out = (uInt)size;
-
-	stream.zalloc = NULL;
-	stream.zfree = NULL;
-	stream.opaque = NULL;
-
-	ret = inflateInit2(&stream, -MAX_WBITS);
-	if (ret != Z_OK) {
-		ERRMSG("error while reading kernel config, inflateInit2 "
-				"returned %d\n", ret);
-		goto out1;
-	}
-
-	ret = inflate(&stream, Z_FINISH);
-
-	if (ret != Z_STREAM_END) {
-		inflateEnd(&stream);
-		if (ret == Z_NEED_DICT ||
-		   (ret == Z_BUF_ERROR && stream.avail_in == 0)) {
-			ERRMSG("error while reading kernel config, stream.avail_in = 0,"
-					"inflate returned %d\n", ret);
-			goto out1;
-		}
-		ERRMSG("error while reading kernel config, inflate returned"
-				"with %d\n", ret);
-		goto out1;
-	}
-	size = stream.total_out;
-
-	ret = inflateEnd(&stream);
-
-	pos = uncomp;
-
-	do {
-		ret = sscanf(pos, "%511[^\n]\n%n", line, &ii);
-		if (ret > 0) {
-			pos += ii;
-
-			ln = line;
-
-			/* skip leading whitespace */
-			while (is_blank(*ln))
-				ln++;
-
-			/* skip comments */
-			if (*ln == '#')
-				continue;
-
-			/* Find '=' */
-			if ((head = strchr(ln, '=')) != NULL) {
-				*head = '\0';
-				val = head + 1;
-
-				head--;
-
-				/* skip trailing whitespace */
-				while (is_blank(*head)) {
-					*head = '\0';
-					head--;
-				}
-
-				/* skip whitespace */
-				while (is_blank(*val))
-					val++;
-
-			} else /* Bad line, skip it */
-				continue;
-
-			if (strcmp(ln, "CONFIG_PGTABLE_4") == 0)
-				info->mem_flags |= MEMORY_4LAYER_PAGETABLE;
-		}
-	} while (ret > 0);
-
-
-	free(uncomp);
-	free(buf);
-	return TRUE;
-
-out1:
-	free(uncomp);
-out2:
-	free(buf);
-
-	return FALSE;
-}
-
 int
 get_structure_info(struct DumpInfo *info)
 {
@@ -1653,6 +1558,14 @@ get_structure_info(struct DumpInfo *info
 }
 
 int
+get_srcfile_info(struct DumpInfo *info)
+{
+	TYPEDEF_SRCFILE_INIT(pud_t, "pud_t");
+
+	return TRUE;
+}
+
+int
 is_sparsemem_extreme(struct DumpInfo *info)
 {
 	if (ARRAY_LENGTH(mem_section)
@@ -1722,6 +1635,9 @@ generate_config(struct DumpInfo *info)
 	if (!get_structure_info(info))
 		return FALSE;
 
+	if (!get_srcfile_info(info))
+		return FALSE;
+
 	if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)
 	    && (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
 		ERRMSG("Can't get the symbol of system_utsname.\n");
@@ -1807,6 +1723,11 @@ generate_config(struct DumpInfo *info)
 
 	WRITE_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
+	/*
+	 * write the source file of 1st kernel
+	 */
+	WRITE_SRCFILE("pud_t", pud_t);
+
 	return TRUE;
 }
 
@@ -1920,6 +1841,30 @@ read_config_structure(struct DumpInfo *i
 }
 
 int
+read_config_string(struct DumpInfo *info, char *str_in, char *str_out)
+{
+	char buf[BUFSIZE_FGETS];
+	unsigned int i;
+
+	if (fseek(info->file_configfile, 0, SEEK_SET) < 0) {
+		ERRMSG("Can't seek the config file(%s). %s\n",
+		    info->name_configfile, strerror(errno));
+		return FALSE;
+	}
+
+	while (fgets(buf, BUFSIZE_FGETS, info->file_configfile)) {
+		i = strlen(buf);
+		if (buf[i - 1] == '\n')
+			buf[i - 1] = '\0';
+		if (strncmp(buf, str_in, strlen(str_in)) == 0) {
+			strncpy(str_out, buf + strlen(str_in), BUFSIZE_FGETS - strlen(str_in));
+			break;
+		}
+	}
+	return TRUE;
+}
+
+int
 read_config(struct DumpInfo *info)
 {
 	if (!read_config_basic_info(info))
@@ -1974,6 +1919,8 @@ read_config(struct DumpInfo *info)
 	READ_ARRAY_LENGTH("mem_section", mem_section);
 	READ_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
+	READ_SRCFILE("pud_t", pud_t);
+
 	return TRUE;
 }
 
@@ -2455,6 +2402,9 @@ initial(struct DumpInfo *info)
 		}
 		if (!get_structure_info(info))
 			return FALSE;
+
+		if (!get_srcfile_info(info))
+			return FALSE;
 	}
 
 	if (!get_machdep_kernel_start(info))
@@ -2463,9 +2413,6 @@ initial(struct DumpInfo *info)
 	if (!check_release(info))
 		return FALSE;
 
-	if (!read_kernel_config(info))
-		return FALSE;
-
 	if (!get_machdep_info(info))
 		return FALSE;
 
diff -puN makedumpfile.org/makedumpfile.h makedumpfile/makedumpfile.h
--- makedumpfile.org/makedumpfile.h	2007-05-21 19:20:06.000000000 +0900
+++ makedumpfile/makedumpfile.h	2007-05-21 19:36:43.000000000 +0900
@@ -69,14 +69,7 @@ enum {
  * Flags
  */
 #define MEMORY_4LAYER_PAGETABLE	(1 << 0)
-
-/*
- * For kernel configuration
- */
-#define MAGIC_START  "IKCFG_ST"
-#define MAGIC_END    "IKCFG_ED"
-#define MAGIC_SIZE   (sizeof(MAGIC_START) - 1)
-
+#define MEMORY_3LAYER_PAGETABLE	(1 << 1)
 
 static inline int
 test_bit(int nr, unsigned long addr)
@@ -87,12 +80,6 @@ test_bit(int nr, unsigned long addr)
 	return ((mask & addr) != 0);
 }
 
-static inline int
-is_blank(int c)
-{
-	return c == ' ' || c == '\t';
-}
-
 #define isLRU(flags)		test_bit(PG_lru, flags)
 #define isPrivate(flags)	test_bit(PG_private, flags)
 #define isSwapCache(flags)	test_bit(PG_swapcache, flags)
@@ -288,6 +275,29 @@ do { \
 } while (0)
 
 /*
+ * for source file name
+ */
+#define SRCFILE(X)		(srcfile_table.X)
+#define	TYPEDEF_SRCFILE_INIT(decl_name, str_decl_name) \
+do { \
+	get_source_filename(str_decl_name, SRCFILE(decl_name), DWARF_INFO_GET_TYPEDEF_SRCNAME); \
+} while (0)
+
+#define WRITE_SRCFILE(str_decl_name, decl_name) \
+do { \
+	if (strlen(SRCFILE(decl_name))) { \
+		fprintf(info->file_configfile, "%s%s\n", \
+		    STR_SRCFILE(str_decl_name), SRCFILE(decl_name)); \
+	} \
+} while (0)
+
+#define READ_SRCFILE(str_decl_name, decl_name) \
+do { \
+	if (!read_config_string(info, STR_SRCFILE(str_decl_name), SRCFILE(decl_name))) \
+		return FALSE; \
+} while (0)
+
+/*
  * kernel version
  */
 #define VERSION_2_6_15		(15)
@@ -309,6 +319,7 @@ do { \
 #define STR_SIZE(X)	"SIZE("X")="
 #define STR_OFFSET(X)	"OFFSET("X")="
 #define STR_LENGTH(X)	"LENGTH("X")="
+#define STR_SRCFILE(X)	"SRCFILE("X")="
 
 /*
  * common value
@@ -412,6 +423,12 @@ do { \
 #define MASK_PUD   	((1UL << REGION_SHIFT) - 1) & (~((1UL << PUD_SHIFT) - 1))
 #define MASK_PGD_4L	((1UL << REGION_SHIFT) - 1) & (~((1UL << PGDIR_SHIFT_4L) - 1))
 
+/*
+ * Key for distinguishing PGTABLE_3L or PGTABLE_4L.
+ */
+#define STR_PUD_T_3L	"include/asm-generic/pgtable-nopud.h"
+#define STR_PUD_T_4L	"include/asm/page.h"
+
 #endif          /* ia64 */
 
 /*
@@ -679,10 +696,19 @@ struct array_table {
 	} zone;
 };
 
+#define LEN_SRCFILE				(50)
+struct srcfile_table {
+	/*
+	 * typedef
+	 */
+	char	pud_t[LEN_SRCFILE];
+};
+
 extern struct symbol_table	symbol_table;
 extern struct size_table	size_table;
 extern struct offset_table	offset_table;
 extern struct array_table	array_table;
+extern struct srcfile_table	srcfile_table;
 
 /*
  * Debugging information
@@ -693,6 +719,7 @@ extern struct array_table	array_table;
 #define DWARF_INFO_GET_MEMBER_ARRAY_LENGTH	(4)
 #define DWARF_INFO_GET_SYMBOL_ARRAY_LENGTH	(5)
 #define DWARF_INFO_CHECK_SYMBOL_ARRAY_TYPE	(6)
+#define DWARF_INFO_GET_TYPEDEF_SRCNAME		(7)
 
 struct dwarf_info {
 	unsigned int	cmd;		/* IN */
@@ -701,14 +728,17 @@ struct dwarf_info {
 	char	*struct_name;		/* IN */
 	char	*symbol_name;		/* IN */
 	char	*member_name;		/* IN */
+	char	*decl_name;		/* IN */
 	long	struct_size;		/* OUT */
 	long	member_offset;		/* OUT */
 	long	array_length;		/* OUT */
+	char	src_name[LEN_SRCFILE];	/* OUT */
 };
 
 extern struct dwarf_info	dwarf_info;
 
 int readmem();
+off_t paddr_to_offset();
 unsigned long long vaddr_to_paddr();
 unsigned long long paddr_to_vaddr();
 
_

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [makedumpfile] Implement memory regions on IA64
  2007-05-21  9:32           ` Ken'ichi Ohmichi
@ 2007-05-21  9:54             ` Bernhard Walle
  0 siblings, 0 replies; 10+ messages in thread
From: Bernhard Walle @ 2007-05-21  9:54 UTC (permalink / raw)
  To: Ken'ichi Ohmichi; +Cc: Jay Lan, Kexec Mailing List

* Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> [2007-05-21 11:32]:
> 2007/05/16 20:20:00 +0900, "Ken'ichi Ohmichi" <oomichi@mxs.nes.nec.co.jp> wrote:
> >I propose that makedumpfile distinguishes the page table (3L or 4L)
> >by checking the defined file name of pud_t.
> >I'm trying for the above implementation.
> >I will send you the patch when it is complete.
> 
> The attached patch is for the above implementation.
> It works fine with linux-2.6.18.
> Could you test it with your environment ?

works, thanks.


Bernhard

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-05-21  9:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-26 19:37 [PATCH] [makedumpfile] Implement memory regions on IA64 Bernhard Walle
2007-05-11  6:59 ` Ken'ichi Ohmichi
2007-05-14 18:15   ` Bernhard Walle
2007-05-14 21:49     ` Bernhard Walle
2007-05-15 22:08       ` Bernhard Walle
2007-05-16 11:20         ` Ken'ichi Ohmichi
2007-05-16 11:26           ` Bernhard Walle
2007-05-21  9:32           ` Ken'ichi Ohmichi
2007-05-21  9:54             ` Bernhard Walle
  -- strict thread matches above, loose matches on Subject: below --
2007-04-27 10:31 tachibana

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox