Skip to contentSkip to conversation

crash-utility: Support for sparc64 architecture

PATCH In review Dave Kleikamp 2 participants 2 messages Apr 25, 2016 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH v3 3/3 crash-utility: Support for sparc64 architecture

Based on original work by Karl Volz <[email protected]>

---
 Makefile            |    9 +-
 configure.c         |   23 +
 defs.h              |  138 ++++++-
 diskdump.c          |   36 ++-
 lkcd_vmdump_v2_v3.h |    2 +-
 sparc64.c           | 1253 +++++++++++++++++++++++++++++++++++++++++++++++++++
 symbols.c           |   10 +
 task.c              |   11 +-
 8 files changed, 1475 insertions(+), 7 deletions(-)
 create mode 100644 sparc64.c
Makefile +1 -1
index 7f5b0f1..d5d9497 100644
@@ -20,7 +20,7 @@
 PROGRAM=crash
 
 #
-# Supported targets: X86 ALPHA PPC IA64 PPC64
+# Supported targets: X86 ALPHA PPC IA64 PPC64 SPARC64
 # TARGET and GDB_CONF_FLAGS will be configured automatically by configure
 #
 TARGET@@ -62,7 +62,7 @@ VMWARE_HFILES=vmware_vmss.h

CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
kernel.c test.c gdb_interface.c configure.c net.c dev.c \
alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \
- arm.c arm64.c mips.c \
+ arm.c arm64.c mips.c sparc64.c \
extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \
lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\
lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \
@@ -81,7 +81,7 @@ SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
build_data.o kernel.o test.o gdb_interface.o net.o dev.o \
alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \
- arm.o arm64.o mips.o \
+ arm.o arm64.o mips.o sparc64.o \
extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \
lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \
lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o \
@@ -422,6 +422,9 @@ arm64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} arm64.c
mips.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips.c
${CC} -c ${CRASH_CFLAGS} mips.c ${WARNING_OPTIONS} ${WARNING_ERROR}

+sparc64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} sparc64.c
+ ${CC} -c ${CRASH_CFLAGS} sparc64.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+
s390.o: ${GENERIC_HFILES} ${IBM_HFILES} s390.c
${CC} -c ${CRASH_CFLAGS} s390.c ${WARNING_OPTIONS} ${WARNING_ERROR}

configure.c +23 -0
index a5167db..a2c033f 100644
@@ -104,6 +104,7 @@ void add_extra_lib(char *);
 #undef X86_64
 #undef ARM
 #undef ARM64
+#undef SPARC64
 
 #define UNKNOWN 0
 #define X86     1
@@ -117,6 +118,7 @@ void add_extra_lib(char *);
 #define ARM	9
 #define ARM64   10
 #define MIPS    11
+#define SPARC64 12
 
 #define TARGET_X86    "TARGET=X86"
 #define TARGET_ALPHA  "TARGET=ALPHA"
@@ -129,6 +131,7 @@ void add_extra_lib(char *);
 #define TARGET_ARM    "TARGET=ARM"
 #define TARGET_ARM64  "TARGET=ARM64"
 #define TARGET_MIPS   "TARGET=MIPS"
+#define TARGET_SPARC64 "TARGET=SPARC64"
 
 #define TARGET_CFLAGS_X86    "TARGET_CFLAGS=-D_FILE_OFFSET_BITSd"
 #define TARGET_CFLAGS_ALPHA  "TARGET_CFLAGS="
@@ -149,6 +152,7 @@ void add_extra_lib(char *);
 #define TARGET_CFLAGS_MIPS            "TARGET_CFLAGS=-D_FILE_OFFSET_BITSd"
 #define TARGET_CFLAGS_MIPS_ON_X86     "TARGET_CFLAGS=-D_FILE_OFFSET_BITSd"
 #define TARGET_CFLAGS_MIPS_ON_X86_64  "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITSd"
+#define TARGET_CFLAGS_SPARC64         "TARGET_CFLAGS="
 
 #define GDB_TARGET_DEFAULT        "GDB_CONF_FLAGS="
 #define GDB_TARGET_ARM_ON_X86     "GDB_CONF_FLAGS=--target=arm-elf-linux"
@@ -378,6 +382,9 @@ get_current_configuration(struct supported_gdb_version *sp)
 #ifdef __mips__
         target_data.target = MIPS;
 #endif
