Subject: [IA64] Xenification of IA64 Kexec/kdump
From: Simon Horman <horms@verge.net.au>

Signed-off-by: Zou Nan hai <nanhai.zou@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

---
Date: Thu, 20 Sep 2007 14:49:43 +0900
As requested this has been split out from the backport of ia64 kexec/kdump
from upstream Linux.

Date: Thu, 20 Sep 2007 14:49:43 +0900
Make reserve_memory changes transparent virtualisation friendly

Date: Tue, 25 Sep 2007 11:30:45 +0900
Guard reserve_memory changes with is_initial_xendomain() instead
of is_running_on_xen() as this port of kexec to xen is not
supposed to do anything on non-privelaged domains.

 arch/ia64/kernel/crash.c           |   11 +++++------
 arch/ia64/kernel/relocate_kernel.S |   32 ++++++++++++++++++++++++++++++++
 arch/ia64/kernel/setup.c           |   12 ++++++++++++
 arch/ia64/xen/xcom_hcall.c         |   31 +++++++++++++++++++++++++++++++
 include/asm-ia64/hypercall.h       |    7 +++++++
 include/asm-ia64/machvec_sn2.h     |    4 ++--
 include/asm-ia64/sn/sn_sal.h       |   14 +++++++-------
 include/asm-ia64/xen/xcom_hcall.h  |    2 ++
 8 files changed, 98 insertions(+), 15 deletions(-)

