All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch][0/2]implement dump_execution_state() on ia64
@ 2008-03-27 13:05 Akio Takebe
  2008-03-27 13:09 ` [Patch][1/2]implement " Akio Takebe
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Akio Takebe @ 2008-03-27 13:05 UTC (permalink / raw)
  To: xen-ia64-devel, xen-devel

Hi,

This patch can show Calltraces at BUG_ON() on ia64.
And this supports xm debug-key d on ia64.
This patch needs to modify some common codes for supporting them.

[1/2] x86  side: implement_dump_execution_state.x86.patch
[2/2] ia64 side: implement_dump_execution_state.ia64.patch

Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>

Best Regards,

Akio Takebe

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Patch][1/2]implement dump_execution_state() on ia64
  2008-03-27 13:05 [Patch][0/2]implement dump_execution_state() on ia64 Akio Takebe
@ 2008-03-27 13:09 ` Akio Takebe
  2008-03-27 13:10 ` [Patch][2/2]implement " Akio Takebe
  2008-03-27 14:47 ` [Patch][0/2]implement " Keir Fraser
  2 siblings, 0 replies; 8+ messages in thread
From: Akio Takebe @ 2008-03-27 13:09 UTC (permalink / raw)
  To: Akio Takebe, xen-ia64-devel, xen-devel

