Index: xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/machine_kexec.c	2008-01-22 16:45:09.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c	2008-01-22 16:46:37.000000000 +0900
@@ -25,6 +25,7 @@
 #include <linux/notifier.h>
 #include <asm/dom_fw_dom0.h>
 
+#if 0
 typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
 					unsigned long indirection_page,
 					unsigned long start_address,
@@ -40,6 +41,15 @@ typedef asmlinkage NORET_TYPE void (*rel
 					unsigned long stack,
 					unsigned long vhpt)
 					ATTRIB_NORET;
+#endif
+
+typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
+					unsigned long indirection_page,
+					unsigned long start_address,
+					struct ia64_boot_param *boot_param,
+					unsigned long cpu_data_pa,
+					unsigned long *tr_list)
+					ATTRIB_NORET;
 
 #define kexec_flush_icache_page(page)					\
 do {									\
@@ -56,6 +66,9 @@ void machine_kexec_unload(int type, int 
 {
 }
 
+#define PURGE_DTLB (1LL<<62)
+#define PURGE_ITLB (1LL<<63)
+
 static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
 {
 	struct vcpu *v = current;
@@ -65,8 +78,7 @@ static void ia64_machine_kexec(struct un
 				  __va(image->reboot_code_buffer);
 	unsigned long cpu_data_pa = (unsigned long)
 				  __pa(cpu_data(smp_processor_id()));
-	unsigned long vhpt;
-	unsigned long stack = 0UL;
+	unsigned long tr[(7*2)+1];
 	int ii;
 
 	/* Interrupts aren't acceptable while we reboot */
@@ -91,33 +103,50 @@ static void ia64_machine_kexec(struct un
 	while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR)
 		ia64_eoi();
 	platform_kernel_launch_event();
-	vhpt = vcpu_vhpt_maddr(current);
-	if (vhpt)
-		vhpt = __va_ul(vhpt);
-	// Clear stack if it doesn't overlap with kernel
-	if (((unsigned long)current & ~(KERNEL_TR_PAGE_SIZE-1)) != KERNEL_START)
-		stack = (unsigned long) current;
-	printk("vhpt=0x%016lx\n", vhpt);
-	printk("PERCPU_ADDR=0x%016lx\n", PERCPU_ADDR);
-	printk("pal_vaddr=0x%016lx\n", (unsigned long)pal_vaddr);
-	printk("GRANULEROUNDDOWN(pal_vaddr)=0x%016lx\n",
-	       GRANULEROUNDDOWN((unsigned long)pal_vaddr));
-	printk("current=0x%016lx\n", (unsigned long)current);
-	printk("stack=0x%016lx\n", stack);
-	printk("shared_info=0x%016lx\n",
-	       (unsigned long)v->domain->arch.shared_info_va);
-	printk("priv_regs=0x%016lx\n", (unsigned long)XMAPPEDREGS_OFS);
+
+	ii = 0;
+	/* TR for kernel text and data */
+	tr[ii++] = PURGE_ITLB|PURGE_DTLB|(KERNEL_TR_PAGE_SHIFT<<2);
+	tr[ii++] = KERNEL_START;
+	/* TR for percpu data */
+	tr[ii++] = PURGE_DTLB|(PERCPU_PAGE_SHIFT<<2);
+	tr[ii++] = PERCPU_ADDR;
+	/* TR for shared_info
+	 * v->domain->arch.shared_info_va is rubbis if
+	 * v->domain->shared_info is zero. If this is
+	 * a problem use a saved value.
+	 */
+	BUG_ON(!v->domain->shared_info);
+	tr[ii++] = PURGE_DTLB|(XSI_SHIFT<<2);
+	tr[ii++] = v->domain->arch.shared_info_va;
+	/* TR for mapped_regs */
+	tr[ii++] = PURGE_DTLB|(XMAPPEDREGS_SHIFT<<2);
+	tr[ii++] = v->domain->arch.shared_info_va + XMAPPEDREGS_OFS;
+	/* TR for pal code */
+	tr[ii++] = PURGE_ITLB|(IA64_GRANULE_SHIFT<<2);
+	/* XXX: GRANULEROUNDDOWN is probably not neccessary
+	 *      as ptr should ignore trailing bits
+	 */
+	tr[ii++] = GRANULEROUNDDOWN((unsigned long) pal_vaddr);
+	/* TR for stack
+	 * Ony clear stack if it doesn't overlap with kernel text and data
+	 * - which it seems to often
+	 */
+	if (((unsigned long)current & ~(KERNEL_TR_PAGE_SIZE-1)) !=
+	    KERNEL_START) {
+		tr[ii++] = PURGE_DTLB|(IA64_GRANULE_SHIFT<<2);
+		tr[ii++] = (unsigned long)current;
+	}
+#if VHPT_ENABLED
+	// TR for VHPT
+	tr[ii++] = PURGE_DTLB|(IA64_GRANULE_SHIFT<<2);
+	tr[ii++] = __va_ul(vcpu_vhpt_maddr(current));
+#endif
+	tr[ii] = 0UL;
+
 	rnk = (relocate_new_kernel_t)&code_addr;
-	// XXX: Assumes IA64_GRANULE_SHIFT (and others?) are the
-	// same for xen and xen-linux
 	(*rnk)(image->indirection_page, image->start_address, ia64_boot_param,
-	       GRANULEROUNDDOWN((unsigned long) pal_vaddr), cpu_data_pa,
-	       KERNEL_START, PERCPU_ADDR,
-	       (unsigned long)v->domain->arch.shared_info_va,
-	       (unsigned long)XSI_SHIFT,
-	       (unsigned long)v->domain->arch.shared_info_va +
-	       	(unsigned long)XMAPPEDREGS_OFS,
-	       (unsigned long)XMAPPEDREGS_SHIFT, stack, vhpt);
+	       cpu_data_pa, tr);
 	BUG();
 }
 