Index: linux-2.6.18-xen.hg/arch/ia64/kernel/crash.c
===================================================================
--- linux-2.6.18-xen.hg.orig/arch/ia64/kernel/crash.c	2007-09-20 14:19:22.000000000 +0900
+++ linux-2.6.18-xen.hg/arch/ia64/kernel/crash.c	2007-09-20 14:19:59.000000000 +0900
@@ -160,7 +160,6 @@ kdump_cpu_freeze(struct unw_frame_info *
 static int
 kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
 {
-	struct ia64_mca_notify_die *nd;
 	struct die_args *args = data;
 
 	if (!kdump_on_init)
@@ -172,11 +171,11 @@ kdump_init_notifier(struct notifier_bloc
 	    val != DIE_MCA_MONARCH_LEAVE)
 		return NOTIFY_DONE;
 
-	nd = (struct ia64_mca_notify_die *)args->err;
-	/* Reason code 1 means machine check rendezous*/
-	if ((val == DIE_INIT_MONARCH_ENTER || DIE_INIT_SLAVE_ENTER) &&
-		 nd->sos->rv_rc == 1)
-		return NOTIFY_DONE;
+	/* There really ought to be a check here to see if this
+	 * is a machine check rendevous. The kexec code that
+	 * was merged around 2.6.20-rc1 includes such a check.
+	 * But the check relies on infastructure that is not
+	 * available in 2.6.16. */
 
 	switch (val) {
 		case DIE_INIT_MONARCH_ENTER:
Index: linux-2.6.18-xen.hg/arch/ia64/kernel/relocate_kernel.S
===================================================================
--- linux-2.6.18-xen.hg.orig/arch/ia64/kernel/relocate_kernel.S	2007-09-20 14:19:23.000000000 +0900
+++ linux-2.6.18-xen.hg/arch/ia64/kernel/relocate_kernel.S	2007-09-20 14:19:59.000000000 +0900
@@ -20,7 +20,11 @@
         */
 GLOBAL_ENTRY(relocate_new_kernel)
 	.prologue
+#ifdef CONFIG_XEN
+	alloc r31=ar.pfs,7,0,0,0
+#else
 	alloc r31=ar.pfs,4,0,0,0
+#endif
         .body
 .reloc_entry:
 {
@@ -33,7 +37,11 @@ GLOBAL_ENTRY(relocate_new_kernel)
         srlz.i
 }
 	;;
+#ifdef CONFIG_XEN
+	dep r2=0,r2,60,4		//to physical address
+#else
 	dep r2=0,r2,61,3		//to physical address
+#endif
 	;;
 	//first switch to physical mode
 	add r3=1f-.reloc_entry, r2
@@ -57,11 +65,19 @@ GLOBAL_ENTRY(relocate_new_kernel)
 1:
 	//physical mode code begin
 	mov b6=in1
+#ifdef CONFIG_XEN
+	dep r28=0,in2,60,4	//to physical address
+#else
 	dep r28=0,in2,61,3	//to physical address
+#endif
 
 	// purge all TC entries
 #define O(member)       IA64_CPUINFO_##member##_OFFSET
+#ifdef CONFIG_XEN
+	mov r2=in4			// load phys addr of cpu_info into r2
+#else
         GET_THIS_PADDR(r2, cpu_info)    // load phys addr of cpu_info into r2
+#endif
         ;;
         addl r17=O(PTCE_STRIDE),r2
         addl r2=O(PTCE_BASE),r2
@@ -95,7 +111,11 @@ GLOBAL_ENTRY(relocate_new_kernel)
         srlz.i
         ;;
 	//purge TR entry for kernel text and data
+#ifdef CONFIG_XEN
+	mov r16=in5
+#else
         movl r16=KERNEL_START
+#endif
         mov r18=KERNEL_TR_PAGE_SHIFT<<2
         ;;
         ptr.i r16, r18
@@ -126,7 +146,11 @@ GLOBAL_ENTRY(relocate_new_kernel)
         mov r16=IA64_KR(CURRENT_STACK)
         ;;
         shl r16=r16,IA64_GRANULE_SHIFT
+#ifdef CONFIG_XEN
+	mov r19=in6
+#else
         movl r19=PAGE_OFFSET
+#endif
         ;;
         add r16=r19,r16
         mov r18=IA64_GRANULE_SHIFT<<2
@@ -183,10 +207,18 @@ GLOBAL_ENTRY(relocate_new_kernel)
 
 .align  32
 memory_stack:
+#ifdef CONFIG_XEN
+	.fill           4096, 1, 0
+#else
 	.fill           8192, 1, 0
+#endif
 memory_stack_end:
 register_stack:
+#ifdef CONFIG_XEN
+	.fill           4096, 1, 0
+#else
 	.fill           8192, 1, 0
+#endif
 register_stack_end:
 relocate_new_kernel_end:
 END(relocate_new_kernel)
Index: linux-2.6.18-xen.hg/arch/ia64/kernel/setup.c
===================================================================
--- linux-2.6.18-xen.hg.orig/arch/ia64/kernel/setup.c	2007-09-20 14:21:28.000000000 +0900
+++ linux-2.6.18-xen.hg/arch/ia64/kernel/setup.c	2007-09-20 14:44:27.000000000 +0900
@@ -307,6 +307,15 @@ reserve_memory (void)
 	{
 		char *from = strstr(saved_command_line, "crashkernel=");
 		unsigned long base, size;
+#ifdef CONFIG_XEN
+		if (is_initial_xendomain()) {
+			if (from)
+				printk("Ignoring crashkernel command line, "
+				       "parameter will be supplied by xen\n");
+			xen_machine_kexec_setup_resources();
+		}
+		else {
+#endif
 		if (from) {
 			size = memparse(from + 12, &from);
 			if (size) {
@@ -324,6 +333,9 @@ reserve_memory (void)
 				}
 			}
 		}
+#ifdef CONFIG_XEN
+		}
+#endif
 		efi_memmap_res.start = ia64_boot_param->efi_memmap;
                 efi_memmap_res.end = efi_memmap_res.start +
                         ia64_boot_param->efi_memmap_size;
Index: linux-2.6.18-xen.hg/arch/ia64/xen/xcom_hcall.c
===================================================================
--- linux-2.6.18-xen.hg.orig/arch/ia64/xen/xcom_hcall.c	2007-09-20 14:02:50.000000000 +0900
+++ linux-2.6.18-xen.hg/arch/ia64/xen/xcom_hcall.c	2007-09-20 14:19:59.000000000 +0900
@@ -39,6 +39,7 @@
 #include <xen/interface/hvm/params.h>
 #include <xen/interface/xenoprof.h>
 #include <xen/interface/vcpu.h>
+#include <xen/interface/kexec.h>
 #include <asm/hypercall.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -624,3 +625,33 @@ xencomm_hypercall_fpswa_revision(unsigne
 	return xencomm_arch_hypercall_fpswa_revision(desc);
 }
 EXPORT_SYMBOL_GPL(xencomm_hypercall_fpswa_revision);
+
+int
+xencomm_hypercall_kexec_op(int cmd, void *arg)
+{
+	unsigned int argsize;
+	struct xencomm_handle *desc;
+
+	switch (cmd) {
+	case KEXEC_CMD_kexec_get_range:
+		argsize = sizeof(xen_kexec_range_t);
+		break;
+	case KEXEC_CMD_kexec_load:
+	case KEXEC_CMD_kexec_unload:
+		argsize = sizeof(xen_kexec_load_t);
+		break;
+	case KEXEC_CMD_kexec:
+		argsize = sizeof(xen_kexec_exec_t);
+		break;
+	default:
+		printk("%s:%d cmd %d isn't supported\n",
+		       __func__, __LINE__, cmd);
+		BUG();
+	}
+
+	desc = xencomm_map_no_alloc(arg, argsize);
+	if (desc == NULL)
+		return -EINVAL;
+
+	return xencomm_arch_hypercall_kexec_op(cmd, desc);
+}
Index: linux-2.6.18-xen.hg/include/asm-ia64/hypercall.h
===================================================================
--- linux-2.6.18-xen.hg.orig/include/asm-ia64/hypercall.h	2007-09-20 14:02:50.000000000 +0900
+++ linux-2.6.18-xen.hg/include/asm-ia64/hypercall.h	2007-09-20 14:19:59.000000000 +0900
@@ -401,6 +401,12 @@ HYPERVISOR_add_io_space(unsigned long ph
 			   phys_base, sparse, space_number);
 }
 
+static inline int
+xencomm_arch_hypercall_kexec_op(int cmd, struct xencomm_handle *arg)
+{
+	return _hypercall2(int, kexec_op, cmd, arg);
+}
+
 // for balloon driver
 #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
 
@@ -419,6 +425,7 @@ HYPERVISOR_add_io_space(unsigned long ph
 #define HYPERVISOR_suspend xencomm_hypercall_suspend
 #define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op
 #define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature
+#define HYPERVISOR_kexec_op xencomm_hypercall_kexec_op
 
 /* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */
 #define HYPERVISOR_mmu_update(req, count, success_count, domid) ({BUG();0;})
Index: linux-2.6.18-xen.hg/include/asm-ia64/machvec_sn2.h
===================================================================
--- linux-2.6.18-xen.hg.orig/include/asm-ia64/machvec_sn2.h	2007-09-20 14:19:23.000000000 +0900
+++ linux-2.6.18-xen.hg/include/asm-ia64/machvec_sn2.h	2007-09-20 14:19:59.000000000 +0900
@@ -67,8 +67,8 @@ extern ia64_mv_dma_sync_sg_for_device	sn
 extern ia64_mv_dma_mapping_error	sn_dma_mapping_error;
 extern ia64_mv_dma_supported		sn_dma_supported;
 extern ia64_mv_migrate_t		sn_migrate;
-extern ia64_mv_kernel_launch_event_t	sn_kernel_launch_event;
 extern ia64_mv_msi_init_t		sn_msi_init;
+extern ia64_mv_kernel_launch_event_t	sn_kernel_launch_event;
 
 
 /*
@@ -120,12 +120,12 @@ extern ia64_mv_msi_init_t		sn_msi_init;
 #define platform_dma_mapping_error		sn_dma_mapping_error
 #define platform_dma_supported		sn_dma_supported
 #define platform_migrate		sn_migrate
-#define platform_kernel_launch_event    sn_kernel_launch_event
 #ifdef CONFIG_PCI_MSI
 #define platform_msi_init		sn_msi_init
 #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>
 
Index: linux-2.6.18-xen.hg/include/asm-ia64/sn/sn_sal.h
===================================================================
--- linux-2.6.18-xen.hg.orig/include/asm-ia64/sn/sn_sal.h	2007-09-20 14:19:23.000000000 +0900
+++ linux-2.6.18-xen.hg/include/asm-ia64/sn/sn_sal.h	2007-09-20 14:19:59.000000000 +0900
@@ -1147,6 +1147,13 @@ sn_inject_error(u64 paddr, u64 *data, u6
 				(u64)ecc, 0, 0, 0, 0);
 	return ret_stuff.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;
+}
 
 static inline int
 ia64_sn_set_cpu_number(int cpu)
@@ -1156,11 +1163,4 @@ ia64_sn_set_cpu_number(int cpu)
 	SAL_CALL_NOLOCK(rv, SN_SAL_SET_CPU_NUMBER, cpu, 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 */
Index: linux-2.6.18-xen.hg/include/asm-ia64/xen/xcom_hcall.h
===================================================================
--- linux-2.6.18-xen.hg.orig/include/asm-ia64/xen/xcom_hcall.h	2007-09-20 14:02:50.000000000 +0900
+++ linux-2.6.18-xen.hg/include/asm-ia64/xen/xcom_hcall.h	2007-09-20 14:19:59.000000000 +0900
@@ -60,4 +60,6 @@ extern long xencomm_hypercall_opt_featur
 struct privcmd_hypercall;
 extern int privcmd_hypercall(struct privcmd_hypercall *hypercall);
 
+extern int xencomm_hypercall_kexec_op(int cmd, void *arg);
+
 #endif /* _LINUX_XENCOMM_HCALL_H_ */
