Blame SOURCES/github_105a3e13_to_b5c2359f.patch

ada8de
commit 105a3e13167665dde5d3c12bf76ef9c916e82d0e
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Thu Oct 10 14:07:22 2019 -0400
ada8de
ada8de
    Fix for Linux 5.4-rc1 and later kernels that contain commit
ada8de
    688fcbfc06e4fdfbb7e1d5a942a1460fe6379d2d, titled "mm/vmalloc:
ada8de
    modify struct vmap_area to reduce its size".  Without the
ada8de
    patch "kmem -v" will display nothing; other architectures
ada8de
    that utilize the vmap_area_list to determine the base of
ada8de
    mapped/vmalloc address space will fail.
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/memory.c b/memory.c
ada8de
index 3a8b998..fe82fac 100644
ada8de
--- a/memory.c
ada8de
+++ b/memory.c
ada8de
@@ -401,9 +401,10 @@ vm_init(void)
ada8de
 	STRUCT_SIZE_INIT(vmap_area, "vmap_area");
ada8de
 	if (VALID_MEMBER(vmap_area_va_start) &&
ada8de
 	    VALID_MEMBER(vmap_area_va_end) &&
ada8de
-	    VALID_MEMBER(vmap_area_flags) &&
ada8de
 	    VALID_MEMBER(vmap_area_list) &&
ada8de
 	    VALID_MEMBER(vmap_area_vm) &&
ada8de
+	    (VALID_MEMBER(vmap_area_flags) || 
ada8de
+		(OFFSET(vmap_area_vm) == MEMBER_OFFSET("vmap_area", "purge_list"))) &&
ada8de
 	    kernel_symbol_exists("vmap_area_list"))
ada8de
 		vt->flags |= USE_VMAP_AREA;
ada8de
 
ada8de
@@ -8742,7 +8743,7 @@ static void
ada8de
 dump_vmap_area(struct meminfo *vi)
ada8de
 {
ada8de
 	int i, cnt;
ada8de
-	ulong start, end, vm_struct, flags;
ada8de
+	ulong start, end, vm_struct, flags, vm;
ada8de
 	struct list_data list_data, *ld;
ada8de
 	char *vmap_area_buf; 
ada8de
 	ulong size, pcheck, count, verified; 
ada8de
@@ -8790,9 +8791,15 @@ dump_vmap_area(struct meminfo *vi)
ada8de
 		readmem(ld->list_ptr[i], KVADDR, vmap_area_buf,
ada8de
                         SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR); 
ada8de
 
ada8de
-		flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
ada8de
-		if (flags != VM_VM_AREA)
ada8de
-			continue;
ada8de
+		if (VALID_MEMBER(vmap_area_flags)) {
ada8de
+			flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
ada8de
+			if (flags != VM_VM_AREA)
ada8de
+				continue;
ada8de
+		} else {
ada8de
+			vm = ULONG(vmap_area_buf + OFFSET(vmap_area_vm));
ada8de
+			if (!vm)
ada8de
+				continue;
ada8de
+		}
ada8de
 		start = ULONG(vmap_area_buf + OFFSET(vmap_area_va_start));
ada8de
 		end = ULONG(vmap_area_buf + OFFSET(vmap_area_va_end));
ada8de
 		vm_struct = ULONG(vmap_area_buf + OFFSET(vmap_area_vm));
ada8de
ada8de
commit 82ce13bceb1082a7c53c1bda71e17ca9c2a5cbc4
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Fri Oct 11 11:14:28 2019 -0400
ada8de
ada8de
    Fix for Linux 5.4-rc1 and later kernels that contain commit/merge
ada8de
    e0703556644a531e50b5dc61b9f6ea83af5f6604, titled "Merge tag 'modules-
ada8de
    for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
ada8de
    which introduces symbol namespaces.  Without the patch, and depending
ada8de
    upon the architecture:
ada8de
     (1) the kernel module symbol list will contain garbage entries
ada8de
     (2) the session fails during session initialization with a dump of
ada8de
         the internal buffer allocation stats followed by the message
ada8de
         "crash: cannot allocate any more memory!"
ada8de
     (3) the session fails during session initialization with a
ada8de
         segmentation violation.
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/defs.h b/defs.h
ada8de
index 32bd147..502e7c2 100644
ada8de
--- a/defs.h
ada8de
+++ b/defs.h
ada8de
@@ -2694,6 +2694,7 @@ struct symbol_table_data {
ada8de
 	ulong saved_command_line_vmlinux;
ada8de
 	ulong pti_init_vmlinux;
ada8de
 	ulong kaiser_init_vmlinux;
ada8de
+	int kernel_symbol_type;
ada8de
 };
ada8de
 
ada8de
 /* flags for st */
ada8de
diff --git a/symbols.c b/symbols.c
ada8de
index 3ce8692..7af5e69 100644
ada8de
--- a/symbols.c
ada8de
+++ b/symbols.c
ada8de
@@ -1607,39 +1607,100 @@ union kernel_symbol {
ada8de
 		unsigned long value;
ada8de
 		const char *name;
ada8de
 	} v1;
ada8de
-	/* kernel 4.19 introduced relative symbol positionning */
ada8de
+	/* kernel 4.19 introduced relative symbol positioning */
ada8de
 	struct kernel_symbol_v2 {
ada8de
 		int value_offset;
ada8de
 		int name_offset;
ada8de
 	} v2;
ada8de
+	/* kernel 5.4 introduced symbol namespaces */
ada8de
+	struct kernel_symbol_v3 {
ada8de
+		int value_offset;
ada8de
+		int name_offset;
ada8de
+		int namespace_offset;
ada8de
+	} v3;
ada8de
+	struct kernel_symbol_v4 {
ada8de
+		unsigned long value;
ada8de
+		const char *name;
ada8de
+		const char *namespace;
ada8de
+	} v4;
ada8de
 };
ada8de
 
ada8de
+static size_t
ada8de
+kernel_symbol_type_init(void)
ada8de
+{
ada8de
+	if (MEMBER_EXISTS("kernel_symbol", "value") &&
ada8de
+	    MEMBER_EXISTS("kernel_symbol", "name")) {
ada8de
+		if (MEMBER_EXISTS("kernel_symbol", "namespace")) {
ada8de
+			st->kernel_symbol_type = 4;
ada8de
+			return (sizeof(struct kernel_symbol_v4));
ada8de
+		} else {
ada8de
+			st->kernel_symbol_type = 1;
ada8de
+			return (sizeof(struct kernel_symbol_v1));
ada8de
+		}
ada8de
+	}
ada8de
+	if (MEMBER_EXISTS("kernel_symbol", "value_offset") &&
ada8de
+	    MEMBER_EXISTS("kernel_symbol", "name_offset")) {
ada8de
+		if (MEMBER_EXISTS("kernel_symbol", "namespace_offset")) {
ada8de
+			st->kernel_symbol_type = 3;
ada8de
+			return (sizeof(struct kernel_symbol_v3));
ada8de
+		} else {
ada8de
+			st->kernel_symbol_type = 2;
ada8de
+			return (sizeof(struct kernel_symbol_v2));
ada8de
+		}
ada8de
+	}
ada8de
+
ada8de
+	error(FATAL, "kernel_symbol data structure has changed\n");
ada8de
+
ada8de
+	return 0;
ada8de
+}
ada8de
+
ada8de
 static ulong
ada8de
 modsym_name(ulong syms, union kernel_symbol *modsym, int i)
