Index: xen-ia64-unstable-14854/patches/linux-2.6.18/ia64-kexec.patch
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ xen-ia64-unstable-14854/patches/linux-2.6.18/ia64-kexec.patch	2007-04-17 11:26:43.000000000 +0900
@@ -0,0 +1,345 @@
+commit a79561134f38de12dce14ed72138f38e55ef53fc
+tree abe109dbe85e5b0085ba9b9a7eed7cc623d67eec
+parent 620034c84d1d939717bdfbe02c51a3fee43541c3
+author Zou Nan hai <nanhai.zou@intel.com> 1165513895 -0800
+committer Tony Luck <tony.luck@intel.com> 1165513895 -0800
+
+[IA64] IA64 Kexec/kdump
+
+Changes and updates.
+
+1. Remove fake rendz path and related code according to discuss with Khalid Aziz.
+2. fc.i offset fix in relocate_kernel.S.
+3. iospic shutdown code eoi and mask race fix from Fujitsu.
+4. Warm boot hook in machine_kexec to SN SAL code from Jack Steiner.
+5. Send slave to SAL slave loop patch from Jay Lan.
+6. Kdump on non-recoverable MCA event patch from Jay Lan
+7. Use CTL_UNNUMBERED in kdump_on_init sysctl.
+
+Signed-off-by: Zou Nan hai <nanhai.zou@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+
+ arch/ia64/Kconfig                  |   23 ++
+ arch/ia64/kernel/Makefile          |    1
+ arch/ia64/kernel/crash.c           |  245 ++++++++++++++++++++++++++
+ arch/ia64/kernel/efi.c             |   65 ++++++-
+ arch/ia64/kernel/entry.S           |    2
+ arch/ia64/kernel/iosapic.c         |   21 ++
+ arch/ia64/kernel/machine_kexec.c   |  133 ++++++++++++++
+ arch/ia64/kernel/mca.c             |    5
+ arch/ia64/kernel/relocate_kernel.S |  334 ++++++++++++++++++++++++++++++++++++
+ arch/ia64/kernel/setup.c           |   38 ++++
+ arch/ia64/kernel/smp.c             |   28 ++-
+ arch/ia64/sn/kernel/setup.c        |    8
+ include/asm-ia64/kexec.h           |   47 +++++
+ include/asm-ia64/machvec.h         |    5
+ include/asm-ia64/machvec_sn2.h     |    2
+ include/asm-ia64/meminit.h         |    3
+ include/asm-ia64/sn/sn_sal.h       |    9
+ include/linux/kexec.h              |    5
+ kernel/kexec.c                     |    1
+ 19 files changed, 969 insertions(+), 6 deletions(-)
+
+a79561134f38de12dce14ed72138f38e55ef53fc
+diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
+index bb8770a..9b96e7d 100644
+--- a/arch/ia64/kernel/efi.c
++++ b/arch/ia64/kernel/efi.c
+@@ -26,6 +26,7 @@
+ #include <linux/types.h>
+ #include <linux/time.h>
+ #include <linux/efi.h>
++#include <linux/kexec.h>
+ 
+ #include <asm/io.h>
+ #include <asm/kregs.h>
+@@ -41,7 +42,7 @@ extern efi_status_t efi_call_phys (void *, ...);
+ struct efi efi;
+ EXPORT_SYMBOL(efi);
+ static efi_runtime_services_t *runtime;
+-static unsigned long mem_limit = ~0UL, max_addr = ~0UL;
++static unsigned long mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
+ 
+ #define efi_call_virt(f, args...)	(*(f))(args)
+ 
+@@ -421,6 +422,8 @@ efi_init (void)
+ 			mem_limit = memparse(cp + 4, &cp);
+ 		} else if (memcmp(cp, "max_addr=", 9) == 0) {
+ 			max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
++		} else if (memcmp(cp, "min_addr=", 9) == 0) {
++			min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
+ 		} else {
+ 			while (*cp != ' ' && *cp)
+ 				++cp;
+@@ -428,6 +431,8 @@ efi_init (void)
+ 				++cp;
+ 		}
+ 	}
++	if (min_addr != 0UL)
++		printk(KERN_INFO "Ignoring memory below %luMB\n", min_addr >> 20);
+ 	if (max_addr != ~0UL)
+ 		printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20);
+ 
+@@ -894,7 +899,8 @@ find_memmap_space (void)
+ 		as = max(contig_low, md->phys_addr);
+ 		ae = min(contig_high, efi_md_end(md));
+ 
+-		/* keep within max_addr= command line arg */
++		/* keep within max_addr= and min_addr= command line arg */
++		as = max(as, min_addr);
+ 		ae = min(ae, max_addr);
+ 		if (ae <= as)
+ 			continue;
+@@ -1004,7 +1010,8 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
+ 		} else
+ 			ae = efi_md_end(md);
+ 
+-		/* keep within max_addr= command line arg */
++		/* keep within max_addr= and min_addr= command line arg */
++		as = max(as, min_addr);
+ 		ae = min(ae, max_addr);
+ 		if (ae <= as)
+ 			continue;
+@@ -1116,6 +1123,58 @@ efi_initialize_iomem_resources(struct resource *code_resource,
+ 			 */
+ 			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);
++#endif
+ 		}
+ 	}
+ }
++
++#ifdef CONFIG_KEXEC
++/* find a block of memory aligned to 64M exclude reserved regions
++   rsvd_regions are sorted
++ */
++unsigned long
++kdump_find_rsvd_region (unsigned long size,
++		struct rsvd_region *r, int n)
++{
++  int i;
++  u64 start, end;
++  u64 alignment = 1UL << _PAGE_SIZE_64M;
++  void *efi_map_start, *efi_map_end, *p;
++  efi_memory_desc_t *md;
++  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;
++
++  for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
++	  md = p;
++	  if (!efi_wb(md))
++		  continue;
++	  start = ALIGN(md->phys_addr, alignment);
++	  end = efi_md_end(md);
++	  for (i = 0; i < n; i++) {
++		if (__pa(r[i].start) >= start && __pa(r[i].end) < end) {
++			if (__pa(r[i].start) > start + size)
++				return start;
++			start = ALIGN(__pa(r[i].end), alignment);
++			if (i < n-1 && __pa(r[i+1].start) < start + size)
++				continue;
++			else
++				break;
++		}
++	  }
++	  if (end > start + size)
++		return start;
++  }
++
++  printk(KERN_WARNING "Cannot reserve 0x%lx byte of memory for crashdump\n",
++	size);
++  return ~0UL;
++}
++#endif
+diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
+index 6bedd97..87c1c4f 100644
+--- a/arch/ia64/kernel/mca.c
++++ b/arch/ia64/kernel/mca.c
+@@ -82,6 +82,7 @@
+ #include <asm/system.h>
+ #include <asm/sal.h>
+ #include <asm/mca.h>
++#include <asm/kexec.h>
+ 
+ #include <asm/irq.h>
+ #include <asm/hw_irq.h>
+@@ -1238,6 +1238,11 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
+ 		ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
+ 		sos->os_status = IA64_MCA_CORRECTED;
+-	}
++ 	} else {
++#ifdef CONFIG_CRASH_DUMP
++		atomic_set(&kdump_in_progress, 1);
++		monarch_cpu = -1;
++#endif
++ 	}
+ 	if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
+ 			== NOTIFY_STOP)
+ 		ia64_mca_spin(__FUNCTION__);
+diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
+index 6ab95ce..b1b9aa4 100644
+--- a/arch/ia64/kernel/smp.c
++++ b/arch/ia64/kernel/smp.c
+@@ -30,6 +30,7 @@
+ #include <linux/delay.h>
+ #include <linux/efi.h>
+ #include <linux/bitops.h>
++#include <linux/kexec.h>
+ 
+ #include <asm/atomic.h>
+ #include <asm/current.h>
+@@ -66,6 +67,7 @@ static volatile struct call_data_struct *call_data;
+ 
+ #define IPI_CALL_FUNC		0
+ #define IPI_CPU_STOP		1
++#define IPI_KDUMP_CPU_STOP	3
+ 
+ /* This needs to be cacheline aligned because it is written to by *other* CPUs.  */
+ static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
+@@ -155,7 +157,11 @@ handle_IPI (int irq, void *dev_id)
+ 			      case IPI_CPU_STOP:
+ 				stop_this_cpu();
+ 				break;
+-
++#ifdef CONFIG_CRASH_DUMP
++			      case IPI_KDUMP_CPU_STOP:
++				unw_init_running(kdump_cpu_freeze, NULL);
++				break;
++#endif
+ 			      default:
+ 				printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
+ 				break;
+@@ -213,6 +219,26 @@ send_IPI_self (int op)
+ 	send_IPI_single(smp_processor_id(), op);
+ }
+ 
++#ifdef CONFIG_CRASH_DUMP
++void
++kdump_smp_send_stop()
++{
++ 	send_IPI_allbutself(IPI_KDUMP_CPU_STOP);
++}
++
++void
++kdump_smp_send_init()
++{
++	unsigned int cpu, self_cpu;
++	self_cpu = smp_processor_id();
++	for_each_online_cpu(cpu) {
++		if (cpu != self_cpu) {
++			if(kdump_status[cpu] == 0)
++				platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
++		}
++	}
++}
++#endif
+ /*
+  * Called with preeemption disabled.
+  */
+diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
+index 1d009f9..a934ad0 100644
+--- a/arch/ia64/sn/kernel/setup.c
++++ b/arch/ia64/sn/kernel/setup.c
+@@ -769,5 +769,13 @@ int sn_prom_feature_available(int id)
+ 		return 0;
+ 	return test_bit(id, sn_prom_features);
+ }
++
++void
++sn_kernel_launch_event(void)
++{
++	/* ignore status until we understand possible failure, if any*/
++	if (ia64_sn_kernel_launch_event())
++		printk(KERN_ERR "KEXEC is not supported in this PROM, Please update the PROM.\n");
++}
+ EXPORT_SYMBOL(sn_prom_feature_available);
+ 
+diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
+index 83325f6..eaa2fce 100644
+--- a/include/asm-ia64/machvec_sn2.h
++++ b/include/asm-ia64/machvec_sn2.h
+@@ -67,6 +67,7 @@ extern ia64_mv_dma_sync_sg_for_device	sn_dma_sync_sg_for_device;
+ extern ia64_mv_dma_supported		sn_dma_supported;
+ extern ia64_mv_migrate_t		sn_migrate;
+ extern ia64_mv_msi_init_t		sn_msi_init;
++extern ia64_mv_kernel_launch_event_t	sn_kernel_launch_event;
+ 
+ /*
+  * This stuff has dual use!
+@@ -121,6 +122,7 @@ extern ia64_mv_pci_fixup_bus_t		sn_pci_fixup_bus;
+ #else
+ #define platform_msi_init			((ia64_mv_msi_init_t*)NULL)
+ #endif
++#define platform_kernel_launch_event    sn_kernel_launch_event
+ 
+ #include <asm/sn/io.h>
+  
+diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
+index be5d83a..2c4004e 100644
+--- a/include/asm-ia64/sn/sn_sal.h
++++ b/include/asm-ia64/sn/sn_sal.h
+@@ -88,6 +88,8 @@
+ #define  SN_SAL_GET_PROM_FEATURE_SET		   0x02000065
+ #define  SN_SAL_SET_OS_FEATURE_SET		   0x02000066
+ 
++#define  SN_SAL_KERNEL_LAUNCH_EVENT		   0x02000069
++
+ /*
+  * Service-specific constants
+  */
+@@ -1155,4 +1157,11 @@ ia64_sn_set_cpu_number(int cpu)
+ 	SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0);
+ 	return rv.status;
+ }
++static inline int
++ia64_sn_kernel_launch_event(void)
++{
++ 	struct ia64_sal_retval rv;
++	SAL_CALL_NOLOCK(rv, SN_SAL_KERNEL_LAUNCH_EVENT, 0, 0, 0, 0, 0, 0, 0);
++	return rv.status;
++}
+ 
+ #endif /* _ASM_IA64_SN_SN_SAL_H */
+diff --git a/include/linux/kexec.h b/include/linux/kexec.h
+index a4ede62..e14cd38 100644
+--- a/include/linux/kexec.h
++++ b/include/linux/kexec.h
+@@ -108,6 +108,10 @@ int kexec_should_crash(struct task_struct *);
+ extern struct kimage *kexec_image;
+ extern struct kimage *kexec_crash_image;
+ 
++#ifndef kexec_flush_icache_page
++#define kexec_flush_icache_page(page)
++#endif
++
+ #define KEXEC_ON_CRASH  0x00000001
+ #define KEXEC_ARCH_MASK 0xffff0000
+ 
+@@ -133,6 +137,7 @@ extern struct resource crashk_res;
+ typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+ extern note_buf_t *crash_notes;
+ 
++
+ #else /* !CONFIG_KEXEC */
+ struct pt_regs;
+ struct task_struct;
+diff --git a/kernel/kexec.c b/kernel/kexec.c
+index fcdd5d2..05aada2 100644
+--- a/kernel/kexec.c
++++ b/kernel/kexec.c
+@@ -851,6 +851,7 @@ static int kimage_load_crash_segment(struct kimage *image,
+ 			memset(ptr + uchunk, 0, mchunk - uchunk);
+ 		}
+ 		result = copy_from_user(ptr, buf, uchunk);
++		kexec_flush_icache_page(page);
+ 		kunmap(page);
+ 		if (result) {
+ 			result = (result < 0) ? result : -EIO;
Index: xen-ia64-unstable-14854/patches/linux-2.6.18/series
===================================================================
--- xen-ia64-unstable-14854.orig/patches/linux-2.6.18/series	2007-04-17 11:25:54.000000000 +0900
+++ xen-ia64-unstable-14854/patches/linux-2.6.18/series	2007-04-17 11:47:55.000000000 +0900
@@ -22,3 +22,4 @@ softlockup-no-idle-hz.patch
 allow-i386-crash-kernels-to-handle-x86_64-dumps.patch
 allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch
 sysctl-unnumbered.patch
+ia64-kexec.patch
