implement dump_execution_state() on ia64
cover implement dump_execution_state() on ia64
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
Best Regards,
Akio Takebe
PATCH 1/2 implement dump_execution_state() on ia64
Hi,
This patch is x86 side.
Best Regards,
Akio Takebe
xen/arch/x86/traps.c +27 -0
@@ -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)
xen/common/keyhandler.c +1 -25
@@ -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" ); }
xen/drivers/char/console.c +2 -2
@@ -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 ); }
xen/include/asm-x86/processor.h +2 -0
@@ -561,6 +561,8 @@ void show_stack_overflow(unsigned int cpvoid 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);
xen/include/asm-x86/x86_32/bug.h +3 -1
@@ -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) )
xen/include/asm-x86/x86_64/bug.h +2 -1
@@ -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) )
xen/include/xen/smp.h +7 -0
@@ -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.
_______________________________________________
Xen-ia64-devel mailing list
[email protected]
http://lists.xensource.com/xen-ia64-devel
PATCH 2/2 implement dump_execution_state() on ia64
In reply to Akio TakebeHi,
This patch is ia64 side.
Best Regards,
Akio Takebe
xen/arch/ia64/linux-xen/smp.c +74 -1
@@ -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, strucatomic_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, voireturn 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 /*
xen/arch/ia64/xen/xenmisc.c +44 -0
50 lines not on this page · raw message
xen/include/asm-ia64/xenprocessor.h +3 -1
@@ -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
_______________________________________________
Xen-ia64-devel mailing list
[email protected]
http://lists.xensource.com/xen-ia64-devel
Quoted 3 lines · Akio Takebe
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
Hi, Keir
Quoted 8 lines · Akio Takebe
Quoted 4 lines
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
Quoted 8 lines · Akio Takebe
Quoted 2 lines
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 andpt_regs. So if possible, I want to usept_regsat 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
Hi,
Quoted 14 lines · Akio Takebe
Quoted 9 lines
Quoted 3 lines
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 andpt_regs. So if possible, I want to usept_regsat 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_regspointer) -- it's calledshow_execution_state().
Quoted 6 lines
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 acpu_user_regspointer and hence can callshow_execution_state(). We use the same trick for handlingBUG()andASSERT(). 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
Quoted 11 lines · Akio Takebe
Quoted 9 lines
There is already a function which does what you want (i.e., takes a
cpu_user_regspointer) -- it's calledshow_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 acpu_user_regspointer and hence can callshow_execution_state(). We use the same trick for handlingBUG()andASSERT(). 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