ada8de
 {
ada8de
-	if (VALID_MEMBER(kernel_symbol_value))
ada8de
+	switch (st->kernel_symbol_type)
ada8de
+	{
ada8de
+	case 1:
ada8de
 		return (ulong)modsym->v1.name;
ada8de
+	case 2:
ada8de
+		return (syms + i * sizeof(struct kernel_symbol_v2) +
ada8de
+			offsetof(struct kernel_symbol_v2, name_offset) +
ada8de
+			modsym->v2.name_offset);
ada8de
+	case 3:
ada8de
+		return (syms + i * sizeof(struct kernel_symbol_v3) +
ada8de
+			offsetof(struct kernel_symbol_v3, name_offset) +
ada8de
+			modsym->v3.name_offset);
ada8de
+	case 4:
ada8de
+		return (ulong)modsym->v4.name;
ada8de
+	}
ada8de
 
ada8de
-	return syms + i * sizeof(struct kernel_symbol_v2) +
ada8de
-		offsetof(struct kernel_symbol_v2, name_offset) +
ada8de
-		modsym->v2.name_offset;
ada8de
+	return 0;
ada8de
 }
ada8de
 
ada8de
 static ulong
ada8de
 modsym_value(ulong syms, union kernel_symbol *modsym, int i)
ada8de
 {
ada8de
-	if (VALID_MEMBER(kernel_symbol_value))
ada8de
+	switch (st->kernel_symbol_type)
ada8de
+	{
ada8de
+	case 1:
ada8de
 		return (ulong)modsym->v1.value;
ada8de
+	case 2:
ada8de
+		return (syms + i * sizeof(struct kernel_symbol_v2) +
ada8de
+			offsetof(struct kernel_symbol_v2, value_offset) +
ada8de
+			modsym->v2.value_offset);
ada8de
+	case 3:
ada8de
+		return (syms + i * sizeof(struct kernel_symbol_v3) +
ada8de
+			offsetof(struct kernel_symbol_v3, value_offset) +
ada8de
+			modsym->v3.value_offset);
ada8de
+	case 4:
ada8de
+		return (ulong)modsym->v4.value;
ada8de
+	}
ada8de
 
ada8de
-	return syms + i * sizeof(struct kernel_symbol_v2) +
ada8de
-		offsetof(struct kernel_symbol_v2, value_offset) +
ada8de
-		modsym->v2.value_offset;
ada8de
+	return 0;
ada8de
 }
ada8de
 
ada8de
 void
ada8de
 store_module_symbols_v2(ulong total, int mods_installed)
ada8de
 {
ada8de
-
ada8de
         int i, m;
ada8de
         ulong mod, mod_next; 
ada8de
 	char *mod_name;
ada8de
@@ -1675,12 +1736,7 @@ store_module_symbols_v2(ulong total, int mods_installed)
ada8de
 		  "re-initialization of module symbols not implemented yet!\n");
ada8de
 	}
ada8de
 
ada8de
-	MEMBER_OFFSET_INIT(kernel_symbol_value, "kernel_symbol", "value");
ada8de
-	if (VALID_MEMBER(kernel_symbol_value)) {
ada8de
-		kernel_symbol_size = sizeof(struct kernel_symbol_v1);
ada8de
-	} else {
ada8de
-		kernel_symbol_size = sizeof(struct kernel_symbol_v2);
ada8de
-	}
ada8de
+	kernel_symbol_size = kernel_symbol_type_init();
ada8de
 
ada8de
         if ((st->ext_module_symtable = (struct syment *)
ada8de
              calloc(total, sizeof(struct syment))) == NULL)
ada8de
@@ -3418,6 +3474,8 @@ dump_symbol_table(void)
ada8de
 		fprintf(fp, "\n");
ada8de
 	} else
ada8de
 		fprintf(fp, "(none)\n");
ada8de
+
ada8de
+	fprintf(fp, "  kernel_symbol_type: v%d\n", st->kernel_symbol_type);
ada8de
 }
ada8de
 
ada8de
 
ada8de
ada8de
commit c1ac656508ad064ef0ef222acb73621ae0bf4f00
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Tue Oct 15 11:21:55 2019 -0400
ada8de
ada8de
    Fix for the "timer -r" option on Linux 5.4-rc1 and later kernels
ada8de
    that contain commit 511885d7061eda3eb1faf3f57dcc936ff75863f1, titled
ada8de
    "lib/timerqueue: Rely on rbtree semantics for next timer".  Without
ada8de
    the patch, the option fails with the following error "timer: invalid
ada8de
    structure member offset: timerqueue_head_next".
ada8de
    (k-hagio@ab.jp.nec.com)
ada8de
ada8de
diff --git a/defs.h b/defs.h
ada8de
index 502e7c2..efa40b9 100644
ada8de
--- a/defs.h
ada8de
+++ b/defs.h
ada8de
@@ -2073,6 +2073,8 @@ struct offset_table {                    /* stash of commonly-used offsets */
ada8de
 	long cpu_context_save_r7;
ada8de
 	long dentry_d_sb;
ada8de
 	long device_private_knode_class;
ada8de
+	long timerqueue_head_rb_root;
ada8de
+	long rb_root_cached_rb_leftmost;
ada8de
 };
ada8de
 
ada8de
 struct size_table {         /* stash of commonly-used sizes */
ada8de
diff --git a/kernel.c b/kernel.c
ada8de
index 375e1b4..c4cb001 100644
ada8de
--- a/kernel.c
ada8de
+++ b/kernel.c
ada8de
@@ -783,7 +783,13 @@ kernel_init()
ada8de
 		MEMBER_OFFSET_INIT(timerqueue_node_expires, 
ada8de
 			"timerqueue_node", "expires");
ada8de
 		MEMBER_OFFSET_INIT(timerqueue_node_node, 
ada8de
-			"timerqueue_node_node", "node");
ada8de
+			"timerqueue_node", "node");
ada8de
+		if (INVALID_MEMBER(timerqueue_head_next)) {
ada8de
+			MEMBER_OFFSET_INIT(timerqueue_head_rb_root,
ada8de
+				"timerqueue_head", "rb_root");
ada8de
+			MEMBER_OFFSET_INIT(rb_root_cached_rb_leftmost,
ada8de
+				"rb_root_cached", "rb_leftmost");
ada8de
+		}
ada8de
 	}
ada8de
 	MEMBER_OFFSET_INIT(hrtimer_softexpires, "hrtimer", "_softexpires");
ada8de
 	MEMBER_OFFSET_INIT(hrtimer_function, "hrtimer", "function");
ada8de
@@ -7647,11 +7653,17 @@ next_one:
ada8de
 		readmem((ulong)(base + OFFSET(hrtimer_clock_base_first)),
ada8de
 			KVADDR,	&curr, sizeof(curr), "hrtimer_clock_base first",
ada8de
 			FAULT_ON_ERROR);
ada8de
-	else
ada8de
+	else if (VALID_MEMBER(timerqueue_head_next))
ada8de
 		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
ada8de
 				OFFSET(timerqueue_head_next)),
ada8de
 			KVADDR, &curr, sizeof(curr), "hrtimer_clock base",
ada8de
 			FAULT_ON_ERROR);
ada8de
+	else
ada8de
+		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
ada8de
+				OFFSET(timerqueue_head_rb_root) +
ada8de
+				OFFSET(rb_root_cached_rb_leftmost)),
ada8de
+			KVADDR, &curr, sizeof(curr),
ada8de
+			"hrtimer_clock_base active", FAULT_ON_ERROR);
ada8de
 
ada8de
 	while (curr && i < next) {
ada8de
 		curr = rb_next(curr);
ada8de
diff --git a/symbols.c b/symbols.c
ada8de
index 7af5e69..eb88ca1 100644
ada8de
--- a/symbols.c
ada8de
+++ b/symbols.c
ada8de
@@ -10032,6 +10032,8 @@ dump_offset_table(char *spec, ulong makestruct)
ada8de
                 OFFSET(rb_node_rb_left));