+#ifdef __sparc_v9__
+	target_data.target = SPARC64;
+#endif
 
 	set_initial_target(sp);
 
@@ -510,6 +517,10 @@ get_current_configuration(struct supported_gdb_version *sp)
 		if ((target_data.target = PPC) &&
 		    (target_data.initial_gdb_target != PPC))
 			arch_mismatch(sp);
+
+		if ((target_data.target = SPARC64) &&
+		    (target_data.initial_gdb_target != SPARC64))
+			arch_mismatch(sp);
 	}
 
         if ((fp = fopen("Makefile", "r")) = NULL) {
@@ -620,6 +631,9 @@ show_configuration(void)
 	case MIPS:
 		printf("TARGET: MIPS\n");
 		break;
+	case SPARC64:
+		printf("TARGET: SPARC64\n");
+		break;
 	}
 
 	if (strlen(target_data.program)) {
@@ -729,6 +743,10 @@ build_configure(struct supported_gdb_version *sp)
 		} else
                         target_CFLAGS = TARGET_CFLAGS_MIPS;
                 break;
+	case SPARC64:
+		target = TARGET_SPARC64;
+		target_CFLAGS = TARGET_CFLAGS_SPARC64;
+		break;
 	}
 
 	ldflags = get_extra_flags("LDFLAGS.extra", NULL);
@@ -1554,6 +1572,8 @@ set_initial_target(struct supported_gdb_version *sp)
 		target_data.initial_gdb_target = ARM;
 	else if (strncmp(buf, "MIPS", strlen("MIPS")) = 0)
 		target_data.initial_gdb_target = MIPS;
+	else if (strncmp(buf, "SPARC64", strlen("SPARC64")) = 0)
+		target_data.initial_gdb_target = SPARC64;
 }
 
 char *
@@ -1572,6 +1592,7 @@ target_to_name(int target)
 	case ARM:    return("ARM"); 
 	case ARM64:  return("ARM64");
 	case MIPS:   return("MIPS");
+	case SPARC64: return("SPARC64");
 	}
 
 	return "UNKNOWN";
@@ -1630,6 +1651,8 @@ name_to_target(char *name)
                 return MIPS;
         else if (strncmp(name, "MIPS", strlen("MIPS")) = 0)
                 return MIPS;
+	else if (strncmp(name, "sparc64", strlen("sparc64")) = 0)
+		return SPARC64;
 
 	return UNKNOWN;
 }
defs.h +137 -1

186 lines not on this page · raw message

diskdump.c +35 -1
index f5ec23d..48667ad 100644
@@ -730,6 +730,8 @@ restart:
 		dd->machine_type = EM_S390;
 	else if (machine_type("ARM64"))
 		dd->machine_type = EM_AARCH64;
