[Crash-utility] [PATCH] s390x: Fix linux-3.10 backtrace for interrupt stacks

Michael Holzheu holzheu at linux.vnet.ibm.com
Tue Jun 4 12:32:08 UTC 2013


Hi Dave,

The following upstream kernel git commit introduced a crash regression
in v3.10-rc1 for s390x:

    commit dc7ee00d4771b3218b10e09e1071ee6eb176d381
    Date:   Wed Apr 24 10:20:43 2013 +0200

    s390: lowcore stack pointer offsets

    Store the stack pointers in the lowcore for the kernel stack, the async
    stack and the panic stack with the offset required for the first user.
    This avoids an unnecessary add instruction on the system call path.

    -	lc->async_stack = pcpu->async_stack + ASYNC_SIZE;
    -	lc->panic_stack = pcpu->panic_stack + PAGE_SIZE;
    +	lc->async_stack = pcpu->async_stack + ASYNC_SIZE
    +		- STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
    +	lc->panic_stack = pcpu->panic_stack + PAGE_SIZE
    +		- STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);

The s390x crash code uses lowcore->panic/async_stack to find out the
location of the per-cpu stacks. With the above kernel change this is
no longer correct. For newer kernels with the "pcpu_devices" array
there is a second location where the stacks are stored. With this
patch we use the new location if available.

Signed-off-by: Michael Holzheu <holzheu at linux.vnet.ibm.com>
---
 s390x.c |   42 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 8 deletions(-)

--- a/s390x.c
+++ b/s390x.c
@@ -913,10 +913,34 @@ s390x_get_lowcore(struct bt_info *bt, ch
 }
 
 /*
+ * Get stack address for interrupt stack using the pcpu array
+ */
+static unsigned long get_int_stack_pcpu(char *stack_name, int cpu)
+{
+	unsigned long addr;
+
+	if (!MEMBER_EXISTS("pcpu", stack_name))
+		return 0;
+	addr = symbol_value("pcpu_devices") +
+		cpu * STRUCT_SIZE("pcpu") + MEMBER_OFFSET("pcpu", stack_name);
+	return readmem_ul(addr) + INT_STACK_SIZE;
+}
+
+/*
+ * Get stack address for interrupt stack using the lowcore
+ */
+static unsigned long get_int_stack_lc(char *stack_name, char *lc)
+{
+	if (!MEMBER_EXISTS(lc_struct, stack_name))
+		return 0;
+	return ULONG(lc + MEMBER_OFFSET(lc_struct, stack_name));
+}
+
+/*
  * Read interrupt stack (either "async_stack" or "panic_stack");
  */
-static void get_int_stack(char *stack_name, char *lc, unsigned long *start,
-			  unsigned long *end)
+static void get_int_stack(char *stack_name, int cpu, char *lc,
+			  unsigned long *start, unsigned long *end)
 {
 	unsigned long stack_addr;
 
@@ -925,9 +949,10 @@ static void get_int_stack(char *stack_na
 		stack_addr = symbol_value("restart_stack");
 		stack_addr = readmem_ul(stack_addr);
 	} else {
-		if (!MEMBER_EXISTS(lc_struct, stack_name))
-			return;
-		stack_addr = ULONG(lc + MEMBER_OFFSET(lc_struct, stack_name));
+		if (symbol_exists("pcpu_devices"))
+			stack_addr = get_int_stack_pcpu(stack_name, cpu);
+		else
+			stack_addr = get_int_stack_lc(stack_name, lc);
 	}
 	if (stack_addr == 0)
 		return;
@@ -1157,12 +1182,13 @@ static void s390x_back_trace_cmd(struct
 		s390x_print_lowcore(lowcore,bt,1);
 		fprintf(fp,"\n");
 		if (symbol_exists("restart_stack")) {
-			get_int_stack("restart_stack", lowcore, &low, &high);
+			get_int_stack("restart_stack",
+				      cpu, lowcore, &low, &high);
 			sp = show_trace(bt, cnt, sp, low, high);
 		}
-		get_int_stack("panic_stack", lowcore, &low, &high);
+		get_int_stack("panic_stack", cpu, lowcore, &low, &high);
 		sp = show_trace(bt, cnt, sp, low, high);
-		get_int_stack("async_stack", lowcore, &low, &high);
+		get_int_stack("async_stack", cpu, lowcore, &low, &high);
 		sp = show_trace(bt, cnt, sp, low, high);
 	}
 	/*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: crash-7.0.0-s390-fix-stacks.patch
Type: text/x-patch
Size: 3545 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20130604/36f3f52e/attachment.bin>


More information about the Crash-utility mailing list