ada8de
         fprintf(fp, "              rb_node_rb_right: %ld\n",
ada8de
                 OFFSET(rb_node_rb_right));
ada8de
+        fprintf(fp, "    rb_root_cached_rb_leftmost: %ld\n",
ada8de
+                OFFSET(rb_root_cached_rb_leftmost));
ada8de
 
ada8de
 	fprintf(fp, "            x8664_pda_pcurrent: %ld\n",
ada8de
 		OFFSET(x8664_pda_pcurrent));
ada8de
@@ -10388,6 +10390,8 @@ dump_offset_table(char *spec, ulong makestruct)
ada8de
 		OFFSET(hrtimer_function));
ada8de
 	fprintf(fp, "          timerqueue_head_next: %ld\n",
ada8de
 		OFFSET(timerqueue_head_next));
ada8de
+	fprintf(fp, "       timerqueue_head_rb_root: %ld\n",
ada8de
+		OFFSET(timerqueue_head_rb_root));
ada8de
 	fprintf(fp, "       timerqueue_node_expires: %ld\n",
ada8de
 		OFFSET(timerqueue_node_expires));
ada8de
 	fprintf(fp, "          timerqueue_node_node: %ld\n",
ada8de
ada8de
commit e13fe8ba5a0b9c54edea103a309e9879784d9b94
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Tue Oct 15 16:29:30 2019 -0400
ada8de
ada8de
    Fix for a "[-Wstringop-truncation]" compiler warning emitted when
ada8de
    symbols.c is built in a Fedora Rawhide environment with gcc-9.0.1
ada8de
    or later.
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/symbols.c b/symbols.c
ada8de
index eb88ca1..55199fc 100644
ada8de
--- a/symbols.c
ada8de
+++ b/symbols.c
ada8de
@@ -8174,8 +8174,10 @@ parse_for_member_extended(struct datatype_member *dm,
ada8de
 		 */
ada8de
 
ada8de
 		if (current && p && (p - p1 < BUFSIZE)) {
ada8de
-			strncpy(current->field_name, p1, p - p1);
ada8de
+//			strncpy(current->field_name, p1, p - p1);  (NOTE: gcc-9.0.1 emits [-Wstringop-truncation] warning)
ada8de
 			current->field_len = p - p1;
ada8de
+			memcpy(current->field_name, p1, current->field_len);
ada8de
+			current->field_name[current->field_len] = '\0';
ada8de
 		}
ada8de
 
ada8de
 		if ( p && (*s_e != '{' || (*s_e == '{' && buf[len] == '}') )) {
ada8de
ada8de
commit 9937878cce2fc049283d833685cb939caca462ca
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Thu Oct 17 12:00:23 2019 -0400
ada8de
ada8de
    Fix for the "kmem -n" option on Linux-5.4-rc1 and later kernels that
ada8de
    contain commit b6c88d3b9d38f9448e0fcf44847a075ea81d5ca2, titled
ada8de
    "drivers/base/memory.c: don't store end_section_nr in memory blocks".
ada8de
    Without the patch, the command option fails with the error message
ada8de
    "kmem: invalid structure member offset: memory_block_end_section_nr".
ada8de
    (msys.mizuma@gmail.com)
ada8de
ada8de
diff --git a/help.c b/help.c
ada8de
index a5218a7..cfd46c3 100644
ada8de
--- a/help.c
ada8de
+++ b/help.c
ada8de
@@ -7177,7 +7177,7 @@ char *help_kmem[] = {
ada8de
 "     6  ffff88003d4d90c0  ffffea0000000000  ffffea0000c00000   PM   196608",
ada8de
 "     7  ffff88003d4d90e0  ffffea0000000000  ffffea0000e00000   PM   229376",
ada8de
 "    ",
ada8de
-"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          SECTIONS",
ada8de
+"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          START_SECTION_NO",
ada8de
 "     ffff88003a707c00  memory0          0 - 7ffffff  ONLINE         0",
ada8de
 "     ffff88003a6e0000  memory1    8000000 - fffffff  ONLINE         1",
ada8de
 "     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE         2",
ada8de
diff --git a/memory.c b/memory.c
ada8de
index fe82fac..0a79838 100644
ada8de
--- a/memory.c
ada8de
+++ b/memory.c
ada8de
@@ -17402,20 +17402,18 @@ fill_memory_block_name(ulong memblock, char *name)
ada8de
 }
ada8de
 
ada8de
 static void
ada8de
-fill_memory_block_srange(ulong start_sec, ulong end_sec, char *srange)
ada8de
+fill_memory_block_srange(ulong start_sec, char *srange)
ada8de
 {
ada8de
 	memset(srange, 0, sizeof(*srange) * BUFSIZE);
ada8de
 
ada8de
-	if (start_sec == end_sec)
ada8de
-		sprintf(srange, "%lu", start_sec);
ada8de
-	else
ada8de
-		sprintf(srange, "%lu-%lu", start_sec, end_sec);
ada8de
+	sprintf(srange, "%lu", start_sec);
ada8de
 }
ada8de
 
ada8de
 static void
ada8de
 print_memory_block(ulong memory_block)
ada8de
 {
ada8de
-	ulong start_sec, end_sec, start_pfn, end_pfn, nid;
ada8de
+	ulong start_sec, end_sec, nid;
ada8de
+	ulong memblock_size, mbs, start_addr, end_addr;
ada8de
 	char statebuf[BUFSIZE];
ada8de
 	char srangebuf[BUFSIZE];
ada8de
 	char name[BUFSIZE];
ada8de
@@ -17430,15 +17428,25 @@ print_memory_block(ulong memory_block)
ada8de
 	readmem(memory_block + OFFSET(memory_block_start_section_nr), KVADDR,
ada8de
 		&start_sec, sizeof(void *), "memory_block start_section_nr",
ada8de
 		FAULT_ON_ERROR);
ada8de
-	readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
ada8de
-		&end_sec, sizeof(void *), "memory_block end_section_nr",
ada8de
-		FAULT_ON_ERROR);
ada8de
 
ada8de
-	start_pfn = section_nr_to_pfn(start_sec);
ada8de
-	end_pfn = section_nr_to_pfn(end_sec + 1);
ada8de
+	start_addr = pfn_to_phys(section_nr_to_pfn(start_sec));
ada8de
+
ada8de
+	if (symbol_exists("memory_block_size_probed")) {
ada8de
+		memblock_size = symbol_value("memory_block_size_probed");
ada8de
+		readmem(memblock_size, KVADDR,
ada8de
+			&mbs, sizeof(ulong), "memory_block_size_probed",
ada8de
+			FAULT_ON_ERROR);
ada8de
+		end_addr = start_addr + mbs - 1;
ada8de
+	} else {
ada8de
+	        readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
ada8de
+			&end_sec, sizeof(void *), "memory_block end_section_nr",
ada8de
+			FAULT_ON_ERROR);
ada8de
+		end_addr = pfn_to_phys(section_nr_to_pfn(end_sec + 1)) - 1;
ada8de
+	}
ada8de
+
ada8de
 	fill_memory_block_state(memory_block, statebuf);
ada8de
 	fill_memory_block_name(memory_block, name);
ada8de
-	fill_memory_block_srange(start_sec, end_sec, srangebuf);
ada8de
+	fill_memory_block_srange(start_sec, srangebuf);
ada8de
 
ada8de
 	if (MEMBER_EXISTS("memory_block", "nid")) {
ada8de
 		readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
ada8de
@@ -17448,9 +17456,9 @@ print_memory_block(ulong memory_block)
ada8de
 			MKSTR(memory_block)),
ada8de
 			mkstring(buf2, 12, CENTER, name),
ada8de
 			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
ada8de
-			MKSTR(pfn_to_phys(start_pfn))),
ada8de
+			MKSTR(start_addr)),
ada8de
 			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