+	else if (machine_type("SPARC64"))
+		dd->machine_type = EM_SPARCV9;
 	else {
 		error(INFO, "%s: unsupported machine type: %s\n", 
 			DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
@@ -1382,6 +1384,31 @@ get_diskdump_regs_arm64(struct bt_info *bt, ulong *eip, ulong *esp)
 	machdep->get_stack_frame(bt, eip, esp);
 }
 
+static void
+get_diskdump_regs_sparc64(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	Elf64_Nhdr *note;
+	int len;
+
+	if (KDUMP_CMPRS_VALID() &&
+		(bt->task = tt->panic_task ||
+		(is_task_active(bt->task) && dd->num_prstatus_notes > 1))) {
+		note  = (Elf64_Nhdr *)dd->nt_prstatus_percpu[bt->tc->processor];
+		if (!note)
+			error(FATAL,
+				    "cannot determine NT_PRSTATUS ELF note "
+				    "for %s task: %lx\n",
+					(bt->task = tt->panic_task) ?
+					"panic" : "active", bt->task);
+		len = sizeof(Elf64_Nhdr);
+		len = roundup(len + note->n_namesz, 4);
+		bt->machdep = (void *)((char *)note + len +
+			MEMBER_OFFSET("elf_prstatus", "pr_reg"));
+	}
+
+	machdep->get_stack_frame(bt, eip, esp);
+}
+
 /*
  *  Send the request to the proper architecture hander.
  */
@@ -1432,6 +1459,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
 		get_diskdump_regs_arm64(bt, eip, esp);
 		break;
 
+	case EM_SPARCV9:
+		get_diskdump_regs_sparc64(bt, eip, esp);
+		break;
+
 	default:
 		error(FATAL, "%s: unsupported machine type: %s\n",
 			DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
@@ -1577,7 +1608,8 @@ dump_note_offsets(FILE *fp)
 		for (tot = cnt = 0; tot < size; tot += len) {
 			qemu = FALSE;
 			if (machine_type("X86_64") || machine_type("S390X") ||
-			    machine_type("ARM64") || machine_type("PPC64")) {
+			    machine_type("ARM64") || machine_type("PPC64") ||
+			    machine_type("SPARC64")) {
 				note64 = (void *)dd->notes_buf + tot;
 				len = sizeof(Elf64_Nhdr);
 				if (STRNEQ((char *)note64 + len, "QEMU"))
@@ -1684,6 +1716,8 @@ __diskdump_memory_dump(FILE *fp)
 		fprintf(fp, "(EM_S390)\n"); break;
 	case EM_AARCH64:
 		fprintf(fp, "(EM_AARCH64)\n"); break;
+	case EM_SPARCV9:
+		fprintf(fp, "(EM_SPARCV9)\n"); break;
 	default:
 		fprintf(fp, "(unknown)\n"); break;
 	}
lkcd_vmdump_v2_v3.h +1 -1
index 7b014ec..8d5eae4 100644
@@ -36,7 +36,7 @@
 #endif
 
 #if defined(ARM) || defined(X86) || defined(PPC) || defined(S390) || \
-	defined(S390X) || defined(ARM64) || defined(MIPS)
+	defined(S390X) || defined(ARM64) || defined(MIPS) || defined(SPARC64)
 
 /*
  * Kernel header file for Linux crash dumps.
sparc64.c new file +1252 -0

1,252 lines not on this page · raw message

symbols.c +10 -0
index 7a3f260..8a837f8 100644
@@ -3398,6 +3398,11 @@ is_kernel(char *file)
 				goto bailout;
 			break;
 
+		case EM_SPARCV9:
+			if (machine_type_mismatch(file, "SPARC64", NULL, 0))
+				goto bailout;
+			break;
+
 		default:
 			if (machine_type_mismatch(file, "(unknown)", NULL, 0))
 				goto bailout;
@@ -3669,6 +3674,11 @@ is_shared_object(char *file)
 			if (machine_type("ARM64"))
 				return TRUE;
 			break;
+
+		case EM_SPARCV9:
+			if (machine_type("SPARC64"))
+				return TRUE;
+			break;
 		}
 
 		if (CRASHDEBUG(1))
task.c +10 -1
index 0743993..f21d0f8 100644
@@ -2369,7 +2369,11 @@ store_context(struct task_context *tc, ulong task, char *tp)
 
         tc->pid = (ulong)(*pid_addr);
 	strlcpy(tc->comm, comm_addr, TASK_COMM_LEN); 
-        tc->processor = *processor_addr;
+#ifdef SPARC64
+	tc->processor = *(unsigned short *)processor_addr;
+#else
+	tc->processor = *processor_addr;
+#endif
         tc->ptask = *parent_addr;
         tc->mm_struct = *mm_addr;
         tc->task = task;
@@ -7287,6 +7291,11 @@ get_idle_threads(ulong *tasklist, int nr_cpus)
 	    VALID_MEMBER(runqueue_idle)) {
 		runqbuf = GETBUF(SIZE(runqueue));
 		for (i = 0; i < nr_cpus; i++) {
+#ifdef SPARC64
+			if (cpu_map_addr("possible") &&
+			    !(in_cpu_map(POSSIBLE, i)))
+				continue;
+#endif
 			if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF))
 				runq = rq_sp->value + kt->__per_cpu_offset[i];
 			else
Signature · 1 line
1.7.1
Acked-by on v3 3/3
#1 lore raw

Hi Dave.

Quoted 1 line · Dave Kleikamp

Based on original work by Karl Volz <[email protected]>

I looked through the file - and this time nothing jumped out in my face like last time.
I did not have time/energy as a line-by-line review like last. But then again,the code does not look like it need it anymore. Looks much better now.

Quoted 2 lines