* [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