From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cooper Subject: [xen-devel] [Patch v2 2/4] x86/stack: Adjust boundary conditions for printed stacks. Date: Mon, 12 Aug 2013 13:15:00 +0100 Message-ID: <1376309700-18755-1-git-send-email-andrew.cooper3@citrix.com> References: <5208CBB402000078000EB1D2@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <5208CBB402000078000EB1D2@nat28.tlf.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Xen-devel Cc: Andrew Cooper , Keir Fraser , Jan Beulich , Tim Deegan List-Id: xen-devel@lists.xenproject.org Move the boundary into current.h along with the other stack manipulation code, and apply the same bottom boundary to both the frame pointer and non-frame pointer case. This will prevent the non-frame pointer case from finding certainly-spurious values on the stack in the guest_cpu_user_regs section. Signed-off-by: Andrew Cooper CC: Keir Fraser CC: Jan Beulich CC: Tim Deegan --- Changes since v1: * Change printable bottom depending on frame pointers --- xen/arch/x86/traps.c | 9 ++++----- xen/include/asm-x86/current.h | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index b686177..2bcfc7b 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -199,8 +199,9 @@ static void show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs) static void __show_trace(unsigned long sp, unsigned long __maybe_unused bp) { unsigned long *stack = (unsigned long *)sp, addr; + unsigned long *bottom = (unsigned long *)get_printable_stack_bottom(sp); - while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 ) + while ( stack <= bottom ) { addr = *stack++; if ( is_active_kernel_text(addr) ) @@ -216,12 +217,10 @@ static void __show_trace(unsigned long sp, unsigned long __maybe_unused bp) /* Stack trace from frames in the stack, using frame pointers */ static void __show_trace(unsigned long sp, unsigned long bp) { - unsigned long *frame, next, addr, low, high; + unsigned long *frame, next, addr; /* Bounds for range of valid frame pointer. */ - low = sp - 2*sizeof(unsigned long); - high = (low & ~(STACK_SIZE - 1)) + - (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long)); + unsigned long low = sp, high = get_printable_stack_bottom(sp); /* The initial frame pointer. */ next = bp; diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h index bec4dbe..02da2ec 100644 --- a/xen/include/asm-x86/current.h +++ b/xen/include/asm-x86/current.h @@ -50,6 +50,28 @@ static inline struct cpu_info *get_cpu_info(void) #define get_stack_bottom() \ ((unsigned long)&get_cpu_info()->guest_cpu_user_regs.es) +/* + * Get the bottom-of-stack, as useful for printing stack traces. This is + * similar position as is returned by get_cpu_info(), but works on arbitrary + * stack pointer, rather than just the current. + * + * In the non-frame pointer case, the boundary is exactly at the cpu_info + * structure, which prevents the stack trace walker from mis-interpreting + * guest register as Xen return addresses. + * + * For the frame pointer case, the boundary is further adjusted by two words, + * as the call out of assembly does not contain a traditional C stack with + * frame pointers. + */ +#ifdef CONFIG_FRAME_POINTER +#define get_printable_stack_bottom(sp) \ + ((sp & (~(STACK_SIZE-1))) + \ + (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long))) +#else +#define get_printable_stack_bottom(sp) \ + ((sp & (~(STACK_SIZE-1))) + (STACK_SIZE - sizeof(struct cpu_info))) +#endif + #define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ "mov %0,%%"__OP"sp; jmp %c1" \ -- 1.7.10.4