[-- Attachment #1: Mail message body --]
[-- Type: text/plain, Size: 114 bytes --]

Hi,

This patch is x86  side.

Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>

Best Regards,

Akio Takebe

[-- Attachment #2: implement_dump_execution_state.x86.patch --]
[-- Type: application/octet-stream, Size: 5424 bytes --]

diff -r edfb58ca4d96 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/arch/x86/traps.c	Fri Mar 28 06:56:55 2008 +0900
@@ -329,6 +329,33 @@ void show_execution_state(struct cpu_use
 {
     show_registers(regs);
     show_stack(regs);
+}
+
+void __dump_execstate(void *unused)
+{
+    dump_execution_state();
+    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
+    if ( is_idle_vcpu(current) )
+        printk("No guest context (CPU is idle).\n");
+    else
+        show_execution_state(guest_cpu_user_regs());
+}
+
+void _dump_registers(struct cpu_user_regs *regs)
+{
+    unsigned int cpu;
+
+    /* Get local execution state out immediately, in case we get stuck. */
+    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
+    __dump_execstate(NULL);
+
+    for_each_online_cpu ( cpu )
+    {
+        if ( cpu == smp_processor_id() )
+            continue;
+        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
+        on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
+    }
 }
 
 char *trapstr(int trapnr)
diff -r edfb58ca4d96 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/common/keyhandler.c	Fri Mar 28 06:56:55 2008 +0900
@@ -89,34 +89,10 @@ static void show_handlers(unsigned char 
                    key_table[i].desc);
 }
 
-static void __dump_execstate(void *unused)
-{
-    dump_execution_state();
-    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
-    if ( is_idle_vcpu(current) )
-        printk("No guest context (CPU is idle).\n");
-    else
-        show_execution_state(guest_cpu_user_regs());
-}
-
 static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
 {
-    unsigned int cpu;
-
     printk("'%c' pressed -> dumping registers\n", key);
-
-    /* Get local execution state out immediately, in case we get stuck. */
-    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
-    __dump_execstate(NULL);
-
-    for_each_online_cpu ( cpu )
-    {
-        if ( cpu == smp_processor_id() )
-            continue;
-        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
-        on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
-    }
-
+    _dump_registers(regs);
     printk("\n");
 }
 
diff -r edfb58ca4d96 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/drivers/char/console.c	Fri Mar 28 06:56:55 2008 +0900
@@ -946,7 +946,7 @@ void __bug(char *file, int line)
 {
     console_start_sync();
     printk("Xen BUG at %s:%d\n", file, line);
-    dump_execution_state();
+    dump_execution_state(NULL);
     panic("Xen BUG at %s:%d\n", file, line);
     for ( ; ; ) ;
 }
@@ -954,7 +954,7 @@ void __warn(char *file, int line)
 void __warn(char *file, int line)
 {
     printk("Xen WARN at %s:%d\n", file, line);
-    dump_execution_state();
+    dump_execution_state(NULL);
 }
 
 
diff -r edfb58ca4d96 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/include/asm-x86/processor.h	Fri Mar 28 06:56:55 2008 +0900
@@ -561,6 +561,8 @@ void show_stack_overflow(unsigned int cp
 void show_stack_overflow(unsigned int cpu, unsigned long esp);
 void show_registers(struct cpu_user_regs *regs);
 void show_execution_state(struct cpu_user_regs *regs);
+void __dump_execstate(void *unused);
+void _dump_registers(struct cpu_user_regs *regs);
 void show_page_walk(unsigned long addr);
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
 
diff -r edfb58ca4d96 xen/include/asm-x86/x86_32/bug.h
--- a/xen/include/asm-x86/x86_32/bug.h	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/include/asm-x86/x86_32/bug.h	Fri Mar 28 06:56:55 2008 +0900
@@ -7,7 +7,9 @@ struct bug_frame_str {
 } __attribute__((packed));
 #define BUG_MOV_STR "\xbc"
 
-#define dump_execution_state()                          \
+#define dump_execution_state(i) _dump_execution_state()
+
+#define _dump_execution_state()                         \
     asm volatile (                                      \
         "ud2 ; ret $%c0"                                \
         : : "i" (BUGFRAME_dump) )
diff -r edfb58ca4d96 xen/include/asm-x86/x86_64/bug.h
--- a/xen/include/asm-x86/x86_64/bug.h	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/include/asm-x86/x86_64/bug.h	Fri Mar 28 06:56:55 2008 +0900
@@ -7,7 +7,8 @@ struct bug_frame_str {
 } __attribute__((packed));
 #define BUG_MOV_STR "\x48\xbc"
 
-#define dump_execution_state()                          \
+#define dump_execution_state(i) _dump_execution_state()
+#define _dump_execution_state()                         \
     asm volatile (                                      \
         "ud2 ; ret $%c0"                                \
         : : "i" (BUGFRAME_dump) )
diff -r edfb58ca4d96 xen/include/xen/smp.h
--- a/xen/include/xen/smp.h	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/include/xen/smp.h	Fri Mar 28 06:56:55 2008 +0900
@@ -47,6 +47,13 @@ extern int on_selected_cpus(
     int retry,
     int wait);
 
+/* this is only for ia64. */
+extern int on_selected_cpus_regs(
+    cpumask_t selected,
+    void (*func) (void *info, struct cpu_user_regs *),
+    void *info,
+    int retry,
+    int wait);
 /*
  * Mark the boot cpu "online" so that it can call console drivers in
  * printk() and can access its per-cpu storage.

[-- Attachment #3: Type: text/plain, Size: 152 bytes --]

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Patch][2/2]implement dump_execution_state() on ia64
  2008-03-27 13:05 [Patch][0/2]implement dump_execution_state() on ia64 Akio Takebe
  2008-03-27 13:09 ` [Patch][1/2]implement " Akio Takebe
@ 2008-03-27 13:10 ` Akio Takebe
  2008-03-27 14:47 ` [Patch][0/2]implement " Keir Fraser
  2 siblings, 0 replies; 8+ messages in thread
From: Akio Takebe @ 2008-03-27 13:10 UTC (permalink / raw)
  To: Akio Takebe, xen-ia64-devel, xen-devel

[-- Attachment #1: Mail message body --]
[-- Type: text/plain, Size: 114 bytes --]

Hi,

This patch is ia64 side.

Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>

Best Regards,

Akio Takebe

[-- Attachment #2: implement_dump_execution_state.ia64.patch --]
[-- Type: application/octet-stream, Size: 4930 bytes --]

diff -r edfb58ca4d96 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/arch/ia64/linux-xen/smp.c	Fri Mar 28 06:58:55 2008 +0900
@@ -91,10 +91,20 @@ struct call_data_struct {
 	atomic_t finished;
 };
 
+struct call_data_regs_struct {
+	void (*func) (void *info, struct cpu_user_regs *);
+	void *info;
+	long wait;
+	atomic_t started;
+	atomic_t finished;
+};
+
 static volatile struct call_data_struct *call_data;
+static volatile struct call_data_regs_struct *call_data_regs;
 
 #define IPI_CALL_FUNC		0
 #define IPI_CPU_STOP		1
+#define IPI_CALL_FUNC_REGS	2
 
 /* This needs to be cacheline aligned because it is written to by *other* CPUs.  */
 static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
@@ -183,7 +193,35 @@ handle_IPI (int irq, void *dev_id, struc
 					      atomic_inc(&data->finished);
 			      }
 			      break;
-
+#ifdef XEN
+			      case IPI_CALL_FUNC_REGS:
+			      {
+				      struct call_data_regs_struct *data;
+				      void (*func)(void *info, struct cpu_user_regs *);
+				      void *info;
+				      int wait;
+
+				      /* release the 'pointer lock' */
+				      data = (struct call_data_regs_struct *) call_data_regs;
+				      func = data->func;
+				      info = data->info;
+				      wait = data->wait;
+
+				      mb();
+				      atomic_inc(&data->started);
+				      /*
+				       * At this point the structure may be gone unless
+				       * wait is true.
+				       */
+				      (*func)(info, regs);
+
+				      /* Notify the sending CPU that the task is done.  */
+				      mb();
+				      if (wait)
+					      atomic_inc(&data->finished);
+			      }
+			      break;
+#endif
 			      case IPI_CPU_STOP:
 				stop_this_cpu();
 				break;
@@ -455,6 +493,41 @@ on_selected_cpus(cpumask_t selected, voi
 
 	return 0;
 }
+
+int
+on_selected_cpus_regs(cpumask_t selected, 
+		void (*func) (void *info, struct cpu_user_regs *), void *info,
+                 int retry, int wait)
+{
+	struct call_data_regs_struct data;
+	unsigned int cpu, nr_cpus = cpus_weight(selected);
+
+	ASSERT(local_irq_is_enabled());
+
+	if (!nr_cpus)
+		return 0;
+
+	data.func = func;
+	data.info = info;
+	data.wait = wait;
+	atomic_set(&data.started, 0);
+	atomic_set(&data.finished, 0);
+
+	spin_lock(&call_lock);
+
+	call_data_regs = &data;
+	wmb();
+
+	for_each_cpu_mask(cpu, selected)
+		send_IPI_single(cpu, IPI_CALL_FUNC_REGS);
+
+	while (atomic_read(wait ? &data.finished : &data.started) != nr_cpus)
+		cpu_relax();
+
+	spin_unlock(&call_lock);
+
+	return 0;
+}
 #endif
 
 /*
diff -r edfb58ca4d96 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/arch/ia64/xen/xenmisc.c	Fri Mar 28 06:58:55 2008 +0900
@@ -123,6 +123,50 @@ void audit_domains_key(unsigned char key
 {
 }
 
+inline void dump_execution_state(struct cpu_user_regs *regs)
+{
+    struct unw_frame_info info;
+    struct switch_stack *sw;
+    struct pt_regs *pt_regs = (struct pt_regs *)regs;
+
+    if (pt_regs == NULL){
+        pt_regs = guest_cpu_user_regs();
+        show_registers(pt_regs);
+    } else {
+        sw = (struct switch_stack *)(current->arch._thread.ksp + 16);
+        unw_init_from_interruption(&info, current, pt_regs, sw);
+        show_registers(pt_regs);
+        ia64_do_show_stack(&info, NULL);
+    }
+}
+
+void __dump_execstate(void *unused, struct cpu_user_regs *regs)
+{
+    dump_execution_state(NULL);
+    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
+    if ( is_idle_vcpu(current) )
+        printk("No guest context (CPU is idle).\n");
+    else
+        dump_execution_state(regs); // dump_execution_state(guest_cpu_user_regs()); ??? // 
+}
+
+void _dump_registers(struct cpu_user_regs *regs)
+{
+    unsigned int cpu;
+
+    /* Get local execution state out immediately, in case we get stuck. */
+    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
+    __dump_execstate(NULL, regs);
+
+    for_each_online_cpu ( cpu )
+    {
+        if ( cpu == smp_processor_id() )
+            continue;
+        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
+        on_selected_cpus_regs(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
+    }
+}
+
 void panic_domain(struct pt_regs *regs, const char *fmt, ...)
 {
 	va_list args;
diff -r edfb58ca4d96 xen/include/asm-ia64/xenprocessor.h
--- a/xen/include/asm-ia64/xenprocessor.h	Tue Mar 25 12:37:17 2008 -0600
+++ b/xen/include/asm-ia64/xenprocessor.h	Fri Mar 28 06:58:55 2008 +0900
@@ -250,6 +250,8 @@ typedef union {
 	};
 } ia64_pkr_t;
 
-#define dump_execution_state() printk("FIXME: implement ia64 dump_execution_state()\n");
+extern inline void dump_execution_state(struct cpu_user_regs *);
+extern inline void __dump_execstate(void *, struct cpu_user_regs *);
+extern inline void _dump_registers(struct cpu_user_regs *);
 
 #endif // _ASM_IA64_XENPROCESSOR_H

[-- Attachment #3: Type: text/plain, Size: 152 bytes --]

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch][0/2]implement dump_execution_state() on ia64
  2008-03-27 13:05 [Patch][0/2]implement dump_execution_state() on ia64 Akio Takebe
  2008-03-27 13:09 ` [Patch][1/2]implement " Akio Takebe
  2008-03-27 13:10 ` [Patch][2/2]implement " Akio Takebe
@ 2008-03-27 14:47 ` Keir Fraser
  2008-03-27 16:56   ` [Xen-devel] " Akio Takebe
  2 siblings, 1 reply; 8+ messages in thread
From: Keir Fraser @ 2008-03-27 14:47 UTC (permalink / raw)
  To: Akio Takebe, xen-ia64-devel, xen-devel

On 27/3/08 13:05, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

> This patch can show Calltraces at BUG_ON() on ia64.
> And this supports xm debug-key d on ia64.
> This patch needs to modify some common codes for supporting them.

Can you carefully explain why the interface changes are required?

 -- Keir

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Xen-devel] [Patch][0/2]implement dump_execution_state() on ia64
  2008-03-27 14:47 ` [Patch][0/2]implement " Keir Fraser
@ 2008-03-27 16:56   ` Akio Takebe
  2008-03-27 17:04     ` Keir Fraser
  0 siblings, 1 reply; 8+ messages in thread
From: Akio Takebe @ 2008-03-27 16:56 UTC (permalink / raw)
  To: Keir Fraser, xen-ia64-devel, xen-devel

Hi, Keir

>On 27/3/08 13:05, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:
>
>> This patch can show Calltraces at BUG_ON() on ia64.
>> And this supports xm debug-key d on ia64.
>> This patch needs to modify some common codes for supporting them.
>
>Can you carefully explain why the interface changes are required?
>
IA64 needs unwind infomation to show the Calltrace.
To make the unwind infomation, we needs switch stack and pt_regs.
So if possible, I want to use pt_regs at geting a interrupt.

I make many interface change because debug-key use IPI.
But I just want to use pt_regs.

Best Regards,

Akio Takebe

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch][0/2]implement dump_execution_state() on ia64
  2008-03-27 16:56   ` [Xen-devel] " Akio Takebe
@ 2008-03-27 17:04     ` Keir Fraser
  2008-03-27 17:22       ` [Xen-devel] " Akio Takebe
  0 siblings, 1 reply; 8+ messages in thread
From: Keir Fraser @ 2008-03-27 17:04 UTC (permalink / raw)
  To: Akio Takebe, xen-ia64-devel, xen-devel

On 27/3/08 16:56, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

>> Can you carefully explain why the interface changes are required?
>> 
> IA64 needs unwind infomation to show the Calltrace.
> To make the unwind infomation, we needs switch stack and pt_regs.
> So if possible, I want to use pt_regs at geting a interrupt.
> 
> I make many interface change because debug-key use IPI.
> But I just want to use pt_regs.

There is already a function which does what you want (i.e., takes a
cpu_user_regs pointer) -- it's called show_execution_state().

On x86 we implement dump_execution_state() by forcing an exception (by
executing an invalid opcode) and dumping the calltrace from within the
exception handler. This works because the exception handler has a
cpu_user_regs pointer and hence can call show_execution_state(). We use the
same trick for handling BUG() and ASSERT(). The code concerned is in
arch/x86/traps.c:do_invalid_op().

Can a similar thing be done on ia64?

 -- Keir

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Xen-devel] [Patch][0/2]implement dump_execution_state() on ia64
  2008-03-27 17:04     ` Keir Fraser
@ 2008-03-27 17:22       ` Akio Takebe
  2008-03-27 19:22         ` Keir Fraser
  0 siblings, 1 reply; 8+ messages in thread
From: Akio Takebe @ 2008-03-27 17:22 UTC (permalink / raw)
  To: Keir Fraser, xen-ia64-devel, xen-devel

Hi,

>On 27/3/08 16:56, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:
>
>>> Can you carefully explain why the interface changes are required?
>>> 
>> IA64 needs unwind infomation to show the Calltrace.
>> To make the unwind infomation, we needs switch stack and pt_regs.
>> So if possible, I want to use pt_regs at geting a interrupt.
>> 
>> I make many interface change because debug-key use IPI.
>> But I just want to use pt_regs.
>
>There is already a function which does what you want (i.e., takes a
>cpu_user_regs pointer) -- it's called show_execution_state().
>
>On x86 we implement dump_execution_state() by forcing an exception (by
>executing an invalid opcode) and dumping the calltrace from within the
>exception handler. This works because the exception handler has a
>cpu_user_regs pointer and hence can call show_execution_state(). We use the
>same trick for handling BUG() and ASSERT(). The code concerned is in
>arch/x86/traps.c:do_invalid_op().
On x86, does "xm debug-key d" make system hang?
Or it just uses the exception handler, not hangup?

Best Regards,

Akio Takebe

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch][0/2]implement dump_execution_state() on ia64
  2008-03-27 17:22       ` [Xen-devel] " Akio Takebe
@ 2008-03-27 19:22         ` Keir Fraser
  0 siblings, 0 replies; 8+ messages in thread
From: Keir Fraser @ 2008-03-27 19:22 UTC (permalink / raw)
  To: Akio Takebe, xen-ia64-devel, xen-devel

On 27/3/08 17:22, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

>> There is already a function which does what you want (i.e., takes a
>> cpu_user_regs pointer) -- it's called show_execution_state().
>> 
>> On x86 we implement dump_execution_state() by forcing an exception (by
>> executing an invalid opcode) and dumping the calltrace from within the
>> exception handler. This works because the exception handler has a
>> cpu_user_regs pointer and hence can call show_execution_state(). We use the
>> same trick for handling BUG() and ASSERT(). The code concerned is in
>> arch/x86/traps.c:do_invalid_op().
> On x86, does "xm debug-key d" make system hang?
> Or it just uses the exception handler, not hangup?

It works fine. It uses dump_execution_state(), as you have seen when you
modified it, and hence it does indeed force an exception on each CPU in
turn, and the exception handler dumps the cpu_user_regs (also known as
'pt_regs' in ia64) pointer that it receives.

 -- Keir

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-03-27 19:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-27 13:05 [Patch][0/2]implement dump_execution_state() on ia64 Akio Takebe
2008-03-27 13:09 ` [Patch][1/2]implement " Akio Takebe
2008-03-27 13:10 ` [Patch][2/2]implement " Akio Takebe
2008-03-27 14:47 ` [Patch][0/2]implement " Keir Fraser
2008-03-27 16:56   ` [Xen-devel] " Akio Takebe
2008-03-27 17:04     ` Keir Fraser
2008-03-27 17:22       ` [Xen-devel] " Akio Takebe
2008-03-27 19:22         ` Keir Fraser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.