ada8de
-			MKSTR(pfn_to_phys(end_pfn) - 1)),
ada8de
+			MKSTR(end_addr)),
ada8de
 			mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
ada8de
 			MKSTR(nid)),
ada8de
 			mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
ada8de
@@ -17462,9 +17470,9 @@ print_memory_block(ulong memory_block)
ada8de
 			MKSTR(memory_block)),
ada8de
 			mkstring(buf2, 10, CENTER, name),
ada8de
 			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
ada8de
-			MKSTR(pfn_to_phys(start_pfn))),
ada8de
+			MKSTR(start_addr)),
ada8de
 			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
ada8de
-			MKSTR(pfn_to_phys(end_pfn) - 1)),
ada8de
+			MKSTR(end_addr)),
ada8de
 			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
ada8de
 			statebuf),
ada8de
 			mkstring(buf6, 12, LJUST, srangebuf));
ada8de
@@ -17552,14 +17560,14 @@ dump_memory_blocks(int initialize)
ada8de
 			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
ada8de
 			mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
ada8de
 			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
ada8de
-			mkstring(buf6, 12, LJUST, "SECTIONS"));
ada8de
+			mkstring(buf6, 12, LJUST, "START_SECTION_NO"));
ada8de
 	else
ada8de
 		sprintf(mb_hdr, "\n%s %s %s     %s %s\n",
ada8de
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
ada8de
 			mkstring(buf2, 10, CENTER, "NAME"),
ada8de
 			mkstring(buf3, PADDR_PRLEN*2, CENTER, "PHYSICAL RANGE"),
ada8de
 			mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
ada8de
-			mkstring(buf5, 12, LJUST, "SECTIONS"));
ada8de
+			mkstring(buf5, 12, LJUST, "START_SECTION_NO"));
ada8de
 	fprintf(fp, "%s", mb_hdr);
ada8de
 
ada8de
 	for (i = 0; i < klistcnt; i++) {
ada8de
ada8de
commit 1f9e0ac5d0b43004639e304f718177ff4c82343b
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Sat Oct 19 16:43:16 2019 -0400
ada8de
ada8de
    Fix for Linux 4.19.5 and later 4.19-based x86_64 kernels which
ada8de
    are NOT configured with CONFIG_RANDOMIZE_BASE and have backported
ada8de
    kernel commit d52888aa2753e3063a9d3a0c9f72f94aa9809c15, titled
ada8de
    "x86/mm: Move LDT remap out of KASLR region on 5-level paging",
ada8de
    which modified the 4-level and 5-level paging PAGE_OFFSET values.
ada8de
    Without this patch, the crash session fails during initialization
ada8de
    with the error message "crash: seek error: kernel virtual address:
ada8de
    <address> type: "tss_struct ist array".
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/x86_64.c b/x86_64.c
ada8de
index d57b602..c7967bd 100644
ada8de
--- a/x86_64.c
ada8de
+++ b/x86_64.c
ada8de
@@ -382,7 +382,7 @@ x86_64_init(int when)
ada8de
 
ada8de
 	case POST_GDB:
ada8de
 		if (!(machdep->flags & RANDOMIZED) &&
ada8de
-		    ((THIS_KERNEL_VERSION >= LINUX(4,20,0)) || 
ada8de
+		    ((THIS_KERNEL_VERSION >= LINUX(4,19,5)) || 
ada8de
 		    ((THIS_KERNEL_VERSION >= LINUX(4,14,84)) && 
ada8de
 		     (THIS_KERNEL_VERSION < LINUX(4,15,0))))) {
ada8de
 			machdep->machspec->page_offset = machdep->flags & VM_5LEVEL ?
ada8de
ada8de
commit 1d2bc0c65792d15f94ebfd97c22da620b74634fa
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Mon Oct 21 11:46:01 2019 -0400
ada8de
ada8de
    Additional fix for the "kmem -n" option on Linux-5.4-rc1 and later
ada8de
    kernels that contain commit b6c88d3b9d38f9448e0fcf44847a075ea81d5ca2,
ada8de
    titled "drivers/base/memory.c: don't store end_section_nr in memory
ada8de
    blocks".  The initial fix only addressed the x86_64 architecture;
ada8de
    this incremental patch addresses the other architectures.
ada8de
    (msys.mizuma@gmail.com)
ada8de
ada8de
diff --git a/help.c b/help.c
ada8de
index cfd46c3..2b2285b 100644
ada8de
--- a/help.c
ada8de
+++ b/help.c
ada8de
@@ -7177,15 +7177,15 @@ char *help_kmem[] = {
ada8de
 "     6  ffff88003d4d90c0  ffffea0000000000  ffffea0000c00000   PM   196608",
ada8de
 "     7  ffff88003d4d90e0  ffffea0000000000  ffffea0000e00000   PM   229376",
ada8de
 "    ",
ada8de
-"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          START_SECTION_NO",
ada8de
-"     ffff88003a707c00  memory0          0 - 7ffffff  ONLINE         0",
ada8de
-"     ffff88003a6e0000  memory1    8000000 - fffffff  ONLINE         1",
ada8de
-"     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE         2",
ada8de
-"     ffff88003a6e1400  memory3   18000000 - 1fffffff ONLINE         3",
ada8de
-"     ffff88003a6e1800  memory4   20000000 - 27ffffff ONLINE         4",
ada8de
-"     ffff88003a6e0400  memory5   28000000 - 2fffffff ONLINE         5",
ada8de
-"     ffff88003a6e0800  memory6   30000000 - 37ffffff ONLINE         6",
ada8de
-"     ffff88003a6e0c00  memory7   38000000 - 3fffffff ONLINE         7",
ada8de
+"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE   START_SECTION_NO",
ada8de
+"     ffff88003a707c00  memory0          0 -  7ffffff ONLINE  0",
ada8de
+"     ffff88003a6e0000  memory1    8000000 -  fffffff ONLINE  1",
ada8de
+"     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE  2",
ada8de
+"     ffff88003a6e1400  memory3   18000000 - 1fffffff ONLINE  3",
ada8de
+"     ffff88003a6e1800  memory4   20000000 - 27ffffff ONLINE  4",
ada8de
+"     ffff88003a6e0400  memory5   28000000 - 2fffffff ONLINE  5",
ada8de
+"     ffff88003a6e0800  memory6   30000000 - 37ffffff ONLINE  6",
ada8de
+"     ffff88003a6e0c00  memory7   38000000 - 3fffffff ONLINE  7",
ada8de
 
ada8de
 "\n  Translate a page structure's flags field contents:\n",
ada8de
 "    %s> kmem -g 4080",
ada8de
diff --git a/memory.c b/memory.c
ada8de
index 0a79838..f36685b 100644
ada8de
--- a/memory.c
ada8de
+++ b/memory.c
ada8de
@@ -17401,6 +17401,23 @@ fill_memory_block_name(ulong memblock, char *name)
ada8de
 	read_string(value, name, BUFSIZE-1);
ada8de
 }
ada8de
 
ada8de
+static void
ada8de
+fill_memory_block_parange(ulong saddr, ulong eaddr, char *parange)
ada8de
+{
ada8de
+	char buf1[BUFSIZE];
ada8de
+	char buf2[BUFSIZE];
ada8de
+
ada8de
+	memset(parange, 0, sizeof(*parange) * BUFSIZE);
ada8de
+
ada8de
+	if (eaddr == ULLONG_MAX)
ada8de
+		sprintf(parange, "%s",
ada8de
+			mkstring(buf1, PADDR_PRLEN*2 + 3, CENTER|LONG_HEX, MKSTR(saddr)));
ada8de
+	else
ada8de
+		sprintf(parange, "%s - %s",
ada8de
+			mkstring(buf1, PADDR_PRLEN, RJUST|LONG_HEX, MKSTR(saddr)),
ada8de
+			mkstring(buf2, PADDR_PRLEN, RJUST|LONG_HEX, MKSTR(eaddr)));
ada8de
+}
ada8de
+
ada8de
 static void
ada8de
 fill_memory_block_srange(ulong start_sec, char *srange)
ada8de
 {
ada8de
@@ -17413,14 +17430,13 @@ static void
ada8de
 print_memory_block(ulong memory_block)
ada8de
 {
ada8de
 	ulong start_sec, end_sec, nid;
ada8de
-	ulong memblock_size, mbs, start_addr, end_addr;
ada8de
+	ulong memblock_size, mbs, start_addr, end_addr = ULLONG_MAX;
ada8de
 	char statebuf[BUFSIZE];
ada8de
 	char srangebuf[BUFSIZE];
ada8de
+	char parangebuf[BUFSIZE];
ada8de
 	char name[BUFSIZE];
ada8de
 	char buf1[BUFSIZE];
ada8de
 	char buf2[BUFSIZE];
ada8de
-	char buf3[BUFSIZE];
ada8de
-	char buf4[BUFSIZE];
ada8de
 	char buf5[BUFSIZE];
ada8de
 	char buf6[BUFSIZE];
ada8de
 	char buf7[BUFSIZE];
ada8de
@@ -17437,7 +17453,7 @@ print_memory_block(ulong memory_block)
ada8de
 			&mbs, sizeof(ulong), "memory_block_size_probed",
ada8de
 			FAULT_ON_ERROR);
ada8de
 		end_addr = start_addr + mbs - 1;
ada8de
-	} else {
ada8de
+	} else if (MEMBER_EXISTS("memory_block", "end_section_nr")) {
ada8de
 	        readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
ada8de
 			&end_sec, sizeof(void *), "memory_block end_section_nr",
ada8de
 			FAULT_ON_ERROR);
ada8de
@@ -17446,34 +17462,29 @@ print_memory_block(ulong memory_block)
ada8de
 
ada8de
 	fill_memory_block_state(memory_block, statebuf);
ada8de
 	fill_memory_block_name(memory_block, name);
ada8de
+	fill_memory_block_parange(start_addr, end_addr, parangebuf);
ada8de
 	fill_memory_block_srange(start_sec, srangebuf);
ada8de
 
ada8de
 	if (MEMBER_EXISTS("memory_block", "nid")) {
ada8de
 		readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
ada8de
 			sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
ada8de
-		fprintf(fp, " %s %s %s - %s %s %s %s\n",
ada8de
+		fprintf(fp, " %s %s %s %s  %s %s\n",
ada8de
 			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
ada8de
 			MKSTR(memory_block)),
ada8de
 			mkstring(buf2, 12, CENTER, name),
ada8de
-			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
ada8de
-			MKSTR(start_addr)),
ada8de
-			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
ada8de
-			MKSTR(end_addr)),
ada8de
+			parangebuf,
ada8de
 			mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
ada8de
 			MKSTR(nid)),
ada8de
-			mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
ada8de
+			mkstring(buf6, strlen("OFFLINE"), LJUST,
ada8de
 			statebuf),
ada8de
 			mkstring(buf7, 12, LJUST, srangebuf));
ada8de
 	} else
