[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] INIT hadler for support coredumping feature



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID efdfbb40db3f124d1bcf8855b976cfc1fd95c363
# Parent  00f20f7c0e23849e4ae2addd1a118434dab39424
[IA64] INIT hadler for support coredumping feature

This patch is for supporting coredumping feature.
Some dump feature is necessary to save registers into memory.
So I implemented it and add a hook of calling dump function.
Because all cpu have to save registers,
the same handler is called by monarch and slave handler.

This patch is useful not only dump feature, but also debug xen.
(Because INIT hadler is always able to show register and call trace.)

Signed-off-by: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>
[Updated for linux-xen location]
Signed-off-by: Alex Williamson <alex.williamson@xxxxxx>
---
 xen/arch/ia64/linux-xen/mca.c     |   95 +++++++++++++++++++++++++++++++++-----
 xen/arch/ia64/linux-xen/mca_asm.S |   19 ++++++-
 2 files changed, 100 insertions(+), 14 deletions(-)

diff -r 00f20f7c0e23 -r efdfbb40db3f xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c     Thu Jul 06 13:27:47 2006 -0600
+++ b/xen/arch/ia64/linux-xen/mca.c     Thu Jul 06 14:07:49 2006 -0600
@@ -88,7 +88,12 @@
 #endif
 
 /* Used by mca_asm.S */
+#ifndef XEN
 ia64_mca_sal_to_os_state_t     ia64_sal_to_os_handoff_state;
+#else
+ia64_mca_sal_to_os_state_t     ia64_sal_to_os_handoff_state[NR_CPUS];
+DEFINE_PER_CPU(u64, ia64_sal_to_os_handoff_state_addr); 
+#endif
 ia64_mca_os_to_sal_state_t     ia64_os_to_sal_handoff_state;
 u64                            ia64_mca_serialize;
 DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
@@ -478,6 +483,43 @@ fetch_min_state (pal_min_state_area_t *m
        PUT_NAT_BIT(sw->caller_unat, &pt->r30); PUT_NAT_BIT(sw->caller_unat, 
&pt->r31);
 }
 
+#ifdef XEN
+static spinlock_t init_dump_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t show_stack_lock = SPIN_LOCK_UNLOCKED;
+
+static void
+save_ksp (struct unw_frame_info *info, void *arg)
+{
+       current->arch._thread.ksp = (__u64)(info->sw) - 16;
+       wmb();
+}
+
+/* FIXME */
+int try_crashdump(struct pt_regs *a) { return 0; }
+
+#define CPU_FLUSH_RETRY_MAX 5
+static void
+init_cache_flush (void)
+{
+       unsigned long flags;
+       int i;
+       s64 rval = 0;
+       u64 vector, progress = 0;
+
+       for (i = 0; i < CPU_FLUSH_RETRY_MAX; i++) {
+               local_irq_save(flags);
+               rval = ia64_pal_cache_flush(PAL_CACHE_TYPE_INSTRUCTION_DATA,
+                                           0, &progress, &vector);
+               local_irq_restore(flags);
+               if (rval == 0){
+                       printk("\nPAL cache flush success\n");
+                       return;
+               }
+       }
+       printk("\nPAL cache flush failed. status=%ld\n",rval);
+}
+#endif /* XEN */
+
 static void
 init_handler_platform (pal_min_state_area_t *ms,
                       struct pt_regs *pt, struct switch_stack *sw)
