# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1191996703 -32400
# Node ID 551fb6d7048179dcc8c5daca7350998f99e6577e
# Parent  679f88a2f502b318b41a708d9cf0e52854804915
fix stack unwinder.
- fix find_save_locs() and unw_unwind().
  instruction pointer check should be suite for xen.
- fix unw_unwind_to_user()
  VTi domain fault handler doesn't always updatevcpu->on_stack so that
  the pUStk check fails. Add more checking to stop winding.
PATCHNAME: fix_stack_unwinder

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff -r 679f88a2f502 -r 551fb6d70481 xen/arch/ia64/linux-xen/unwind.c
--- a/xen/arch/ia64/linux-xen/unwind.c  Wed Oct 10 15:40:20 2007 +0900
+++ b/xen/arch/ia64/linux-xen/unwind.c  Wed Oct 10 15:11:43 2007 +0900
@@ -1847,6 +1847,16 @@ run_script (struct unw_script *script, s
        goto redo;
 }
 
+#ifdef XEN
+static inline int
+is_hypervisor_virt(unsigned long addr)
+{
+       return IS_VMM_ADDRESS(addr) &&
+               (HYPERVISOR_VIRT_START <= addr) &&
+               (addr < HYPERVISOR_VIRT_END);
+}
+#endif
+
 static int
 find_save_locs (struct unw_frame_info *info)
 {
@@ -1857,6 +1867,8 @@ find_save_locs (struct unw_frame_info *i
        if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf))
 #ifndef XEN
            || info->ip < TASK_SIZE
+#else
+           || !is_hypervisor_virt(info->ip)
 #endif
                ) {
                /* don't let obviously bad addresses pollute the cache */
@@ -1915,7 +1927,11 @@ unw_unwind (struct unw_frame_info *info)
                return -1;
        }
        ip = info->ip = *info->rp_loc;
+#ifndef XEN
        if (ip < GATE_ADDR) {
+#else
+       if (!is_hypervisor_virt(info->ip)) {
+#endif
                UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", 
__FUNCTION__, ip);
                STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; 
local_irq_restore(flags));
                return -1;
@@ -1993,6 +2009,21 @@ unw_unwind_to_user (struct unw_frame_inf
                if (unw_is_intr_frame(info) &&
                    (pr & (1UL << PRED_USER_STACK)))
                        return 0;
+#ifdef XEN
+               /*
+                * vmx fault handlers don't always update vcpu->on_stack
+                * so that the above (pr & (1UL << PRED_USER_STACK)) condition
+                * isn't always true.
+                * hypercall path of break_fault does set pUStk=1,
+                * other fault paths don't set.
+                *
+                * we need to stop unwinding somehow.
+                */
+               if (unw_is_intr_frame(info) &&
+                   info->task->domain->arch.is_vti &&
+                   info->pr_loc == &vcpu_regs(info->task)->pr)
+                       return 0;
+#endif
                if (unw_get_pr (info, &pr) < 0) {
                        unw_get_rp(info, &ip);
                        UNW_DPRINT(0, "unwind.%s: failed to read "
# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1191996703 -32400
# Node ID 551fb6d7048179dcc8c5daca7350998f99e6577e
# Parent  679f88a2f502b318b41a708d9cf0e52854804915
fix stack unwinder.
- fix find_save_locs() and unw_unwind().
  instruction pointer check should be suite for xen.
- fix unw_unwind_to_user()
  VTi domain fault handler doesn't always updatevcpu->on_stack so that
  the pUStk check fails. Add more checking to stop winding.
PATCHNAME: fix_stack_unwinder

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff -r 679f88a2f502 -r 551fb6d70481 xen/arch/ia64/linux-xen/unwind.c
--- a/xen/arch/ia64/linux-xen/unwind.c	Wed Oct 10 15:40:20 2007 +0900
+++ b/xen/arch/ia64/linux-xen/unwind.c	Wed Oct 10 15:11:43 2007 +0900
@@ -1847,6 +1847,16 @@ run_script (struct unw_script *script, s
 	goto redo;
 }
 
+#ifdef XEN
+static inline int
+is_hypervisor_virt(unsigned long addr)
+{
+	return IS_VMM_ADDRESS(addr) &&
+		(HYPERVISOR_VIRT_START <= addr) &&
+		(addr < HYPERVISOR_VIRT_END);
+}
+#endif
+
 static int
 find_save_locs (struct unw_frame_info *info)
 {
@@ -1857,6 +1867,8 @@ find_save_locs (struct unw_frame_info *i
 	if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf))
 #ifndef XEN
 	    || info->ip < TASK_SIZE
+#else
+	    || !is_hypervisor_virt(info->ip)
 #endif
 		) {
 		/* don't let obviously bad addresses pollute the cache */
@@ -1915,7 +1927,11 @@ unw_unwind (struct unw_frame_info *info)
 		return -1;
 	}
 	ip = info->ip = *info->rp_loc;
+#ifndef XEN
 	if (ip < GATE_ADDR) {
+#else
+	if (!is_hypervisor_virt(info->ip)) {
+#endif
 		UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
@@ -1993,6 +2009,21 @@ unw_unwind_to_user (struct unw_frame_inf
 		if (unw_is_intr_frame(info) &&
 		    (pr & (1UL << PRED_USER_STACK)))
 			return 0;
+#ifdef XEN
+		/*
+		 * vmx fault handlers don't always update vcpu->on_stack
+		 * so that the above (pr & (1UL << PRED_USER_STACK)) condition
+		 * isn't always true.
+		 * hypercall path of break_fault does set pUStk=1,
+		 * other fault paths don't set.
+		 *
+		 * we need to stop unwinding somehow.
+		 */
+		if (unw_is_intr_frame(info) &&
+		    info->task->domain->arch.is_vti &&
+		    info->pr_loc == &vcpu_regs(info->task)->pr)
+			return 0;
+#endif
 		if (unw_get_pr (info, &pr) < 0) {
 			unw_get_rp(info, &ip);
 			UNW_DPRINT(0, "unwind.%s: failed to read "
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to