ada8de
-		fprintf(fp, " %s %s %s - %s %s %s\n",
ada8de
+		fprintf(fp, " %s %s %s  %s %s\n",
ada8de
 			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
ada8de
 			MKSTR(memory_block)),
ada8de
 			mkstring(buf2, 10, CENTER, name),
ada8de
-			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
ada8de
-			MKSTR(start_addr)),
ada8de
-			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
ada8de
-			MKSTR(end_addr)),
ada8de
-			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
ada8de
+			parangebuf,
ada8de
+			mkstring(buf5, strlen("OFFLINE"), LJUST,
ada8de
 			statebuf),
ada8de
 			mkstring(buf6, 12, LJUST, srangebuf));
ada8de
 }
ada8de
@@ -17537,6 +17548,7 @@ dump_memory_blocks(int initialize)
ada8de
 	int klistcnt, i;
ada8de
 	struct list_data list_data;
ada8de
 	char mb_hdr[BUFSIZE];
ada8de
+	char paddr_hdr[BUFSIZE];
ada8de
 	char buf1[BUFSIZE];
ada8de
 	char buf2[BUFSIZE];
ada8de
 	char buf3[BUFSIZE];
ada8de
@@ -17553,20 +17565,26 @@ dump_memory_blocks(int initialize)
ada8de
 
ada8de
 	init_memory_block(&list_data, &klistcnt, &klistbuf);
ada8de
 
ada8de
+	if ((symbol_exists("memory_block_size_probed")) ||
ada8de
+	    (MEMBER_EXISTS("memory_block", "end_section_nr")))
ada8de
+		sprintf(paddr_hdr, "%s", "PHYSICAL RANGE");
ada8de
+	else
ada8de
+		sprintf(paddr_hdr, "%s", "PHYSICAL START");
ada8de
+
ada8de
 	if (MEMBER_EXISTS("memory_block", "nid"))
ada8de
-		sprintf(mb_hdr, "\n%s %s %s     %s %s %s\n",
ada8de
+		sprintf(mb_hdr, "\n%s %s   %s   %s  %s %s\n",
ada8de
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
ada8de
 			mkstring(buf2, 10, CENTER, "NAME"),
ada8de
-			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
ada8de
+			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, paddr_hdr),
ada8de
 			mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
ada8de
-			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
ada8de
+			mkstring(buf5, strlen("OFFLINE"), LJUST, "STATE"),
ada8de
 			mkstring(buf6, 12, LJUST, "START_SECTION_NO"));
ada8de
 	else
