2/6
port Linux stack unwinder to Xen
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
--
diff -r df6a9e0d7e05 -r a1626275b04b xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile Wed Dec 28 15:19:56 2005 +0900
+++ b/xen/arch/ia64/Makefile Wed Dec 28 15:19:58 2005 +0900
@@ -22,6 +22,10 @@
memset.o strlen.o memcpy_mck.o \
__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
+
+# xen stack unwinder
+# unwind_decoder.c is included in unwind.c
+OBJS += unwind.o
# perfmon.o
# unwind.o needed for kernel unwinding (rare)
diff -r df6a9e0d7e05 -r a1626275b04b xen/arch/ia64/linux-xen/entry.S
--- a/xen/arch/ia64/linux-xen/entry.S Wed Dec 28 15:19:56 2005 +0900
+++ b/xen/arch/ia64/linux-xen/entry.S Wed Dec 28 15:19:58 2005 +0900
@@ -1417,7 +1417,6 @@
br.cond.sptk.many rp // goes to
ia64_leave_kernel
END(ia64_prepare_handle_unaligned)
-#ifndef XEN
//
// unw_init_running(void (*callback)(info, arg), void *arg)
//
@@ -1463,6 +1462,7 @@
br.ret.sptk.many rp
END(unw_init_running)
+#ifndef XEN
.rodata
.align 8
.globl sys_call_table
diff -r df6a9e0d7e05 -r a1626275b04b xen/arch/ia64/linux-xen/unwind.c
--- a/xen/arch/ia64/linux-xen/unwind.c Wed Dec 28 15:19:56 2005 +0900
+++ b/xen/arch/ia64/linux-xen/unwind.c Wed Dec 28 15:19:58 2005 +0900
@@ -26,12 +26,29 @@
* o if both the unw.lock spinlock and a script's read-write lock must be
* acquired, then the read-write lock must be acquired first.
*/
+#ifdef XEN
+#include <xen/types.h>
+#include <xen/elf.h>
+#include <xen/kernel.h>
+#include <xen/sched.h>
+#include <xen/xmalloc.h>
+#include <xen/spinlock.h>
+
+// work around
+#ifdef CONFIG_SMP
+#define write_trylock(lock) _raw_write_trylock(lock)
+#else
+#define write_trylock(lock) ({1;})
+#endif
+
+#else
#include <linux/module.h>
#include <linux/bootmem.h>
#include <linux/elf.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#endif
#include <asm/unwind.h>
@@ -72,10 +89,17 @@
# define STAT(x...)
#endif
+#ifdef XEN
+#define alloc_reg_state() xmalloc(struct unw_reg_state)
+#define free_reg_state(usr) xfree(usr)
+#define alloc_labeled_state() xmalloc(struct unw_labeled_state)
+#define free_labeled_state(usr) xfree(usr)
+#else
#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state),
GFP_ATOMIC)
#define free_reg_state(usr) kfree(usr)
#define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state),
GFP_ATOMIC)
#define free_labeled_state(usr) kfree(usr)
+#endif
typedef unsigned long unw_word;
typedef unsigned char unw_hash_index_t;
@@ -475,7 +499,11 @@
ia64_sync_fph(t);
else
ia64_flush_fph(t);
+#ifdef XEN
+ addr = t->arch._thread.fph + (regnum - 32);
+#else
addr = t->thread.fph + (regnum - 32);
+#endif
}
if (write)
@@ -1787,7 +1815,10 @@
case UNW_INSN_LOAD:
#ifdef UNW_DEBUG
if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7))
!= 0
- || s[val] < TASK_SIZE)
+#ifndef XEN
+ || s[val] < TASK_SIZE
+#endif
+ )
{
UNW_DPRINT(0, "unwind.%s: rejecting bad
psp=0x%lx\n",
__FUNCTION__, s[val]);
@@ -1821,7 +1852,11 @@
struct unw_script *scr;
unsigned long flags = 0;
- if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip <
TASK_SIZE) {
+ if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf))
+#ifndef XEN
+ || info->ip < TASK_SIZE
+#endif
+ ) {
/* don't let obviously bad addresses pollute the cache */
/* FIXME: should really be level 0 but it occurs too often. KAO
*/
UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n",
__FUNCTION__, info->ip);
@@ -2042,7 +2077,11 @@
void
unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
{
+#ifdef XEN
+ struct switch_stack *sw = (struct switch_stack *) (t->arch._thread.ksp
+ 16);
+#else
struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
+#endif
UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__);
unw_init_frame_info(info, t, sw);
@@ -2064,6 +2103,7 @@
table->length = end - start;
}
+#ifndef XEN
void *
unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned
long gp,
const void *table_start, const void *table_end)
@@ -2210,6 +2250,7 @@
}
__initcall(create_gate_table);
+#endif // !XEN
void __init
unw_init (void)
diff -r df6a9e0d7e05 -r a1626275b04b xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c Wed Dec 28 15:19:56 2005 +0900
+++ b/xen/arch/ia64/xen/xenmisc.c Wed Dec 28 15:19:58 2005 +0900
@@ -25,7 +25,6 @@
int phys_proc_id[NR_CPUS];
unsigned long loops_per_jiffy = (1<<12); // from linux/init/main.c
-void unw_init(void) { printf("unw_init() skipped (NEED FOR KERNEL UNWIND)\n");
}
void ia64_mca_init(void) { printf("ia64_mca_init() skipped (Machine check
abort handling)\n"); }
void ia64_mca_cpu_init(void *x) { }
void ia64_patch_mckinley_e9(unsigned long a, unsigned long b) { }
--
yamahata
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|