Index: xen-ia64-unstable-wip.hg/patches/linux-2.6.18/ia64-kexec-iomem_machine.patch
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ xen-ia64-unstable-wip.hg/patches/linux-2.6.18/ia64-kexec-iomem_machine.patch	2007-05-09 17:35:46.000000000 +0900
@@ -0,0 +1,264 @@
+From: Simon Horman <horms@verge.net.au>
+Date: Tue, 08 May 2007 19:11:53 +0900
+Subject: Add /proc/iomem_machine
+X-Upstream-Status: not sent as its only useful on Xen
+
+Add /proc/iomem_machine for ia64 where pysical and machine efi maps differ.
+Without this kexec gets a very jaded view of the world, and /proc/vmcore
+after a kdump will only have a partial memory dump. Requires a companion
+patch to kexec-tools.
+
+There is also a separate portion of this patch that applies
+directly to linux-2.6-xen-sparse/fs/Kconfig
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+
+--- 
+ arch/ia64/kernel/efi.c |  108 ++++++++++++++++++++++++++++++++++++++++--------
+ include/linux/ioport.h |    3 +
+ kernel/resource.c      |   36 ++++++++++++++++
+ 3 files changed, 129 insertions(+), 18 deletions(-)
+
+Index: a/kernel/resource.c
+===================================================================
+--- a/kernel/resource.c	2006-09-20 12:42:06.000000000 +0900
++++ a/kernel/resource.c	2007-05-08 19:01:31.000000000 +0900
+@@ -36,6 +36,16 @@ struct resource iomem_resource = {
+ };
+ EXPORT_SYMBOL(iomem_resource);
+ 
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++struct resource iomem_machine_resource = {
++	.name	= "Machine PCI mem",
++	.start	= 0,
++	.end	= -1,
++	.flags	= IORESOURCE_MEM,
++};
++EXPORT_SYMBOL(iomem_machine_resource);
++#endif
++
+ static DEFINE_RWLOCK(resource_lock);
+ 
+ #ifdef CONFIG_PROC_FS
+@@ -115,6 +125,18 @@ static int iomem_open(struct inode *inod
+ 	return res;
+ }
+ 
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++static int iomem_machine_open(struct inode *inode, struct file *file)
++{
++	int res = seq_open(file, &resource_op);
++	if (!res) {
++		struct seq_file *m = file->private_data;
++		m->private = &iomem_machine_resource;
++	}
++	return res;
++}
++#endif
++
+ static struct file_operations proc_ioports_operations = {
+ 	.open		= ioports_open,
+ 	.read		= seq_read,
+@@ -129,6 +151,15 @@ static struct file_operations proc_iomem
+ 	.release	= seq_release,
+ };
+ 
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++static struct file_operations proc_iomem_machine_operations = {
++	.open		= iomem_machine_open,
++	.read		= seq_read,
++	.llseek		= seq_lseek,
++	.release	= seq_release,
++};
++#endif
++
+ static int __init ioresources_init(void)
+ {
+ 	struct proc_dir_entry *entry;
+@@ -139,6 +170,11 @@ static int __init ioresources_init(void)
+ 	entry = create_proc_entry("iomem", 0, NULL);
+ 	if (entry)
+ 		entry->proc_fops = &proc_iomem_operations;
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++	entry = create_proc_entry("iomem_machine", 0, NULL);
++	if (entry)
++		entry->proc_fops = &proc_iomem_machine_operations;
++#endif
+ 	return 0;
+ }
+ __initcall(ioresources_init);
+Index: a/arch/ia64/kernel/efi.c
+===================================================================
+--- a/arch/ia64/kernel/efi.c	2007-05-08 18:18:58.000000000 +0900
++++ a/arch/ia64/kernel/efi.c	2007-05-08 19:02:56.000000000 +0900
+@@ -35,6 +35,11 @@
+ #include <asm/processor.h>
+ #include <asm/mca.h>
+ 
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++#include <xen/interface/memory.h>
++#include <asm/hypercall.h>
++#endif
++
+ #define EFI_DEBUG	0
+ 
+ extern efi_status_t efi_call_phys (void *, ...);
+@@ -947,7 +952,7 @@ efi_memmap_init(unsigned long *s, unsign
+ 		md = p;
+ 		if (!efi_wb(md)) {
+ 			if (efi_uc(md) && (md->type == EFI_CONVENTIONAL_MEMORY ||
+-				    	   md->type == EFI_BOOT_SERVICES_DATA)) {
++					   md->type == EFI_BOOT_SERVICES_DATA)) {
+ 				k->attribute = EFI_MEMORY_UC;
+ 				k->start = md->phys_addr;
+ 				k->num_pages = md->num_pages;
+@@ -1040,21 +1045,22 @@ efi_memmap_init(unsigned long *s, unsign
+ 	*e = (u64)++k;
+ }
+ 
+-void
+-efi_initialize_iomem_resources(struct resource *code_resource,
+-			       struct resource *data_resource)
++#define EFI_INITIALISE_PHYS 0x1
++#define EFI_INITIALISE_MACH 0x2
++#define EFI_INITIALISE_ALL  (EFI_INITIALISE_PHYS|EFI_INITIALISE_MACH)
++
++static void
++efi_initialize_resources(void *efi_map_start, void *efi_map_end,
++			 u64 efi_desc_size, struct resource *root_resource,
++			 struct resource *code_resource,
++			 struct resource *data_resource, unsigned flag)
+ {
+ 	struct resource *res;
+-	void *efi_map_start, *efi_map_end, *p;
++	void *p;
+ 	efi_memory_desc_t *md;
+-	u64 efi_desc_size;
+ 	char *name;
+ 	unsigned long flags;
+ 
+-	efi_map_start = __va(ia64_boot_param->efi_memmap);
+-	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+-	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+-
+ 	res = NULL;
+ 
+ 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+@@ -1113,7 +1119,7 @@ efi_initialize_iomem_resources(struct re
+ 		res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
+ 		res->flags = flags;
+ 
+-		if (insert_resource(&iomem_resource, res) < 0)
++		if (insert_resource(root_resource, res) < 0)
+ 			kfree(res);
+ 		else {
+ 			/*
+@@ -1121,21 +1127,87 @@ efi_initialize_iomem_resources(struct re
+ 			 * kernel data so we try it repeatedly and
+ 			 * let the resource manager test it.
+ 			 */
+-			insert_resource(res, code_resource);
+-			insert_resource(res, data_resource);
++			if (flag & EFI_INITIALISE_PHYS) {
++				insert_resource(res, code_resource);
++				insert_resource(res, data_resource);
++			}
+ #ifdef CONFIG_KEXEC
+-                        insert_resource(res, &efi_memmap_res);
+-                        insert_resource(res, &boot_param_res);
+-			if (crashk_res.end > crashk_res.start)
+-				insert_resource(res, &crashk_res);
++			if (flag & EFI_INITIALISE_MACH) {
++				insert_resource(res, &efi_memmap_res);
++				insert_resource(res, &boot_param_res);
++				if (crashk_res.end > crashk_res.start)
++					insert_resource(res, &crashk_res);
+ #ifdef CONFIG_XEN
+-			xen_machine_kexec_register_resources(res);
++				xen_machine_kexec_register_resources(res);
+ #endif
++			}
+ #endif
+ 		}
+ 	}
+ }
+ 
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++static int
++efi_initialize_iomem_machine_resources(void)
++{
++	unsigned long size;
++	xen_memory_map_t memmap;
++	xen_ia64_memmap_info_t *memmap_info = NULL;
++	void *efi_map_start, *efi_map_end;
++	u64 efi_desc_size;
++	int ret;
++
++	/* It would be nice if it wasn't neccessary to loop like this */
++	for (size = 1024; 1; size += 1024) {
++		memmap_info = kmalloc(size, GFP_KERNEL);
++		if (memmap_info == NULL)
++			return -ENOMEM;
++
++		memmap.nr_entries = size;
++		set_xen_guest_handle(memmap.buffer, memmap_info);
++		ret = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap);
++		if (!ret)
++			break;
++
++		kfree(memmap_info);
++	}
++
++	efi_map_start = &memmap_info->memdesc;
++	efi_map_end = efi_map_start + memmap_info->efi_memmap_size;
++	efi_desc_size = memmap_info->efi_memdesc_size;
++	efi_initialize_resources(efi_map_start, efi_map_end, efi_desc_size,
++				 &iomem_machine_resource, NULL, NULL,
++				 EFI_INITIALISE_MACH);
++
++	kfree(memmap_info);
++}
++#endif
++
++void
++efi_initialize_iomem_resources(struct resource *code_resource,
++			       struct resource *data_resource)
++{
++	void *efi_map_start, *efi_map_end;
++	u64 efi_desc_size;
++
++	efi_map_start = __va(ia64_boot_param->efi_memmap);
++	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
++	efi_desc_size = ia64_boot_param->efi_memdesc_size;
++
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++	efi_initialize_resources(efi_map_start, efi_map_end, efi_desc_size,
++				 &iomem_resource, code_resource,
++				 data_resource, EFI_INITIALISE_PHYS);
++	efi_initialize_iomem_machine_resources();
++#else
++	efi_initialize_resources(efi_map_start, efi_map_end, efi_desc_size,
++				 &iomem_resource, code_resource,
++				 data_resource, EFI_INITIALISE_ALL);
++#endif
++}
++
++
++
+ #ifdef CONFIG_KEXEC
+ /* find a block of memory aligned to 64M exclude reserved regions
+    rsvd_regions are sorted
+Index: a/include/linux/ioport.h
+===================================================================
+--- a/include/linux/ioport.h	2006-09-20 12:42:06.000000000 +0900
++++ a/include/linux/ioport.h	2007-05-08 18:47:39.000000000 +0900
+@@ -93,6 +93,9 @@ struct resource_list {
+ /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
+ extern struct resource ioport_resource;
+ extern struct resource iomem_resource;
++#ifdef CONFIG_XEN
++extern struct resource iomem_machine_resource;
++#endif
+ 
+ extern int request_resource(struct resource *root, struct resource *new);
+ extern struct resource * ____request_resource(struct resource *root, struct resource *new);
Index: xen-ia64-unstable-wip.hg/patches/linux-2.6.18/series
===================================================================
--- xen-ia64-unstable-wip.hg.orig/patches/linux-2.6.18/series	2007-05-09 17:19:21.000000000 +0900
+++ xen-ia64-unstable-wip.hg/patches/linux-2.6.18/series	2007-05-09 17:20:57.000000000 +0900
@@ -25,3 +25,4 @@ sysctl-unnumbered.patch
 ia64-kexec.patch
 ia64-kexec-CONFIG_KEXEC-cleanup.patch
 ia64-kexec-xen.patch
+ia64-kexec-iomem_machine.patch