ada8de
-		sprintf(mb_hdr, "\n%s %s %s     %s %s\n",
ada8de
+		sprintf(mb_hdr, "\n%s %s   %s    %s %s\n",
ada8de
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
ada8de
 			mkstring(buf2, 10, CENTER, "NAME"),
ada8de
-			mkstring(buf3, PADDR_PRLEN*2, CENTER, "PHYSICAL RANGE"),
ada8de
-			mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
ada8de
+			mkstring(buf3, PADDR_PRLEN*2, CENTER, paddr_hdr),
ada8de
+			mkstring(buf4, strlen("OFFLINE"), LJUST, "STATE"),
ada8de
 			mkstring(buf5, 12, LJUST, "START_SECTION_NO"));
ada8de
 	fprintf(fp, "%s", mb_hdr);
ada8de
 
ada8de
ada8de
commit 869f3b24fc3f1dd236b58e1cff86fb4e68da76cf
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Tue Oct 22 16:42:57 2019 -0400
ada8de
ada8de
    In the unlikely event that the panic task in a dumpfile cannot be
ada8de
    determined by the normal means, scan the kernel log buffer for panic
ada8de
    keywords, and if found, generate the panic task from the CPU number
ada8de
    that is specified following the panic message.
ada8de
    (chenqiwu@xiaomi.com)
ada8de
ada8de
diff --git a/task.c b/task.c
ada8de
index 829c794..8dd2b96 100644
ada8de
--- a/task.c
ada8de
+++ b/task.c
ada8de
@@ -48,6 +48,9 @@ static void show_tgid_list(ulong);
ada8de
 static int compare_start_time(const void *, const void *);
ada8de
 static int start_time_timespec(void);
ada8de
 static ulonglong convert_start_time(ulonglong, ulonglong);
ada8de
+static ulong search_panic_task_by_cpu(char *);
ada8de
+static ulong search_panic_task_by_keywords(char *, int *);
ada8de
+static ulong get_log_panic_task(void);
ada8de
 static ulong get_dumpfile_panic_task(void);
ada8de
 static ulong get_active_set_panic_task(void);
ada8de
 static void populate_panic_threads(void);
ada8de
@@ -132,6 +135,23 @@ static struct sched_policy_info {
ada8de
 	{ ULONG_MAX,		NULL }
ada8de
 };
ada8de
 
ada8de
+enum PANIC_TASK_FOUND_RESULT {
ada8de
+	FOUND_NO_PANIC_KEYWORD,
ada8de
+	FOUND_PANIC_KEYWORD,
ada8de
+	FOUND_PANIC_TASK
ada8de
+};
ada8de
+
ada8de
+const char *panic_keywords[] = {
ada8de
+	"Unable to handle kernel",
ada8de
+	"BUG: unable to handle kernel",
ada8de
+	"Kernel BUG at",
ada8de
+	"kernel BUG at",
ada8de
+	"Bad mode in",
ada8de
+	"Oops",
ada8de
+	"Kernel panic",
ada8de
+	NULL,
ada8de
+};
ada8de
+
ada8de
 /*
ada8de
  *  Figure out how much space will be required to hold the task context
ada8de
  *  data, malloc() it, and call refresh_task_table() to fill it up.
ada8de
@@ -6116,8 +6136,8 @@ get_panic_ksp(struct bt_info *bt, ulong *ksp)
ada8de
 
ada8de
 /*
ada8de
  *  Look for kcore's storage information for the system's panic state.
ada8de
- *  If it's not there (somebody else's dump format?), look through all the
ada8de
- *  stack traces for evidence of panic. 
ada8de
+ *  If it's not there (somebody else's dump format?), look through all
ada8de
+ *  the stack traces or the log buffer for evidence of panic.
ada8de
  */
ada8de
 static ulong
ada8de
 get_panic_context(void)
ada8de
@@ -6321,6 +6341,13 @@ get_panicmsg(char *buf)
ada8de
 			break;
ada8de
 		}
ada8de
 	}
ada8de
+	rewind(pc->tmpfile);
ada8de
+	while (!msg_found && fgets(buf, BUFSIZE, pc->tmpfile)) {
ada8de
+		if (strstr(buf, "Bad mode in ")) {
ada8de
+			msg_found = TRUE;
ada8de
+			break;
ada8de
+		}
ada8de
+	}
ada8de
 
ada8de
         close_tmpfile();
ada8de
 
ada8de
@@ -7401,6 +7428,8 @@ panic_search(void)
ada8de
 
ada8de
 	close_tmpfile();
ada8de
 
ada8de
+	pc->curcmd = pc->program_name;
ada8de
+
ada8de
 	if (!found && (dietask > (NO_TASK+1)) && task_has_cpu(dietask, NULL)) {
ada8de
 		lasttask = dietask;
ada8de
 		found = TRUE;
ada8de
@@ -7410,9 +7439,16 @@ panic_search(void)
ada8de
 		error(WARNING, "multiple active tasks have called die\n\n");
ada8de
 
ada8de
 	if (CRASHDEBUG(1) && found)
ada8de
-		error(INFO, "panic_search: %lx (via foreach bt)\n", 
ada8de
+		error(INFO, "panic_search: %lx (via foreach bt)\n",
ada8de
 			lasttask);
ada8de
 
ada8de
+	if (!found) {
ada8de
+		if (CRASHDEBUG(1))
ada8de
+			error(INFO, "panic_search: failed (via foreach bt)\n");
ada8de
+		if ((lasttask = get_log_panic_task()))
ada8de
+			found = TRUE;
ada8de
+	}
ada8de
+
ada8de
 found_panic_task:
ada8de
 	populate_panic_threads();
ada8de
 
ada8de
@@ -7430,11 +7466,114 @@ found_panic_task:
ada8de
 	} 
ada8de
 
ada8de
 	if (CRASHDEBUG(1))
ada8de
-		error(INFO, "panic_search: failed (via foreach bt)\n");
ada8de
+		error(INFO, "panic_search: failed\n");
ada8de
 
ada8de
 	return NULL;
ada8de
 }
ada8de
 
ada8de
+static ulong
ada8de
+search_panic_task_by_cpu(char *buf)
ada8de
+{
ada8de
+	int crashing_cpu;
ada8de
+	char *p1, *p2;
ada8de
+	ulong task = NO_TASK;
ada8de
+
ada8de
+	p1 = NULL;
ada8de
+
ada8de
+	if ((p1 = strstr(buf, "CPU: ")))
ada8de
+		p1 += strlen("CPU: ");
ada8de
+	else if (STRNEQ(buf, "CPU "))
ada8de
+		p1 = buf + strlen("CPU ");
ada8de
+
ada8de
+	if (p1) {
ada8de
+		p2 = p1;
ada8de
+		while (!whitespace(*p2) && (*p2 != '\n'))
ada8de
+			p2++;
ada8de
+		*p2 = NULLCHAR;
ada8de
+		crashing_cpu = dtol(p1, RETURN_ON_ERROR, NULL);
ada8de
+		if ((crashing_cpu >= 0) && in_cpu_map(ONLINE_MAP, crashing_cpu)) {
ada8de
+			task = tt->active_set[crashing_cpu];
ada8de
+			if (CRASHDEBUG(1))
ada8de
+				error(WARNING,
ada8de
+					"get_log_panic_task: active_set[%d]: %lx\n",
ada8de
+					crashing_cpu, tt->active_set[crashing_cpu]);
ada8de
+		}
ada8de
+	}
ada8de
+	return task;
ada8de
+}
ada8de
+
ada8de
+static ulong
ada8de
+search_panic_task_by_keywords(char *buf, int *found_flag)
ada8de
+{
ada8de
+	char *p;
ada8de
+	int i = 0;
ada8de
+	ulong task;
ada8de
+
ada8de
+	while (panic_keywords[i]) {
ada8de
+		if ((p = strstr(buf, panic_keywords[i]))) {
ada8de
+			if ((task = search_panic_task_by_cpu(p))) {
ada8de
+				*found_flag = FOUND_PANIC_TASK;
ada8de
+				return task;
ada8de
+			} else {
ada8de
+				*found_flag = FOUND_PANIC_KEYWORD;
ada8de
+				return NO_TASK;
ada8de
+			}
ada8de
+		}
ada8de
+		i++;
ada8de
+	}
ada8de
+	*found_flag = FOUND_NO_PANIC_KEYWORD;
ada8de
+	return NO_TASK;
ada8de
+}
ada8de
+
ada8de
+/*
ada8de
+ *   Search for the panic task by seeking panic keywords from kernel log buffer.
ada8de
+ *   The panic keyword is generally followed by printing out the stack trace info
ada8de
+ *   of the panicking task.  We can determine the panic task by finding the first
ada8de
+ *   instance of "CPU: " or "CPU " following the panic keywords.
ada8de
+ */
ada8de
+static ulong
ada8de
+get_log_panic_task(void)
ada8de
+{
ada8de
+	int found_flag = FOUND_NO_PANIC_KEYWORD;
ada8de
+	int found_panic_keyword = FALSE;
ada8de
+	ulong task = NO_TASK;
ada8de
+	char buf[BUFSIZE];
ada8de
+
ada8de
+	if (!get_active_set())
ada8de
+		goto fail;
ada8de
+
ada8de
+	BZERO(buf, BUFSIZE);
ada8de
+	open_tmpfile();
ada8de
+	dump_log(SHOW_LOG_TEXT);
ada8de
+	rewind(pc->tmpfile);
ada8de
+	while (fgets(buf, BUFSIZE, pc->tmpfile)) {
ada8de
+		if (!found_panic_keyword) {
ada8de
+			task = search_panic_task_by_keywords(buf, &found_flag);
ada8de
+			switch (found_flag) {
ada8de
+				case FOUND_PANIC_TASK:
ada8de
+					goto found_panic_task;
ada8de
+				case FOUND_PANIC_KEYWORD:
ada8de
+					found_panic_keyword = TRUE;
ada8de
+					continue;
ada8de
+				default:
ada8de
+					continue;
ada8de
+			}
ada8de
+		} else {
ada8de
+			task = search_panic_task_by_cpu(buf);
ada8de
+			if (task)
ada8de
+				goto found_panic_task;
ada8de
+		}
ada8de
+	}
ada8de
+
ada8de
+found_panic_task:
ada8de
+	close_tmpfile();
ada8de
+fail:
ada8de
+	if (CRASHDEBUG(1) && !task)
ada8de
+		 error(WARNING, "cannot determine the panic task from kernel log buffer\n");
ada8de
+
ada8de
+	return task;
ada8de
+}
ada8de
+
ada8de
 /*
ada8de
  *   Get the panic task from the appropriate dumpfile handler.
ada8de
  */
