Subject: [IA64] Kexec: Implement elf_core_save_regs()
Date: Mon, 20 Aug 2007 12:26:52 +0900
From: Simon Horman <horms@verge.net.au>

Implement elf_core_save_regs() by porting (un #ifdefing)
ia64_elf_core_copy_regs() from Linux.

This ommits the calls to ia64_get_user_rbs_end() and ia64_sync_user_rbs()
in do_copy_task_regs(). Supplying them would seem to involve a reasonably
involved ammount of porting. I'm really not sure that its neccessary.

Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/process-linux-xen.c	2007-08-20 11:38:06.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c	2007-08-20 12:32:09.000000000 +0900
@@ -13,6 +13,7 @@
 #include <xen/symbols.h>
 #include <xen/smp.h>
 #include <xen/sched.h>
+#include <asm/elf.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
@@ -542,6 +543,8 @@ copy_thread (int nr, unsigned long clone
 	return retval;
 }
 
+#endif /* !XEN */
+
 static void
 do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
 {
@@ -559,10 +562,14 @@ do_copy_task_regs (struct task_struct *t
 	unw_get_sp(info, &sp);
 	pt = (struct pt_regs *) (sp + 16);
 
+#ifndef XEN
+	/* FIXME: Is this needed by XEN when it makes its crash notes
+	 * during kdump? */
 	urbs_end = ia64_get_user_rbs_end(task, pt, &cfm);
 
 	if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0)
 		return;
+#endif /* !XEN */
 
 	ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end),
 		  &ar_rnat);
@@ -614,6 +621,8 @@ do_copy_task_regs (struct task_struct *t
 	unw_get_ar(info, UNW_AR_SSD, &dst[56]);
 }
 
+#ifndef XEN
+
 void
 do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg)
 {
@@ -635,12 +644,16 @@ do_dump_task_fpu (struct task_struct *ta
 		memcpy(dst + 32, task->thread.fph, 96*16);
 }
 
+#endif /* !XEN */
+
 void
 do_copy_regs (struct unw_frame_info *info, void *arg)
 {
 	do_copy_task_regs(current, info, arg);
 }
 
+#ifndef XEN
+
 void
 do_dump_fpu (struct unw_frame_info *info, void *arg)
 {
@@ -662,12 +675,16 @@ dump_task_regs(struct task_struct *task,
 	return 1;
 }
 
+#endif /* !XEN */
+
 void
 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 {
 	unw_init_running(do_copy_regs, dst);
 }
 
+#ifndef XEN
+
 int
 dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst)
 {
Index: xen-unstable.hg/xen/include/asm-ia64/elf.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/elf.h	2007-08-20 11:38:06.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/elf.h	2007-08-20 12:00:01.000000000 +0900
@@ -1,8 +1,6 @@
 #ifndef __IA64_ELF_H__
 #define __IA64_ELF_H__
 
-#include <xen/lib.h>       /* for printk() used in stub */
-
 typedef struct {
     unsigned long r1;
     unsigned long r2;
@@ -20,14 +18,29 @@ typedef struct {
     unsigned long ar_ssd;
 } ELF_Gregset;
 
-typedef struct {
-    unsigned long dummy;
-} crash_xen_core_t;
+/*
+ * elf_gregset_t contains the application-level state in the following order:
+ *	r0-r31
+ *	NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
+ *	predicate registers (p0-p63)
+ *	b0-b7
+ *	ip cfm psr
+ *	ar.rsc ar.bsp ar.bspstore ar.rnat
+ *	ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
+ */
+#define ELF_NGREG	128 /* we really need just 72,
+			     * but let's leave some headroom */
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+typedef elf_gregset_t crash_xen_core_t;
+
+extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
 
 static inline void elf_core_save_regs(ELF_Gregset *core_regs, 
                                       crash_xen_core_t *xen_core_regs)
 {
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+    ia64_elf_core_copy_regs(NULL, *xen_core_regs);
 }
 
 #endif /* __IA64_ELF_H__ */
