[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#986706: marked as done (unblock: makedumpfile/1:1.6.8-4)



Your message dated Sun, 11 Apr 2021 09:48:08 +0000
with message-id <E1lVWhM-0007ZP-JL@respighi.debian.org>
and subject line unblock makedumpfile
has caused the Debian Bug report #986706,
regarding unblock: makedumpfile/1:1.6.8-4
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
986706: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986706
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package makedumpfile

[ Reason ]
Adds necessary fixes for supporting current kernels.

[ Impact ]
makedumpfile will be unable to extract the dmesg from the 5.10 kernel,
and does not support 5.4 and newer kernels on arm64.

[ Tests ]
Forcing a crash dump in an x86 VM and verifying that the dmesg file
is produced and the crash utility is able to analyze the dump.

[ Risks ]
The biggest risk I can think of is that we may have broken support with
some earlier kernel version. But things do work with the kernel version
we're currently planning to release.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
N/A

unblock makedumpfile/1:1.6.8-4
diff -Nru makedumpfile-1.6.8/debian/changelog makedumpfile-1.6.8/debian/changelog
--- makedumpfile-1.6.8/debian/changelog	2021-01-18 07:50:02.000000000 -0700
+++ makedumpfile-1.6.8/debian/changelog	2021-04-07 16:32:38.000000000 -0600
@@ -1,3 +1,13 @@
+makedumpfile (1:1.6.8-4) unstable; urgency=medium
+
+  [ Ioanna Alifieraki ]
+  * Fix failure of dmesg.<timestamp> creation on 5.10+ kernels.
+    (Closes: #985896) (LP: #1921403). 
+  * Fix makedumpfile failure on arm64 with 5.4 kernels.
+    (Closes: #986594) (LP: #1879214)
+
+ -- dann frazier <dannf@debian.org>  Wed, 07 Apr 2021 16:32:38 -0600
+
 makedumpfile (1:1.6.8-3) unstable; urgency=medium
 
   * Drop kdump-tools, which has been split into its own source package.
diff -Nru makedumpfile-1.6.8/debian/patches/0002-PATCH-1-2-printk-add-support-for-lockless-ringbuffer.patch makedumpfile-1.6.8/debian/patches/0002-PATCH-1-2-printk-add-support-for-lockless-ringbuffer.patch
--- makedumpfile-1.6.8/debian/patches/0002-PATCH-1-2-printk-add-support-for-lockless-ringbuffer.patch	1969-12-31 17:00:00.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/0002-PATCH-1-2-printk-add-support-for-lockless-ringbuffer.patch	2021-04-07 16:32:38.000000000 -0600
@@ -0,0 +1,587 @@
+From: John Ogness <john.ogness@linutronix.de>
+Date: Thu, 19 Nov 2020 02:41:21 +0000
+Subject: [PATCH 1/2] printk: add support for lockless ringbuffer
+
+* Required for kernel 5.10
+
+Linux 5.10 introduces a new lockless ringbuffer. The new ringbuffer
+is structured completely different to the previous iterations.
+Add support for retrieving the ringbuffer from debug information
+and/or using vmcoreinfo. The new ringbuffer is detected based on
+the availability of the "prb" symbol.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
+
+Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/c617ec63339222f3a44d73e36677a9acc8954ccd
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=985896
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1921403
+---
+ Makefile       |   2 +-
+ dwarf_info.c   |  36 +++++++++-
+ makedumpfile.c | 103 ++++++++++++++++++++++++++--
+ makedumpfile.h |  58 ++++++++++++++++
+ printk.c       | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 399 insertions(+), 7 deletions(-)
+ create mode 100644 printk.c
+
+diff --git a/Makefile b/Makefile
+index b12bbb0..6f4d0e0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -45,7 +45,7 @@ CFLAGS_ARCH += -m32
+ endif
+ 
+ SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h
+-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c
++SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c
+ OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART))
+ SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c
+ OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
+diff --git a/dwarf_info.c b/dwarf_info.c
+index e42a9f5..543588b 100644
+--- a/dwarf_info.c
++++ b/dwarf_info.c
+@@ -614,6 +614,7 @@ search_structure(Dwarf_Die *die, int *found)
+ {
+ 	int tag;
+ 	const char *name;
++	Dwarf_Die die_type;
+ 
+ 	/*
+ 	 * If we get to here then we don't have any more
+@@ -622,9 +623,31 @@ search_structure(Dwarf_Die *die, int *found)
+ 	do {
+ 		tag  = dwarf_tag(die);
+ 		name = dwarf_diename(die);
+-		if ((tag != DW_TAG_structure_type) || (!name)
+-		    || strcmp(name, dwarf_info.struct_name))
++		if ((!name) || strcmp(name, dwarf_info.struct_name))
++			continue;
++
++		if (tag == DW_TAG_typedef) {
++			if (!get_die_type(die, &die_type)) {
++				ERRMSG("Can't get CU die of DW_AT_type.\n");
++				break;
++			}
++
++			/* Resolve typedefs of typedefs. */
++			while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) {
++				if (!get_die_type(&die_type, &die_type)) {
++					ERRMSG("Can't get CU die of DW_AT_type.\n");
++					return;
++				}
++			}
++
++			if (tag != DW_TAG_structure_type)
++				continue;
++			die = &die_type;
++
++		} else if (tag != DW_TAG_structure_type) {
+ 			continue;
++		}
++
+ 		/*
+ 		 * Skip if DW_AT_byte_size is not included.
+ 		 */
+@@ -740,6 +763,15 @@ search_typedef(Dwarf_Die *die, int *found)
+ 				ERRMSG("Can't get CU die of DW_AT_type.\n");
+ 				break;
+ 			}
++
++			/* Resolve typedefs of typedefs. */
++			while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) {
++				if (!get_die_type(&die_type, &die_type)) {
++					ERRMSG("Can't get CU die of DW_AT_type.\n");
++					return;
++				}
++			}
++
+ 			dwarf_info.struct_size = dwarf_bytesize(&die_type);
+ 			if (dwarf_info.struct_size <= 0)
+ 				continue;
+diff --git a/makedumpfile.c b/makedumpfile.c
+index cdde040..061741f 100644
+--- a/makedumpfile.c
++++ b/makedumpfile.c
+@@ -1555,6 +1555,7 @@ get_symbol_info(void)
+ 	SYMBOL_INIT(node_data, "node_data");
+ 	SYMBOL_INIT(pgdat_list, "pgdat_list");
+ 	SYMBOL_INIT(contig_page_data, "contig_page_data");
++	SYMBOL_INIT(prb, "prb");
+ 	SYMBOL_INIT(log_buf, "log_buf");
+ 	SYMBOL_INIT(log_buf_len, "log_buf_len");
+ 	SYMBOL_INIT(log_end, "log_end");
+@@ -1971,16 +1972,47 @@ get_structure_info(void)
+ 	OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz");
+ 
+ 	SIZE_INIT(printk_log, "printk_log");
+-	if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) {
++	SIZE_INIT(printk_ringbuffer, "printk_ringbuffer");
++	if ((SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE)) {
++		info->flag_use_printk_ringbuffer = TRUE;
++		info->flag_use_printk_log = FALSE;
++
++		OFFSET_INIT(printk_ringbuffer.desc_ring, "printk_ringbuffer", "desc_ring");
++		OFFSET_INIT(printk_ringbuffer.text_data_ring, "printk_ringbuffer", "text_data_ring");
++
++		OFFSET_INIT(prb_desc_ring.count_bits, "prb_desc_ring", "count_bits");
++		OFFSET_INIT(prb_desc_ring.descs, "prb_desc_ring", "descs");
++		OFFSET_INIT(prb_desc_ring.infos, "prb_desc_ring", "infos");
++		OFFSET_INIT(prb_desc_ring.head_id, "prb_desc_ring", "head_id");
++		OFFSET_INIT(prb_desc_ring.tail_id, "prb_desc_ring", "tail_id");
++
++		SIZE_INIT(prb_desc, "prb_desc");
++		OFFSET_INIT(prb_desc.state_var, "prb_desc", "state_var");
++		OFFSET_INIT(prb_desc.text_blk_lpos, "prb_desc", "text_blk_lpos");
++
++		OFFSET_INIT(prb_data_blk_lpos.begin, "prb_data_blk_lpos", "begin");
++		OFFSET_INIT(prb_data_blk_lpos.next, "prb_data_blk_lpos", "next");
++
++		OFFSET_INIT(prb_data_ring.size_bits, "prb_data_ring", "size_bits");
++		OFFSET_INIT(prb_data_ring.data, "prb_data_ring", "data");
++
++		SIZE_INIT(printk_info, "printk_info");
++		OFFSET_INIT(printk_info.ts_nsec, "printk_info", "ts_nsec");
++		OFFSET_INIT(printk_info.text_len, "printk_info", "text_len");
++
++		OFFSET_INIT(atomic_long_t.counter, "atomic_long_t", "counter");
++	} else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) {
+ 		/*
+ 		 * In kernel 3.11-rc4 the log structure name was renamed
+ 		 * to "printk_log".
+ 		 */
++		info->flag_use_printk_ringbuffer = FALSE;
+ 		info->flag_use_printk_log = TRUE;
+ 		OFFSET_INIT(printk_log.ts_nsec, "printk_log", "ts_nsec");
+ 		OFFSET_INIT(printk_log.len, "printk_log", "len");
+ 		OFFSET_INIT(printk_log.text_len, "printk_log", "text_len");
+ 	} else {
++		info->flag_use_printk_ringbuffer = FALSE;
+ 		info->flag_use_printk_log = FALSE;
+ 		SIZE_INIT(printk_log, "log");
+ 		OFFSET_INIT(printk_log.ts_nsec, "log", "ts_nsec");
+@@ -2191,6 +2223,7 @@ write_vmcoreinfo_data(void)
+ 	WRITE_SYMBOL("node_data", node_data);
+ 	WRITE_SYMBOL("pgdat_list", pgdat_list);
+ 	WRITE_SYMBOL("contig_page_data", contig_page_data);
++	WRITE_SYMBOL("prb", prb);
+ 	WRITE_SYMBOL("log_buf", log_buf);
+ 	WRITE_SYMBOL("log_buf_len", log_buf_len);
+ 	WRITE_SYMBOL("log_end", log_end);
+@@ -2222,7 +2255,11 @@ write_vmcoreinfo_data(void)
+ 	WRITE_STRUCTURE_SIZE("node_memblk_s", node_memblk_s);
+ 	WRITE_STRUCTURE_SIZE("nodemask_t", nodemask_t);
+ 	WRITE_STRUCTURE_SIZE("pageflags", pageflags);
+-	if (info->flag_use_printk_log)
++	if (info->flag_use_printk_ringbuffer) {
++		WRITE_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer);
++		WRITE_STRUCTURE_SIZE("prb_desc", prb_desc);
++		WRITE_STRUCTURE_SIZE("printk_info", printk_info);
++	} else if (info->flag_use_printk_log)
+ 		WRITE_STRUCTURE_SIZE("printk_log", printk_log);
+ 	else
+ 		WRITE_STRUCTURE_SIZE("log", printk_log);
+@@ -2268,7 +2305,30 @@ write_vmcoreinfo_data(void)
+ 	WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr);
+ 	WRITE_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start);
+ 	WRITE_MEMBER_OFFSET("vmap_area.list", vmap_area.list);
+-	if (info->flag_use_printk_log) {
++	if (info->flag_use_printk_ringbuffer) {
++		WRITE_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring);
++		WRITE_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring);
++
++		WRITE_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits);
++		WRITE_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs);
++		WRITE_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos);
++		WRITE_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id);
++		WRITE_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id);
++
++		WRITE_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var);
++		WRITE_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos);
++
++		WRITE_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin);
++		WRITE_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next);
++
++		WRITE_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits);
++		WRITE_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data);
++
++		WRITE_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec);
++		WRITE_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len);
++
++		WRITE_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter);
++	} else if (info->flag_use_printk_log) {
+ 		WRITE_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec);
+ 		WRITE_MEMBER_OFFSET("printk_log.len", printk_log.len);
+ 		WRITE_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len);
+@@ -2606,6 +2666,7 @@ read_vmcoreinfo(void)
+ 	READ_SYMBOL("node_data", node_data);
+ 	READ_SYMBOL("pgdat_list", pgdat_list);
+ 	READ_SYMBOL("contig_page_data", contig_page_data);
++	READ_SYMBOL("prb", prb);
+ 	READ_SYMBOL("log_buf", log_buf);
+ 	READ_SYMBOL("log_buf_len", log_buf_len);
+ 	READ_SYMBOL("log_end", log_end);
+@@ -2684,12 +2745,43 @@ read_vmcoreinfo(void)
+ 	READ_MEMBER_OFFSET("cpu_spec.mmu_features", cpu_spec.mmu_features);
+ 
+ 	READ_STRUCTURE_SIZE("printk_log", printk_log);
+-	if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) {
++	READ_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer);
++	if (SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE) {
++		info->flag_use_printk_ringbuffer = TRUE;
++		info->flag_use_printk_log = FALSE;
++
++		READ_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring);
++		READ_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring);
++
++		READ_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits);
++		READ_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs);
++		READ_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos);
++		READ_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id);
++		READ_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id);
++
++		READ_STRUCTURE_SIZE("prb_desc", prb_desc);
++		READ_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var);
++		READ_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos);
++
++		READ_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin);
++		READ_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next);
++
++		READ_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits);
++		READ_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data);
++
++		READ_STRUCTURE_SIZE("printk_info", printk_info);
++		READ_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec);
++		READ_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len);
++
++		READ_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter);
++	} else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) {
++		info->flag_use_printk_ringbuffer = FALSE;
+ 		info->flag_use_printk_log = TRUE;
+ 		READ_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec);
+ 		READ_MEMBER_OFFSET("printk_log.len", printk_log.len);
+ 		READ_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len);
+ 	} else {
++		info->flag_use_printk_ringbuffer = FALSE;
+ 		info->flag_use_printk_log = FALSE;
+ 		READ_STRUCTURE_SIZE("log", printk_log);
+ 		READ_MEMBER_OFFSET("log.ts_nsec", printk_log.ts_nsec);
+@@ -5286,6 +5378,9 @@ dump_dmesg()
+ 	if (!initial())
+ 		return FALSE;
+ 
++	if ((SYMBOL(prb) != NOT_FOUND_SYMBOL))
++		return dump_lockless_dmesg();
++
+ 	if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL)
+ 	    || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL)) {
+ 		ERRMSG("Can't find some symbols for log_buf.\n");
+diff --git a/makedumpfile.h b/makedumpfile.h
+index 698c054..47f7e79 100644
+--- a/makedumpfile.h
++++ b/makedumpfile.h
+@@ -1317,6 +1317,7 @@ struct DumpInfo {
+ 	int             flag_partial_dmesg;  /* dmesg dump only from the last cleared index*/
+ 	int             flag_mem_usage;  /*show the page number of memory in different use*/
+ 	int		flag_use_printk_log; /* did we read printk_log symbol name? */
++	int		flag_use_printk_ringbuffer; /* using lockless printk ringbuffer? */
+ 	int		flag_nospace;	     /* the flag of "No space on device" error */
+ 	int		flag_vmemmap;        /* kernel supports vmemmap address space */
+ 	int		flag_excludevm;      /* -e - excluding unused vmemmap pages */
+@@ -1602,6 +1603,7 @@ struct symbol_table {
+ 	unsigned long long	node_data;
+ 	unsigned long long	pgdat_list;
+ 	unsigned long long	contig_page_data;
++	unsigned long long	prb;
+ 	unsigned long long	log_buf;
+ 	unsigned long long	log_buf_len;
+ 	unsigned long long	log_end;
+@@ -1689,6 +1691,13 @@ struct size_table {
+ 	long	nodemask_t;
+ 	long	printk_log;
+ 
++	/*
++	 * for lockless printk ringbuffer
++	 */
++	long	printk_ringbuffer;
++	long	prb_desc;
++	long	printk_info;
++
+ 	/*
+ 	 * for Xen extraction
+ 	 */
+@@ -1864,6 +1873,52 @@ struct offset_table {
+ 		long text_len;
+ 	} printk_log;
+ 
++	/*
++	 * for lockless printk ringbuffer
++	 */
++	struct printk_ringbuffer_s {
++		long desc_ring;
++		long text_data_ring;
++		long fail;
++	} printk_ringbuffer;
++
++	struct prb_desc_ring_s {
++		long count_bits;
++		long descs;
++		long infos;
++		long head_id;
++		long tail_id;
++	} prb_desc_ring;
++
++	struct prb_desc_s {
++		long state_var;
++		long text_blk_lpos;
++	} prb_desc;
++
++	struct prb_data_blk_lpos_s {
++		long begin;
++		long next;
++	} prb_data_blk_lpos;
++
++	struct printk_info_s {
++		long seq;
++		long ts_nsec;
++		long text_len;
++		long caller_id;
++		long dev_info;
++	} printk_info;
++
++	struct prb_data_ring_s {
++		long size_bits;
++		long data;
++		long head_lpos;
++		long tail_lpos;
++	} prb_data_ring;
++
++	struct atomic_long_t_s {
++		long counter;
++	} atomic_long_t;
++
+ 	/*
+ 	 * symbols on ppc64 arch
+ 	 */
+@@ -2390,4 +2445,7 @@ int hexadecimal(char *s, int count);
+ int decimal(char *s, int count);
+ int file_exists(char *file);
+ 
++int open_dump_file(void);
++int dump_lockless_dmesg(void);
++
+ #endif /* MAKEDUMPFILE_H */
+diff --git a/printk.c b/printk.c
+new file mode 100644
+index 0000000..acffb6c
+--- /dev/null
++++ b/printk.c
+@@ -0,0 +1,207 @@
++#include "makedumpfile.h"
++#include <ctype.h>
++
++#define DESC_SV_BITS		(sizeof(unsigned long) * 8)
++#define DESC_COMMITTED_MASK	(1UL << (DESC_SV_BITS - 1))
++#define DESC_REUSE_MASK		(1UL << (DESC_SV_BITS - 2))
++#define DESC_FLAGS_MASK		(DESC_COMMITTED_MASK | DESC_REUSE_MASK)
++#define DESC_ID_MASK		(~DESC_FLAGS_MASK)
++
++/* convenience struct for passing many values to helper functions */
++struct prb_map {
++	char		*prb;
++
++	char		*desc_ring;
++	unsigned long	desc_ring_count;
++	char		*descs;
++	char		*infos;
++
++	char		*text_data_ring;
++	unsigned long	text_data_ring_size;
++	char		*text_data;
++};
++
++static void
++dump_record(struct prb_map *m, unsigned long id)
++{
++	unsigned long long ts_nsec;
++	unsigned long state_var;
++	unsigned short text_len;
++	unsigned long begin;
++	unsigned long next;
++	char buf[BUFSIZE];
++	ulonglong nanos;
++	int indent_len;
++	int buf_need;
++	char *bufp;
++	char *text;
++	char *desc;
++	char *inf;
++	ulong rem;
++	char *p;
++	int i;
++
++	desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc));
++
++	/* skip non-committed record */
++	state_var = ULONG(desc + OFFSET(prb_desc.state_var) + OFFSET(atomic_long_t.counter));
++	if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
++		return;
++
++	begin = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.begin)) %
++			m->text_data_ring_size;
++	next = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.next)) %
++			m->text_data_ring_size;
++
++	/* skip data-less text blocks */
++	if (begin == next)
++		return;
++
++	inf = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
++
++	text_len = USHORT(inf + OFFSET(printk_info.text_len));
++
++	/* handle wrapping data block */
++	if (begin > next)
++		begin = 0;
++
++	/* skip over descriptor ID */
++	begin += sizeof(unsigned long);
++
++	/* handle truncated messages */
++	if (next - begin < text_len)
++		text_len = next - begin;
++
++	text = m->text_data + begin;
++
++	ts_nsec = ULONGLONG(inf + OFFSET(printk_info.ts_nsec));
++	nanos = (ulonglong)ts_nsec / (ulonglong)1000000000;
++	rem = (ulonglong)ts_nsec % (ulonglong)1000000000;
++
++	bufp = buf;
++	bufp += sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000);
++	indent_len = strlen(buf);
++
++	/* How much buffer space is needed in the worst case */
++	buf_need = MAX(sizeof("\\xXX\n"), sizeof("\n") + indent_len);
++
++	for (i = 0, p = text; i < text_len; i++, p++) {
++		if (bufp - buf >= sizeof(buf) - buf_need) {
++			if (write(info->fd_dumpfile, buf, bufp - buf) < 0)
++				return;
++			bufp = buf;
++		}
++
++		if (*p == '\n')
++			bufp += sprintf(bufp, "\n%-*s", indent_len, "");
++		else if (isprint(*p) || isspace(*p))
++			*bufp++ = *p;
++		else
++			bufp += sprintf(bufp, "\\x%02x", *p);
++	}
++
++	*bufp++ = '\n';
++
++	write(info->fd_dumpfile, buf, bufp - buf);
++}
++
++int
++dump_lockless_dmesg(void)
++{
++	unsigned long head_id;
++	unsigned long tail_id;
++	unsigned long kaddr;
++	unsigned long id;
++	struct prb_map m;
++	int ret = FALSE;
++
++	/* setup printk_ringbuffer */
++	if (!readmem(VADDR, SYMBOL(prb), &kaddr, sizeof(kaddr))) {
++		ERRMSG("Can't get the prb address.\n");
++		return ret;
++	}
++
++	m.prb = malloc(SIZE(printk_ringbuffer));
++	if (!m.prb) {
++		ERRMSG("Can't allocate memory for prb.\n");
++		return ret;
++	}
++	if (!readmem(VADDR, kaddr, m.prb, SIZE(printk_ringbuffer))) {
++		ERRMSG("Can't get prb.\n");
++		goto out_prb;
++	}
++
++	/* setup descriptor ring */
++	m.desc_ring = m.prb + OFFSET(printk_ringbuffer.desc_ring);
++	m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring.count_bits));
++
++	kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.descs));
++	m.descs = malloc(SIZE(prb_desc) * m.desc_ring_count);
++	if (!m.descs) {
++		ERRMSG("Can't allocate memory for prb.desc_ring.descs.\n");
++		goto out_prb;
++	}
++	if (!readmem(VADDR, kaddr, m.descs,
++		     SIZE(prb_desc) * m.desc_ring_count)) {
++		ERRMSG("Can't get prb.desc_ring.descs.\n");
++		goto out_descs;
++	}
++
++	kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.infos));
++	m.infos = malloc(SIZE(printk_info) * m.desc_ring_count);
++	if (!m.infos) {
++		ERRMSG("Can't allocate memory for prb.desc_ring.infos.\n");
++		goto out_descs;
++	}
++	if (!readmem(VADDR, kaddr, m.infos, SIZE(printk_info) * m.desc_ring_count)) {
++		ERRMSG("Can't get prb.desc_ring.infos.\n");
++		goto out_infos;
++	}
++
++	/* setup text data ring */
++	m.text_data_ring = m.prb + OFFSET(printk_ringbuffer.text_data_ring);
++	m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring.size_bits));
++
++	kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring.data));
++	m.text_data = malloc(m.text_data_ring_size);
++	if (!m.text_data) {
++		ERRMSG("Can't allocate memory for prb.text_data_ring.data.\n");
++		goto out_infos;
++	}
++	if (!readmem(VADDR, kaddr, m.text_data, m.text_data_ring_size)) {
++		ERRMSG("Can't get prb.text_data_ring.\n");
++		goto out_text_data;
++	}
++
++	/* ready to go */
++
++	tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.tail_id) +
++			OFFSET(atomic_long_t.counter));
++	head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.head_id) +
++			OFFSET(atomic_long_t.counter));
++
++	if (!open_dump_file()) {
++		ERRMSG("Can't open output file.\n");
++		goto out_text_data;
++	}
++
++	for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK)
++		dump_record(&m, id);
++
++	/* dump head record */
++	dump_record(&m, id);
++
++	if (!close_files_for_creating_dumpfile())
++		goto out_text_data;
++
++	ret = TRUE;
++out_text_data:
++	free(m.text_data);
++out_infos:
++	free(m.infos);
++out_descs:
++	free(m.descs);
++out_prb:
++	free(m.prb);
++	return ret;
++}
diff -Nru makedumpfile-1.6.8/debian/patches/0003-PATCH-2-2-printk-use-committed-finalized-state-value.patch makedumpfile-1.6.8/debian/patches/0003-PATCH-2-2-printk-use-committed-finalized-state-value.patch
--- makedumpfile-1.6.8/debian/patches/0003-PATCH-2-2-printk-use-committed-finalized-state-value.patch	1969-12-31 17:00:00.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/0003-PATCH-2-2-printk-use-committed-finalized-state-value.patch	2021-04-07 16:32:38.000000000 -0600
@@ -0,0 +1,99 @@
+From: John Ogness <john.ogness@linutronix.de>
+Date: Wed, 25 Nov 2020 10:10:31 +0106
+Subject: [PATCH 2/2] printk: use committed/finalized state values
+
+* Required for kernel 5.10
+
+The ringbuffer entries use 2 state values (committed and finalized)
+rather than a single flag to represent being available for reading.
+Copy the definitions and state lookup function directly from the
+kernel source and use the new states.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+
+Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/44b073b7ec467aee0d7de381d455b8ace1199184
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=985896
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1921403
+---
+ printk.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 41 insertions(+), 7 deletions(-)
+
+diff --git a/printk.c b/printk.c
+index acffb6c..2af8562 100644
+--- a/printk.c
++++ b/printk.c
+@@ -1,12 +1,6 @@
+ #include "makedumpfile.h"
+ #include <ctype.h>
+ 
+-#define DESC_SV_BITS		(sizeof(unsigned long) * 8)
+-#define DESC_COMMITTED_MASK	(1UL << (DESC_SV_BITS - 1))
+-#define DESC_REUSE_MASK		(1UL << (DESC_SV_BITS - 2))
+-#define DESC_FLAGS_MASK		(DESC_COMMITTED_MASK | DESC_REUSE_MASK)
+-#define DESC_ID_MASK		(~DESC_FLAGS_MASK)
+-
+ /* convenience struct for passing many values to helper functions */
+ struct prb_map {
+ 	char		*prb;
+@@ -21,12 +15,51 @@ struct prb_map {
+ 	char		*text_data;
+ };
+ 
++/*
++ * desc_state and DESC_* definitions taken from kernel source:
++ *
++ * kernel/printk/printk_ringbuffer.h
++ */
++
++/* The possible responses of a descriptor state-query. */
++enum desc_state {
++	desc_miss	=  -1,	/* ID mismatch (pseudo state) */
++	desc_reserved	= 0x0,	/* reserved, in use by writer */
++	desc_committed	= 0x1,	/* committed by writer, could get reopened */
++	desc_finalized	= 0x2,	/* committed, no further modification allowed */
++	desc_reusable	= 0x3,	/* free, not yet used by any writer */
++};
++
++#define DESC_SV_BITS		(sizeof(unsigned long) * 8)
++#define DESC_FLAGS_SHIFT	(DESC_SV_BITS - 2)
++#define DESC_FLAGS_MASK		(3UL << DESC_FLAGS_SHIFT)
++#define DESC_STATE(sv)		(3UL & (sv >> DESC_FLAGS_SHIFT))
++#define DESC_ID_MASK		(~DESC_FLAGS_MASK)
++#define DESC_ID(sv)		((sv) & DESC_ID_MASK)
++
++/*
++ * get_desc_state() taken from kernel source:
++ *
++ * kernel/printk/printk_ringbuffer.c
++ */
++
++/* Query the state of a descriptor. */
++static enum desc_state get_desc_state(unsigned long id,
++				      unsigned long state_val)
++{
++	if (id != DESC_ID(state_val))
++		return desc_miss;
++
++	return DESC_STATE(state_val);
++}
++
+ static void
+ dump_record(struct prb_map *m, unsigned long id)
+ {
+ 	unsigned long long ts_nsec;
+ 	unsigned long state_var;
+ 	unsigned short text_len;
++	enum desc_state state;
+ 	unsigned long begin;
+ 	unsigned long next;
+ 	char buf[BUFSIZE];
+@@ -45,7 +78,8 @@ dump_record(struct prb_map *m, unsigned long id)
+ 
+ 	/* skip non-committed record */
+ 	state_var = ULONG(desc + OFFSET(prb_desc.state_var) + OFFSET(atomic_long_t.counter));
+-	if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
++	state = get_desc_state(id, state_var);
++	if (state != desc_committed && state != desc_finalized)
+ 		return;
+ 
+ 	begin = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.begin)) %
diff -Nru makedumpfile-1.6.8/debian/patches/0004-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch makedumpfile-1.6.8/debian/patches/0004-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch
--- makedumpfile-1.6.8/debian/patches/0004-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch	1969-12-31 17:00:00.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/0004-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch	2021-04-07 16:32:38.000000000 -0600
@@ -0,0 +1,146 @@
+From: Kazuhito Hagio <k-hagio-ab@nec.com>
+Date: Fri, 29 Jan 2021 11:40:23 +0900
+Subject: [PATCH 1/3] Use vmcoreinfo note in /proc/kcore for --mem-usage
+ option
+
+kernel commit 23c85094fe18 added vmcoreinfo note to /proc/kcore.
+Use the vmcoreinfo note to get necessary information, especially
+page_offset and phys_base on arm64, for the --mem-usage option.
+
+Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
+
+Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/d8b701796f0491f2ac4b06c7a5b795c29399efab
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214
+---
+ elf_info.c     | 49 -------------------------------------------------
+ elf_info.h     |  1 -
+ makedumpfile.c | 26 +++++++++++++++++++++-----
+ 3 files changed, 21 insertions(+), 55 deletions(-)
+
+diff --git a/elf_info.c b/elf_info.c
+index a6624b5..e8affb7 100644
+--- a/elf_info.c
++++ b/elf_info.c
+@@ -698,55 +698,6 @@ get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr)
+ 	return TRUE;
+ }
+ 
+-int
+-get_elf_loads(int fd, char *filename)
+-{
+-	int i, j, phnum, elf_format;
+-	Elf64_Phdr phdr;
+-
+-	/*
+-	 * Check ELF64 or ELF32.
+-	 */
+-	elf_format = check_elf_format(fd, filename, &phnum, &num_pt_loads);
+-	if (elf_format == ELF64)
+-		flags_memory |= MEMORY_ELF64;
+-	else if (elf_format != ELF32)
+-		return FALSE;
+-
+-	if (!num_pt_loads) {
+-		ERRMSG("Can't get the number of PT_LOAD.\n");
+-		return FALSE;
+-	}
+-
+-	/*
+-	 * The below file information will be used as /proc/vmcore.
+-	 */
+-	fd_memory   = fd;
+-	name_memory = filename;
+-
+-	pt_loads = calloc(sizeof(struct pt_load_segment), num_pt_loads);
+-	if (pt_loads == NULL) {
+-		ERRMSG("Can't allocate memory for the PT_LOAD. %s\n",
+-		    strerror(errno));
+-		return FALSE;
+-	}
+-	for (i = 0, j = 0; i < phnum; i++) {
+-		if (!get_phdr_memory(i, &phdr))
+-			return FALSE;
+-
+-		if (phdr.p_type != PT_LOAD)
+-			continue;
+-
+-		if (j >= num_pt_loads)
+-			return FALSE;
+-		if (!dump_Elf_load(&phdr, j))
+-			return FALSE;
+-		j++;
+-	}
+-
+-	return TRUE;
+-}
+-
+ static int exclude_segment(struct pt_load_segment **pt_loads,
+ 			   unsigned int	*num_pt_loads, uint64_t start, uint64_t end)
+ {
+diff --git a/elf_info.h b/elf_info.h
+index d9b5d05..d5416b3 100644
+--- a/elf_info.h
++++ b/elf_info.h
+@@ -44,7 +44,6 @@ int get_elf64_ehdr(int fd, char *filename, Elf64_Ehdr *ehdr);
+ int get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr);
+ int get_elf_info(int fd, char *filename);
+ void free_elf_info(void);
+-int get_elf_loads(int fd, char *filename);
+ int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len);
+ int get_kcore_dump_loads(void);
+ 
+diff --git a/makedumpfile.c b/makedumpfile.c
+index 061741f..949b7e4 100644
+--- a/makedumpfile.c
++++ b/makedumpfile.c
+@@ -11413,6 +11413,7 @@ int show_mem_usage(void)
+ {
+ 	uint64_t vmcoreinfo_addr, vmcoreinfo_len;
+ 	struct cycle cycle = {0};
++	int vmcoreinfo = FALSE;
+ 
+ 	if (!is_crashkernel_mem_reserved()) {
+ 		ERRMSG("No memory is reserved for crashkernel!\n");
+@@ -11424,9 +11425,22 @@ int show_mem_usage(void)
+ 	if (!open_files_for_creating_dumpfile())
+ 		return FALSE;
+ 
+-	if (!get_elf_loads(info->fd_memory, info->name_memory))
++	if (!get_elf_info(info->fd_memory, info->name_memory))
+ 		return FALSE;
+ 
++	/*
++	 * /proc/kcore on Linux 4.19 and later kernels have vmcoreinfo note in
++	 * NOTE segment.  See commit 23c85094fe18.
++	 */
++	if (has_vmcoreinfo()) {
++		off_t offset;
++		unsigned long size;
++
++		get_vmcoreinfo(&offset, &size);
++		vmcoreinfo = read_vmcoreinfo_from_vmcore(offset, size, FALSE);
++		DEBUG_MSG("Read vmcoreinfo from NOTE segment: %d\n", vmcoreinfo);
++	}
++
+ 	if (!get_page_offset())
+ 		return FALSE;
+ 
+@@ -11434,11 +11448,13 @@ int show_mem_usage(void)
+ 	if (!get_phys_base())
+ 		return FALSE;
+ 
+-	if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
+-		return FALSE;
++	if (!vmcoreinfo) {
++		if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
++			return FALSE;
+ 
+-	if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len))
+-		return FALSE;
++		if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len))
++			return FALSE;
++	}
+ 
+ 	if (!initial())
+ 		return FALSE;
diff -Nru makedumpfile-1.6.8/debian/patches/0005-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch makedumpfile-1.6.8/debian/patches/0005-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch
--- makedumpfile-1.6.8/debian/patches/0005-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch	1969-12-31 17:00:00.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/0005-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch	2021-04-07 16:32:38.000000000 -0600
@@ -0,0 +1,100 @@
+From: Kazuhito Hagio <k-hagio-ab@nec.com>
+Date: Fri, 29 Jan 2021 11:40:24 +0900
+Subject: [PATCH 2/3] arm64: Make use of NUMBER(VA_BITS) in vmcoreinfo
+
+Make use of the NUMBER(VA_BITS) in vmcoreinfo, which was added by
+kernel commit 20a166243328 (Linux 4.12 and later kernels), as the
+current way of guessing VA_BITS does not work on Linux 5.4 and
+later kernels.
+
+Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
+Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
+
+Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/67d0e1d68f28c567a704fd6b9b8fd696ad3df183
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214
+---
+ arch/arm64.c | 63 ++++++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 42 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm64.c b/arch/arm64.c
+index 3d7b416..2916b4f 100644
+--- a/arch/arm64.c
++++ b/arch/arm64.c
+@@ -345,6 +345,43 @@ get_stext_symbol(void)
+ 	return(found ? kallsym : FALSE);
+ }
+ 
++static int
++get_va_bits_from_stext_arm64(void)
++{
++	ulong _stext;
++
++	_stext = get_stext_symbol();
++	if (!_stext) {
++		ERRMSG("Can't get the symbol of _stext.\n");
++		return FALSE;
++	}
++
++	/*
++	 * Derive va_bits as per arch/arm64/Kconfig. Note that this is a
++	 * best case approximation at the moment, as there can be
++	 * inconsistencies in this calculation (for e.g., for 52-bit
++	 * kernel VA case, the 48th bit is set in * the _stext symbol).
++	 */
++	if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
++		va_bits = 48;
++	} else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
++		va_bits = 47;
++	} else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
++		va_bits = 42;
++	} else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
++		va_bits = 39;
++	} else if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
++		va_bits = 36;
++	} else {
++		ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
++		return FALSE;
++	}
++
++	DEBUG_MSG("va_bits       : %d (guess from _stext)\n", va_bits);
++
++	return TRUE;
++}
++
+ int
+ get_machdep_info_arm64(void)
+ {
+@@ -398,27 +435,11 @@ get_xen_info_arm64(void)
+ int
+ get_versiondep_info_arm64(void)
+ {
+-	ulong _stext;
+-
+-	_stext = get_stext_symbol();
+-	if (!_stext) {
+-		ERRMSG("Can't get the symbol of _stext.\n");
+-		return FALSE;
+-	}
+-
+-	/* Derive va_bits as per arch/arm64/Kconfig */
+-	if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
+-		va_bits = 36;
+-	} else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
+-		va_bits = 39;
+-	} else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
+-		va_bits = 42;
+-	} else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
+-		va_bits = 47;
+-	} else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
+-		va_bits = 48;
+-	} else {
+-		ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
++	if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) {
++		va_bits = NUMBER(VA_BITS);
++		DEBUG_MSG("va_bits      : %d (vmcoreinfo)\n", va_bits);
++	} else if (get_va_bits_from_stext_arm64() == FALSE) {
++		ERRMSG("Can't determine va_bits.\n");
+ 		return FALSE;
+ 	}
+ 
diff -Nru makedumpfile-1.6.8/debian/patches/0006-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch makedumpfile-1.6.8/debian/patches/0006-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch
--- makedumpfile-1.6.8/debian/patches/0006-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch	1969-12-31 17:00:00.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/0006-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch	2021-04-07 16:32:38.000000000 -0600
@@ -0,0 +1,244 @@
+From: Kazuhito Hagio <k-hagio-ab@nec.com>
+Date: Fri, 29 Jan 2021 11:40:25 +0900
+Subject: [PATCH 3/3] arm64: support flipped VA and 52-bit kernel VA
+
+Linux 5.4 and later kernels for arm64 changed the kernel VA space
+arrangement and introduced 52-bit kernel VAs by merging branch
+commit b333b0ba2346.  Support 5.9+ kernels with vmcoreinfo entries
+and 5.4+ kernels with best guessing.
+
+However, the following conditions are not supported for now due to
+no necessary information provided from kernel:
+(1) 5.4 <= kernels <= 5.8 and
+    - if PA_BITS=52 && VA_BITS!=52
+    - with -x option if vabits_actual=52
+(2) kernels < 5.4 with CONFIG_ARM64_USER_VA_BITS_52=y
+
+(1) should be supported with kernel commit bbdbc11804ff and
+1d50e5d0c5052 adding necessary information to vmcoreinfo.
+
+Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
+Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
+Reviewed-by: Pingfan Liu <piliu@redhat.com>
+
+Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/a0216b678a95f099a16172cc4a67ad5aa6a89583
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214
+---
+ arch/arm64.c   | 100 ++++++++++++++++++++++++++++++++++++++++++++++++---------
+ makedumpfile.c |   2 ++
+ makedumpfile.h |   1 +
+ 3 files changed, 88 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm64.c b/arch/arm64.c
+index 2916b4f..1072178 100644
+--- a/arch/arm64.c
++++ b/arch/arm64.c
+@@ -47,6 +47,8 @@ typedef struct {
+ static int lpa_52_bit_support_available;
+ static int pgtable_level;
+ static int va_bits;
++static int vabits_actual;
++static int flipped_va;
+ static unsigned long kimage_voffset;
+ 
+ #define SZ_4K			4096
+@@ -58,7 +60,6 @@ static unsigned long kimage_voffset;
+ #define PAGE_OFFSET_42		((0xffffffffffffffffUL) << 42)
+ #define PAGE_OFFSET_47		((0xffffffffffffffffUL) << 47)
+ #define PAGE_OFFSET_48		((0xffffffffffffffffUL) << 48)
+-#define PAGE_OFFSET_52		((0xffffffffffffffffUL) << 52)
+ 
+ #define pgd_val(x)		((x).pgd)
+ #define pud_val(x)		(pgd_val((x).pgd))
+@@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd)
+ #define pte_index(vaddr)		(((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
+ #define pte_offset(dir, vaddr)		(pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t))
+ 
++/*
++ * The linear kernel range starts at the bottom of the virtual address
++ * space. Testing the top bit for the start of the region is a
++ * sufficient check and avoids having to worry about the tag.
++ */
++#define is_linear_addr(addr)	(flipped_va ?	\
++	(!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \
++	(!!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))))
++
+ static unsigned long long
+ __pa(unsigned long vaddr)
+ {
+-	if (kimage_voffset == NOT_FOUND_NUMBER ||
+-			(vaddr >= PAGE_OFFSET))
+-		return (vaddr - PAGE_OFFSET + info->phys_base);
++	if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr))
++		return ((vaddr & ~PAGE_OFFSET) + info->phys_base);
+ 	else
+ 		return (vaddr - kimage_voffset);
+ }
+@@ -253,6 +262,7 @@ static int calculate_plat_config(void)
+ 			(PAGESIZE() == SZ_64K && va_bits == 42)) {
+ 		pgtable_level = 2;
+ 	} else if ((PAGESIZE() == SZ_64K && va_bits == 48) ||
++			(PAGESIZE() == SZ_64K && va_bits == 52) ||
+ 			(PAGESIZE() == SZ_4K && va_bits == 39) ||
+ 			(PAGESIZE() == SZ_16K && va_bits == 47)) {
+ 		pgtable_level = 3;
+@@ -263,6 +273,7 @@ static int calculate_plat_config(void)
+ 				PAGESIZE(), va_bits);
+ 		return FALSE;
+ 	}
++	DEBUG_MSG("pgtable_level: %d\n", pgtable_level);
+ 
+ 	return TRUE;
+ }
+@@ -270,6 +281,9 @@ static int calculate_plat_config(void)
+ unsigned long
+ get_kvbase_arm64(void)
+ {
++	if (flipped_va)
++		return PAGE_OFFSET;
++
+ 	return (0xffffffffffffffffUL << va_bits);
+ }
+ 
+@@ -382,22 +396,54 @@ get_va_bits_from_stext_arm64(void)
+ 	return TRUE;
+ }
+ 
++static void
++get_page_offset_arm64(void)
++{
++	ulong page_end;
++	int vabits_min;
++
++	/*
++	 * See arch/arm64/include/asm/memory.h for more details of
++	 * the PAGE_OFFSET calculation.
++	 */
++	vabits_min = (va_bits > 48) ? 48 : va_bits;
++	page_end = -(1UL << (vabits_min - 1));
++
++	if (SYMBOL(_stext) > page_end) {
++		flipped_va = TRUE;
++		info->page_offset = -(1UL << vabits_actual);
++	} else {
++		flipped_va = FALSE;
++		info->page_offset = -(1UL << (vabits_actual - 1));
++	}
++
++	DEBUG_MSG("page_offset   : %lx (from page_end check)\n",
++		info->page_offset);
++}
++
+ int
+ get_machdep_info_arm64(void)
+ {
++	/* Check if va_bits is still not initialized. If still 0, call
++	 * get_versiondep_info() to initialize the same.
++	 */
++	if (!va_bits)
++		get_versiondep_info_arm64();
++
+ 	/* Determine if the PA address range is 52-bits: ARMv8.2-LPA */
+ 	if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) {
+ 		info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
++		DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits);
+ 		if (info->max_physmem_bits == 52)
+ 			lpa_52_bit_support_available = 1;
+-	} else
+-		info->max_physmem_bits = 48;
++	} else {
++		if (va_bits == 52)
++			info->max_physmem_bits = 52; /* just guess */
++		else
++			info->max_physmem_bits = 48;
+ 
+-	/* Check if va_bits is still not initialized. If still 0, call
+-	 * get_versiondep_info() to initialize the same.
+-	 */
+-	if (!va_bits)
+-		get_versiondep_info_arm64();
++		DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits);
++	}
+ 
+ 	if (!calculate_plat_config()) {
+ 		ERRMSG("Can't determine platform config values\n");
+@@ -408,7 +454,6 @@ get_machdep_info_arm64(void)
+ 	info->section_size_bits = SECTIONS_SIZE_BITS;
+ 
+ 	DEBUG_MSG("kimage_voffset   : %lx\n", kimage_voffset);
+-	DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits);
+ 	DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits);
+ 
+ 	return TRUE;
+@@ -443,10 +488,35 @@ get_versiondep_info_arm64(void)
+ 		return FALSE;
+ 	}
+ 
+-	info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
++	/*
++	 * See TCR_EL1, Translation Control Register (EL1) register
++	 * description in the ARMv8 Architecture Reference Manual.
++	 * Basically, we can use the TCR_EL1.T1SZ value to determine
++	 * the virtual addressing range supported in the kernel-space
++	 * (i.e. vabits_actual) since Linux 5.9.
++	 */
++	if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) {
++		vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ);
++		DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual);
++	} else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) {
++		/*
++		 * Linux 5.4 through 5.10 have the following linear space:
++		 *   48-bit: 0xffff000000000000 - 0xffff7fffffffffff
++		 *   52-bit: 0xfff0000000000000 - 0xfff7ffffffffffff
++		 * and SYMBOL(mem_section) should be in linear space if
++		 * the kernel is configured with COMFIG_SPARSEMEM_EXTREME=y.
++		 */
++		if (SYMBOL(mem_section) & (1UL << (va_bits - 1)))
++			vabits_actual = 48;
++		else
++			vabits_actual = 52;
++		DEBUG_MSG("vabits_actual : %d (guess from mem_section)\n", vabits_actual);
++	} else {
++		vabits_actual = va_bits;
++		DEBUG_MSG("vabits_actual : %d (same as va_bits)\n", vabits_actual);
++	}
+ 
+-	DEBUG_MSG("va_bits      : %d\n", va_bits);
+-	DEBUG_MSG("page_offset  : %lx\n", info->page_offset);
++	get_page_offset_arm64();
+ 
+ 	return TRUE;
+ }
+diff --git a/makedumpfile.c b/makedumpfile.c
+index 949b7e4..aaaea38 100644
+--- a/makedumpfile.c
++++ b/makedumpfile.c
+@@ -2383,6 +2383,7 @@ write_vmcoreinfo_data(void)
+ 	WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
+ #ifdef __aarch64__
+ 	WRITE_NUMBER("VA_BITS", VA_BITS);
++	/* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */
+ 	WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
+ 	WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
+ #endif
+@@ -2821,6 +2822,7 @@ read_vmcoreinfo(void)
+ 	READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
+ #ifdef __aarch64__
+ 	READ_NUMBER("VA_BITS", VA_BITS);
++	READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ);
+ 	READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
+ 	READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
+ #endif
+diff --git a/makedumpfile.h b/makedumpfile.h
+index 47f7e79..0fe3645 100644
+--- a/makedumpfile.h
++++ b/makedumpfile.h
+@@ -1993,6 +1993,7 @@ struct number_table {
+ 	long	KERNEL_IMAGE_SIZE;
+ #ifdef __aarch64__
+ 	long 	VA_BITS;
++	long	TCR_EL1_T1SZ;
+ 	unsigned long	PHYS_OFFSET;
+ 	unsigned long	kimage_voffset;
+ #endif
diff -Nru makedumpfile-1.6.8/debian/patches/series makedumpfile-1.6.8/debian/patches/series
--- makedumpfile-1.6.8/debian/patches/series	2021-01-18 07:50:02.000000000 -0700
+++ makedumpfile-1.6.8/debian/patches/series	2021-04-07 16:32:38.000000000 -0600
@@ -1 +1,6 @@
 0002-adapt-makefile-to-debian.patch
+0002-PATCH-1-2-printk-add-support-for-lockless-ringbuffer.patch
+0003-PATCH-2-2-printk-use-committed-finalized-state-value.patch
+0004-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch
+0005-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch
+0006-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: