Blob Blame History Raw
From edbd19bb260f7a98bc9e0b49fe2f0b8214885797 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Tue, 4 Oct 2022 18:57:11 +0800
Subject: [PATCH 26/28] ppc64: still allow to move on if the emergency stacks
 info fails to initialize

Currently crash will fail and then exit, if the initialization of
the emergency stacks information fails. In real customer environments,
sometimes, a vmcore may be partially damaged, although such vmcores
are rare. For example:

  # ./crash ../3.10.0-1127.18.2.el7.ppc64le/vmcore ../3.10.0-1127.18.2.el7.ppc64le/vmlinux  -s
  crash: invalid kernel virtual address: 38  type: "paca->emergency_sp"
  #

Lets try to keep loading vmcore if such issues happen, so call
the readmem() with the RETURN_ON_ERROR instead of FAULT_ON_ERROR,
which allows the crash move on.

Reported-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
 ppc64.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/ppc64.c b/ppc64.c
index 4ea1f7c0c6f8..b95a621d8fe4 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -1224,13 +1224,13 @@ ppc64_init_paca_info(void)
 		ulong paca_loc;
 
 		readmem(symbol_value("paca_ptrs"), KVADDR, &paca_loc, sizeof(void *),
-			"paca double pointer", FAULT_ON_ERROR);
+			"paca double pointer", RETURN_ON_ERROR);
 		readmem(paca_loc, KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
-			"paca pointers", FAULT_ON_ERROR);
+			"paca pointers", RETURN_ON_ERROR);
 	} else if (symbol_exists("paca") &&
 		   (get_symbol_type("paca", NULL, NULL) == TYPE_CODE_PTR)) {
 		readmem(symbol_value("paca"), KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
-			"paca pointers", FAULT_ON_ERROR);
+			"paca pointers", RETURN_ON_ERROR);
 	} else {
 		free(paca_ptr);
 		return;
@@ -1245,7 +1245,7 @@ ppc64_init_paca_info(void)
 		for (i = 0; i < kt->cpus; i++)
 			readmem(paca_ptr[i] + offset, KVADDR, &ms->emergency_sp[i],
 				sizeof(void *), "paca->emergency_sp",
-				FAULT_ON_ERROR);
+				RETURN_ON_ERROR);
 	}
 
 	if (MEMBER_EXISTS("paca_struct", "nmi_emergency_sp")) {
@@ -1256,7 +1256,7 @@ ppc64_init_paca_info(void)
 		for (i = 0; i < kt->cpus; i++)
 			readmem(paca_ptr[i] + offset, KVADDR, &ms->nmi_emergency_sp[i],
 				sizeof(void *), "paca->nmi_emergency_sp",
-				FAULT_ON_ERROR);
+				RETURN_ON_ERROR);
 	}
 
 	if (MEMBER_EXISTS("paca_struct", "mc_emergency_sp")) {
@@ -1267,7 +1267,7 @@ ppc64_init_paca_info(void)
 		for (i = 0; i < kt->cpus; i++)
 			readmem(paca_ptr[i] + offset, KVADDR, &ms->mc_emergency_sp[i],
 				sizeof(void *), "paca->mc_emergency_sp",
-				FAULT_ON_ERROR);
+				RETURN_ON_ERROR);
 	}
 
 	free(paca_ptr);
@@ -1947,7 +1947,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
 	if (cpu < 0  || cpu >= kt->cpus)
 		return NONE_STACK;
 
-	if (ms->emergency_sp) {
+	if (ms->emergency_sp && IS_KVADDR(ms->emergency_sp[cpu])) {
 		top = ms->emergency_sp[cpu];
 		base =  top - STACKSIZE();
 		if (addr >= base && addr < top) {
@@ -1957,7 +1957,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
 		}
 	}
 
-	if (ms->nmi_emergency_sp) {
+	if (ms->nmi_emergency_sp && IS_KVADDR(ms->nmi_emergency_sp[cpu])) {
 		top = ms->nmi_emergency_sp[cpu];
 		base = top - STACKSIZE();
 		if (addr >= base && addr < top) {
@@ -1967,7 +1967,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
 		}
 	}
 
-	if (ms->mc_emergency_sp) {
+	if (ms->mc_emergency_sp && IS_KVADDR(ms->mc_emergency_sp[cpu])) {
 		top = ms->mc_emergency_sp[cpu];
 		base =  top - STACKSIZE();
 		if (addr >= base && addr < top) {
-- 
2.37.1