ada8de
ada8de
commit 6a466f8afbb0dcdf4ddc5ef37aec6d343c2636c6
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Mon Nov 4 11:56:28 2019 -0500
ada8de
ada8de
    Adjust a crash-7.1.8 patch for support of /proc/kcore as the live
ada8de
    memory source in Linux 4.8 and later x86_64 kernels configured with
ada8de
    CONFIG_RANDOMIZE_BASE, which randomizes the unity-mapping PAGE_OFFSET
ada8de
    value.  Since the problem only arises before the determination of the
ada8de
    randomized PAGE_OFFSET value, restrict the patch such that it only
ada8de
    takes effect during session initialization.
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/netdump.c b/netdump.c
ada8de
index 55b64e6..fdaecf3 100644
ada8de
--- a/netdump.c
ada8de
+++ b/netdump.c
ada8de
@@ -4269,7 +4269,8 @@ read_proc_kcore(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
ada8de
 		 *  If KASLR, the PAGE_OFFSET may be unknown early on, so try
ada8de
 		 *  the (hopefully) mapped kernel address first.
ada8de
 		 */
ada8de
-		if ((pc->curcmd_flags & MEMTYPE_KVADDR) && (kvaddr != addr)) {
ada8de
+		if (!(pc->flags & RUNTIME) &&
ada8de
+		    (pc->curcmd_flags & MEMTYPE_KVADDR) && (kvaddr != addr)) {
ada8de
 			pc->curcmd_flags &= ~MEMTYPE_KVADDR;
ada8de
 			for (i = 0; i < pkd->segments; i++) {
ada8de
 				lp64 = pkd->load64 + i;
ada8de
ada8de
commit c0bbd8fae4271159aee9e643350781909484c92f
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Fri Nov 8 14:00:56 2019 -0500
ada8de
ada8de
    Add support for extended numbering support in ELF dumpfiles to handle
ada8de
    more than PN_XNUM (0xffff) program headers.  If the real number of
ada8de
    program header table entries is equal to or greater than PN_XNUM, the
ada8de
    e_phnum field of the ELF header is set to PN_XNUM, and the actual
ada8de
    number is set in the sh_info field of the section header at index 0.
ada8de
    (k-hagio@ab.jp.nec.com)
ada8de
ada8de
diff --git a/netdump.c b/netdump.c
ada8de
index fdaecf3..3ced87c 100644
ada8de
--- a/netdump.c
ada8de
+++ b/netdump.c
ada8de
@@ -28,12 +28,13 @@ static struct vmcore_data *nd = &vmcore_data;
ada8de
 static struct proc_kcore_data proc_kcore_data = { 0 };
ada8de
 static struct proc_kcore_data *pkd = &proc_kcore_data;
ada8de
 static void netdump_print(char *, ...);
ada8de
-static size_t resize_elf_header(int, char *, char **, ulong);
ada8de
+static size_t resize_elf_header(int, char *, char **, char **, ulong);
ada8de
 static void dump_Elf32_Ehdr(Elf32_Ehdr *);
ada8de
 static void dump_Elf32_Phdr(Elf32_Phdr *, int);
ada8de
 static size_t dump_Elf32_Nhdr(Elf32_Off offset, int);
ada8de
 static void dump_Elf64_Ehdr(Elf64_Ehdr *);
ada8de
 static void dump_Elf64_Phdr(Elf64_Phdr *, int);
ada8de
+static void dump_Elf64_Shdr(Elf64_Shdr *shdr);
ada8de
 static size_t dump_Elf64_Nhdr(Elf64_Off offset, int);
ada8de
 static void get_netdump_regs_32(struct bt_info *, ulong *, ulong *);
ada8de
 static void get_netdump_regs_ppc(struct bt_info *, ulong *, ulong *);
ada8de
@@ -116,7 +117,7 @@ is_netdump(char *file, ulong source_query)
ada8de
 	Elf32_Phdr *load32;
ada8de
 	Elf64_Ehdr *elf64;
ada8de
 	Elf64_Phdr *load64;
ada8de
-	char *eheader;
ada8de
+	char *eheader, *sect0;
ada8de
 	char buf[BUFSIZE];
ada8de
 	size_t size, len, tot;
ada8de
         Elf32_Off offset32;
ada8de
@@ -330,7 +331,8 @@ is_netdump(char *file, ulong source_query)
ada8de
 			goto bailout;
ada8de
 	}
ada8de
 
ada8de
-	if (!(size = resize_elf_header(fd, file, &eheader, format)))
ada8de
+	sect0 = NULL;
ada8de
+	if (!(size = resize_elf_header(fd, file, &eheader, &sect0, format)))
ada8de
 		goto bailout;
ada8de
 
ada8de
 	nd->ndfd = fd;
ada8de
@@ -372,7 +374,17 @@ is_netdump(char *file, ulong source_query)
ada8de
 	case KDUMP_ELF64:
ada8de
                 nd->header_size = size;
ada8de
                 nd->elf64 = (Elf64_Ehdr *)&nd->elf_header[0];
ada8de
-		nd->num_pt_load_segments = nd->elf64->e_phnum - 1;
ada8de
+
ada8de
+		/*
ada8de
+		 * Extended Numbering support
ada8de
+		 * See include/uapi/linux/elf.h and elf(5) for more information
ada8de
+		 */
ada8de
+		if (nd->elf64->e_phnum == PN_XNUM) {
ada8de
+			nd->sect0_64 = (Elf64_Shdr *)sect0;
ada8de
+			nd->num_pt_load_segments = nd->sect0_64->sh_info - 1;
ada8de
+		} else
ada8de
+			nd->num_pt_load_segments = nd->elf64->e_phnum - 1;
ada8de
+
ada8de
                 if ((nd->pt_load_segments = (struct pt_load_segment *)
ada8de
                     malloc(sizeof(struct pt_load_segment) *
ada8de
                     nd->num_pt_load_segments)) == NULL) {
ada8de
@@ -432,7 +444,8 @@ bailout:
ada8de
  */
ada8de
 
ada8de
 static size_t
ada8de
-resize_elf_header(int fd, char *file, char **eheader_ptr, ulong format)
ada8de
+resize_elf_header(int fd, char *file, char **eheader_ptr, char **sect0_ptr,
ada8de
+		ulong format)
ada8de
 {
ada8de
 	int i;
ada8de
 	char buf[BUFSIZE];
ada8de
@@ -462,7 +475,44 @@ resize_elf_header(int fd, char *file, char **eheader_ptr, ulong format)
ada8de
 
ada8de
 	case NETDUMP_ELF64:
ada8de
 	case KDUMP_ELF64:
ada8de
-		num_pt_load_segments = elf64->e_phnum - 1;
ada8de
+		/*
ada8de
+		 * Extended Numbering support
ada8de
+		 * See include/uapi/linux/elf.h and elf(5) for more information
ada8de
+		 */
ada8de
+		if (elf64->e_phnum == PN_XNUM) {
ada8de
+			Elf64_Shdr *shdr64;
ada8de
+
ada8de
+			shdr64 = (Elf64_Shdr *)malloc(sizeof(*shdr64));
ada8de
+			if (!shdr64) {
ada8de
+				fprintf(stderr,
ada8de
+				    "cannot malloc a section header buffer\n");
ada8de
+				return 0;
ada8de
+			}
ada8de
+			if (FLAT_FORMAT()) {
ada8de
+				if (!read_flattened_format(fd, elf64->e_shoff,
ada8de
+				    shdr64, elf64->e_shentsize))
ada8de
+					return 0;
ada8de
+			} else {
ada8de
+				if (lseek(fd, elf64->e_shoff, SEEK_SET) !=
ada8de
+				    elf64->e_shoff) {
ada8de
+					sprintf(buf, "%s: section header lseek",
ada8de
+						file);
ada8de
+					perror(buf);
ada8de
+					return 0;
ada8de
+				}
ada8de
+				if (read(fd, shdr64, elf64->e_shentsize) !=
ada8de
+				    elf64->e_shentsize) {
ada8de
+					sprintf(buf, "%s: section header read",
ada8de
+						file);
ada8de
+					perror(buf);
ada8de
+					return 0;
ada8de
+				}
ada8de
+			}
ada8de
+			num_pt_load_segments = shdr64->sh_info - 1;
ada8de
+			*sect0_ptr = (char *)shdr64;
ada8de
+		} else
ada8de
+			num_pt_load_segments = elf64->e_phnum - 1;
ada8de
+
ada8de
 		header_size = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) +
ada8de
 			(sizeof(Elf64_Phdr) * num_pt_load_segments);
ada8de
 		break;
ada8de
@@ -1168,6 +1218,7 @@ netdump_memory_dump(FILE *fp)
ada8de
 	netdump_print("                  elf64: %lx\n", nd->elf64);
ada8de
 	netdump_print("                notes64: %lx\n", nd->notes64);
ada8de
 	netdump_print("                 load64: %lx\n", nd->load64);
ada8de
+	netdump_print("               sect0_64: %lx\n", nd->sect0_64);
ada8de
 	netdump_print("            nt_prstatus: %lx\n", nd->nt_prstatus);
ada8de
 	netdump_print("            nt_prpsinfo: %lx\n", nd->nt_prpsinfo);
ada8de
 	netdump_print("          nt_taskstruct: %lx\n", nd->nt_taskstruct);
ada8de
@@ -1252,6 +1303,8 @@ netdump_memory_dump(FILE *fp)
ada8de
 		dump_Elf64_Phdr(nd->notes64, ELFREAD);
ada8de
                 for (i = 0; i < nd->num_pt_load_segments; i++)
ada8de
 			dump_Elf64_Phdr(nd->load64 + i, ELFREAD);
ada8de
+		if (nd->sect0_64)
ada8de
+			dump_Elf64_Shdr(nd->sect0_64);
ada8de
         	offset64 = nd->notes64->p_offset;
ada8de
         	for (tot = 0; tot < nd->notes64->p_filesz; tot += len) {
ada8de
                 	if (!(len = dump_Elf64_Nhdr(offset64, ELFREAD)))
ada8de
@@ -1763,6 +1816,32 @@ dump_Elf64_Phdr(Elf64_Phdr *prog, int store_pt_load_data)
ada8de
 	netdump_print("                p_align: %lld\n", prog->p_align);
ada8de
 }
ada8de
 
ada8de
+static void
ada8de
+dump_Elf64_Shdr(Elf64_Shdr *shdr)
ada8de
+{
ada8de
+	netdump_print("Elf64_Shdr:\n");
ada8de
+	netdump_print("                sh_name: %x\n", shdr->sh_name);
ada8de
+	netdump_print("                sh_type: %x ", shdr->sh_type);
ada8de
+	switch (shdr->sh_type)
ada8de
+	{
ada8de
+	case SHT_NULL:
ada8de
+		netdump_print("(SHT_NULL)\n");
ada8de
+		break;
ada8de
+	default:
ada8de
+		netdump_print("\n");
ada8de
+		break;
ada8de
+	}
ada8de
+	netdump_print("               sh_flags: %lx\n", shdr->sh_flags);
ada8de
+	netdump_print("                sh_addr: %lx\n", shdr->sh_addr);
ada8de
+	netdump_print("              sh_offset: %lx\n", shdr->sh_offset);
ada8de
+	netdump_print("                sh_size: %lx\n", shdr->sh_size);
ada8de
+	netdump_print("                sh_link: %x\n", shdr->sh_link);
ada8de
+	netdump_print("                sh_info: %x (%u)\n", shdr->sh_info,
ada8de
+		shdr->sh_info);
ada8de
+	netdump_print("           sh_addralign: %lx\n", shdr->sh_addralign);
ada8de
+	netdump_print("             sh_entsize: %lx\n", shdr->sh_entsize);
ada8de
+}
ada8de
+
ada8de
 /*
ada8de
  * VMCOREINFO
ada8de
  *
ada8de
diff --git a/netdump.h b/netdump.h
ada8de
index ad1fc77..7fa04f7 100644
ada8de
--- a/netdump.h
ada8de
+++ b/netdump.h
ada8de
@@ -61,6 +61,7 @@ struct vmcore_data {
ada8de
         Elf64_Ehdr *elf64;
ada8de
         Elf64_Phdr *notes64;
ada8de
         Elf64_Phdr *load64;
ada8de
+        Elf64_Shdr *sect0_64;
ada8de
         void *nt_prstatus;
ada8de
         void *nt_prpsinfo;
ada8de
         void *nt_taskstruct;
ada8de
ada8de
commit b5c2359f9f7347a2efa4896fa134dbf128601ca8
ada8de
Author: Dave Anderson <anderson@redhat.com>
ada8de
Date:   Fri Nov 8 14:32:53 2019 -0500
ada8de
ada8de
    Fix for a "warning: large integer implicitly truncated to unsigned
ada8de
    type [-Woverflow]" compiler message generated on 32-bit architectures
ada8de
    as a result of the "Additional fix for the kmem -n option" patch
ada8de
    above.
ada8de
    (anderson@redhat.com)
ada8de
ada8de
diff --git a/memory.c b/memory.c
ada8de
index f36685b..4f7b6a0 100644
ada8de
--- a/memory.c
ada8de
+++ b/memory.c
ada8de
@@ -17430,7 +17430,7 @@ static void
ada8de
 print_memory_block(ulong memory_block)
ada8de
 {
ada8de
 	ulong start_sec, end_sec, nid;
ada8de
-	ulong memblock_size, mbs, start_addr, end_addr = ULLONG_MAX;
ada8de
+	ulong memblock_size, mbs, start_addr, end_addr = (ulong)ULLONG_MAX;
ada8de
 	char statebuf[BUFSIZE];
ada8de
 	char srangebuf[BUFSIZE];
ada8de
 	char parangebuf[BUFSIZE];