@@ -494,18 +536,36 @@ init_handler_platform (pal_min_state_are
         */
        printk("Delaying for 5 seconds...\n");
        udelay(5*1000000);
+#ifdef XEN
+       fetch_min_state(ms, pt, sw);
+       spin_lock(&show_stack_lock);
+#endif
        show_min_state(ms);
 
-#ifndef XEN
+#ifdef XEN
+       printk("Backtrace of current vcpu (vcpu_id %d)\n", current->vcpu_id);
+#else
        printk("Backtrace of current task (pid %d, %s)\n", current->pid, 
current->comm);
-#else
-       printk("Backtrace of current vcpu (vcpu_id %d)\n", current->vcpu_id);
+       fetch_min_state(ms, pt, sw);
 #endif
-       fetch_min_state(ms, pt, sw);
        unw_init_from_interruption(&info, current, pt, sw);
        ia64_do_show_stack(&info, NULL);
-
-#ifndef XEN
+#ifdef XEN
+       unw_init_running(save_ksp, NULL);
+       spin_unlock(&show_stack_lock);
+       wmb();
+       init_cache_flush();
+
+       if (spin_trylock(&init_dump_lock)) {
+#ifdef CONFIG_SMP
+               udelay(5*1000000);
+#endif
+               if (try_crashdump(pt) == 0)
+                       printk("\nINIT dump complete.  Please reboot now.\n");
+       }
+       printk("%s: CPU%d init handler done\n",
+              __FUNCTION__, smp_processor_id());
+#else /* XEN */
 #ifdef CONFIG_SMP
        /* read_trylock() would be handy... */
        if (!tasklist_lock.write_lock)
@@ -525,9 +585,9 @@ init_handler_platform (pal_min_state_are
        if (!tasklist_lock.write_lock)
                read_unlock(&tasklist_lock);
 #endif
-#endif /* !XEN */
 
        printk("\nINIT dump complete.  Please reboot now.\n");
+#endif /* XEN */
        while (1);                      /* hang city if no debugger */
 }
 
@@ -1158,16 +1218,20 @@ ia64_init_handler (struct pt_regs *pt, s
 ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
 {
        pal_min_state_area_t *ms;
+#ifdef XEN
+       int cpu = smp_processor_id();
+
+       printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
+              ia64_sal_to_os_handoff_state[cpu].proc_state_param);
+#endif
 
 #ifndef XEN
        oops_in_progress = 1;   /* avoid deadlock in printk, but it makes 
recovery dodgy */
        console_loglevel = 15;  /* make sure printks make it to console */
-#endif
 
        printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
                ia64_sal_to_os_handoff_state.proc_state_param);
 
-#ifndef XEN
        /*
         * Address of minstate area provided by PAL is physical,
         * uncacheable (bit 63 set). Convert to Linux virtual
@@ -1176,7 +1240,7 @@ ia64_init_handler (struct pt_regs *pt, s
        ms = (pal_min_state_area_t 
*)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
 #else
        /* Xen virtual address in region 7. */
-       ms = __va((pal_min_state_area_t 
*)(ia64_sal_to_os_handoff_state.pal_min_state));
+       ms = __va((pal_min_state_area_t 
*)(ia64_sal_to_os_handoff_state[cpu].pal_min_state));
 #endif
 
        init_handler_platform(ms, pt, sw);      /* call platform specific 
routines */
@@ -1273,7 +1337,14 @@ ia64_mca_cpu_init(void *cpu_data)
        __get_cpu_var(ia64_mca_data) = __per_cpu_mca[smp_processor_id()];
 #ifdef XEN
        IA64_MCA_DEBUG("%s: CPU#%d, ia64_mca_data=%lx\n", __FUNCTION__,
-                      smp_processor_id(),__get_cpu_var(ia64_mca_data));
+                      smp_processor_id(), __get_cpu_var(ia64_mca_data));
+
+       /* sal_to_os_handoff for smp support */
+       __get_cpu_var(ia64_sal_to_os_handoff_state_addr) =
+                     __pa(&ia64_sal_to_os_handoff_state[smp_processor_id()]);
+       IA64_MCA_DEBUG("%s: CPU#%d, ia64_sal_to_os=%lx\n", __FUNCTION__,
+                      smp_processor_id(),
+                      __get_cpu_var(ia64_sal_to_os_handoff_state_addr));
 #endif
 
        /*
@@ -1324,6 +1395,8 @@ ia64_mca_init(void)
        ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
 #ifdef XEN
        s64 rc;
+
+       slave_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
 
        IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
 #else
diff -r 00f20f7c0e23 -r efdfbb40db3f xen/arch/ia64/linux-xen/mca_asm.S
--- a/xen/arch/ia64/linux-xen/mca_asm.S Thu Jul 06 13:27:47 2006 -0600
+++ b/xen/arch/ia64/linux-xen/mca_asm.S Thu Jul 06 14:07:49 2006 -0600
@@ -48,6 +48,20 @@
  *             5. GR11 = Rendez state
  *             6. GR12 = Return address to location within SAL_CHECK
  */
+#ifdef XEN
+#define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)         \
+       movl    _tmp=THIS_CPU(ia64_sal_to_os_handoff_state_addr);;      \
+       tpa     _tmp=_tmp;;                             \
+       ld8     _tmp=[_tmp];;                           \
+       st8     [_tmp]=r1,0x08;;                        \
+       st8     [_tmp]=r8,0x08;;                        \
+       st8     [_tmp]=r9,0x08;;                        \
+       st8     [_tmp]=r10,0x08;;                       \
+       st8     [_tmp]=r11,0x08;;                       \
+       st8     [_tmp]=r12,0x08;;                       \
+       st8     [_tmp]=r17,0x08;;                       \
+       st8     [_tmp]=r18,0x08
+#else
 #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)         \
        LOAD_PHYSICAL(p0, _tmp, ia64_sal_to_os_handoff_state);; \
        st8     [_tmp]=r1,0x08;;                        \
@@ -59,7 +73,6 @@
        st8     [_tmp]=r17,0x08;;                       \
        st8     [_tmp]=r18,0x08
 
-#ifndef XEN
 /*
  * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
  * (p6) is executed if we never entered virtual mode (TLB error)
@@ -107,11 +120,11 @@
        ;;                                                              \
        ld8 reg=[reg]
 
-#endif /* !XEN */
+#endif /* XEN */
        .global ia64_os_mca_dispatch
        .global ia64_os_mca_dispatch_end
+#ifndef XEN
        .global ia64_sal_to_os_handoff_state
-#ifndef XEN
        .global ia64_os_to_sal_handoff_state
        .global ia64_do_tlb_purge
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.