Blame SOURCES/github_b97e7fd4e826_to_8b50d94ada21.patch

d6db87
From b97e7fd4e8268d5c46f1b30b41ce1f6ca9ceb216 Mon Sep 17 00:00:00 2001
d6db87
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
Date: Mon, 27 Jul 2020 19:00:19 +0900
d6db87
Subject: [PATCH 1/4] symbols: Add linux_banner_vmlinux in symbol table
d6db87
d6db87
Add linux_banner_vmlinux in symbol table, which we'll later use in
d6db87
calc_kaslr_offset() to do a sanity check in calculation of
d6db87
kaslr_offset and phys_base.
d6db87
d6db87
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
---
d6db87
 defs.h    |  2 ++
d6db87
 symbols.c | 10 ++++++++++
d6db87
 2 files changed, 12 insertions(+)
d6db87
d6db87
diff --git a/defs.h b/defs.h
d6db87
index 131a705ad855..fa2374eb5717 100644
d6db87
--- a/defs.h
d6db87
+++ b/defs.h
d6db87
@@ -2677,6 +2677,8 @@ struct symbol_table_data {
d6db87
 	ulong saved_command_line_vmlinux;
d6db87
 	ulong pti_init_vmlinux;
d6db87
 	ulong kaiser_init_vmlinux;
d6db87
+	int kernel_symbol_type;
d6db87
+	ulong linux_banner_vmlinux;
d6db87
 };
d6db87
 
d6db87
 /* flags for st */
d6db87
diff --git a/symbols.c b/symbols.c
d6db87
index cea54db3ffd0..c587af2a61d2 100644
d6db87
--- a/symbols.c
d6db87
+++ b/symbols.c
d6db87
@@ -3148,6 +3148,11 @@ dump_symbol_table(void)
d6db87
 		fprintf(fp, " kaiser_init_vmlinux: (unused)\n");
d6db87
 	}
d6db87
 
d6db87
+	if (SADUMP_DUMPFILE())
d6db87
+		fprintf(fp, "linux_banner_vmlinux: %lx\n", st->linux_banner_vmlinux);
d6db87
+	else
d6db87
+		fprintf(fp, "linux_banner_vmlinux: (unused)\n");
d6db87
+
d6db87
         fprintf(fp, "    symval_hash[%d]: %lx\n", SYMVAL_HASH,
d6db87
                 (ulong)&st->symval_hash[0]);
d6db87
 
d6db87
@@ -12500,6 +12505,11 @@ numeric_forward(const void *P_x, const void *P_y)
d6db87
 		else if (STREQ(y->name, "idt_table"))
d6db87
 			st->idt_table_vmlinux = valueof(y);
d6db87
 
d6db87
+		if (STREQ(x->name, "linux_banner"))
d6db87
+			st->linux_banner_vmlinux = valueof(x);
d6db87
+		else if (STREQ(y->name, "linux_banner"))
d6db87
+			st->linux_banner_vmlinux = valueof(y);
d6db87
+
d6db87
 		if (STREQ(x->name, "saved_command_line"))
d6db87
 			st->saved_command_line_vmlinux = valueof(x);
d6db87
 		else if (STREQ(y->name, "saved_command_line"))
d6db87
-- 
d6db87
2.26.2
d6db87
d6db87
d6db87
From d494fabe99b90cea8d717a90951e44e6dbda84bb Mon Sep 17 00:00:00 2001
d6db87
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
Date: Mon, 27 Jul 2020 19:00:20 +0900
d6db87
Subject: [PATCH 2/4] symbols: fix initialization of st->{pti_init,
d6db87
 kaiser}_vmlinux
d6db87
d6db87
In numeric_forward(), care must be taken both for x- and y- positions,
d6db87
but either of kaiser_init and pti_init is only for x- or y- position
d6db87
only. Fix this. Also, move the code in an appropriate position
d6db87
according to each symbol name in the alphabetical order.
d6db87
d6db87
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
---
d6db87
 symbols.c | 15 ++++++++++-----
d6db87
 1 file changed, 10 insertions(+), 5 deletions(-)
d6db87
d6db87
diff --git a/symbols.c b/symbols.c
d6db87
index c587af2a61d2..c546b9f46acb 100644
d6db87
--- a/symbols.c
d6db87
+++ b/symbols.c
d6db87
@@ -12505,20 +12505,25 @@ numeric_forward(const void *P_x, const void *P_y)
d6db87
 		else if (STREQ(y->name, "idt_table"))
d6db87
 			st->idt_table_vmlinux = valueof(y);
d6db87
 
d6db87
+		if (STREQ(x->name, "kaiser_init"))
d6db87
+			st->kaiser_init_vmlinux = valueof(x);
d6db87
+		else if (STREQ(y->name, "kaiser_init"))
d6db87
+			st->kaiser_init_vmlinux = valueof(y);
d6db87
+
d6db87
 		if (STREQ(x->name, "linux_banner"))
d6db87
 			st->linux_banner_vmlinux = valueof(x);
d6db87
 		else if (STREQ(y->name, "linux_banner"))
d6db87
 			st->linux_banner_vmlinux = valueof(y);
d6db87
 
d6db87
+		if (STREQ(x->name, "pti_init"))
d6db87
+			st->pti_init_vmlinux = valueof(x);
d6db87
+		else if (STREQ(y->name, "pti_init"))
d6db87
+			st->pti_init_vmlinux = valueof(y);
d6db87
+
d6db87
 		if (STREQ(x->name, "saved_command_line"))
d6db87
 			st->saved_command_line_vmlinux = valueof(x);
d6db87
 		else if (STREQ(y->name, "saved_command_line"))
d6db87
 			st->saved_command_line_vmlinux = valueof(y);
d6db87
-
d6db87
-		if (STREQ(x->name, "pti_init"))
d6db87
-			st->pti_init_vmlinux = valueof(x);
d6db87
-		else if (STREQ(y->name, "kaiser_init"))
d6db87
-			st->kaiser_init_vmlinux = valueof(y);
d6db87
 	}
d6db87
 
d6db87
   	xs = bfd_get_section(x);
d6db87
-- 
d6db87
2.26.2
d6db87
d6db87
d6db87
From ff45c8da8cafed350940b1a56dce65f58051db5e Mon Sep 17 00:00:00 2001
d6db87
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
Date: Mon, 27 Jul 2020 19:00:22 +0900
d6db87
Subject: [PATCH 3/4] kaslr: cleanup how to set values to the arguments of
d6db87
 calc_kaslr_offset()
d6db87
d6db87
Setting values of the arguments of calc_kaslr_offset() should be done
d6db87
at the end of the function. Currently, they are set in the middle
d6db87
where their values could still be changed according to
d6db87
get_kaslr_offset_from_vmcoreinfo(). This behavior will be problematic
d6db87
in the later commits when we implement a trial-and-error approach
d6db87
because the value of kaslr_offset could be passed to the outside of
d6db87
calc_kaslr_offset() unexpectedly. Thus, fix this first.
d6db87
d6db87
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
---
d6db87
 kaslr_helper.c | 22 +++++++++++++---------
d6db87
 1 file changed, 13 insertions(+), 9 deletions(-)
d6db87
d6db87
diff --git a/kaslr_helper.c b/kaslr_helper.c
d6db87
index fe5909caa937..acbb5c2692e2 100644
d6db87
--- a/kaslr_helper.c
d6db87
+++ b/kaslr_helper.c
d6db87
@@ -394,10 +394,11 @@ quit:
d6db87
 #define PTI_USER_PGTABLE_MASK	(1 << PTI_USER_PGTABLE_BIT)
d6db87
 #define CR3_PCID_MASK		0xFFFull
d6db87
 int
d6db87
-calc_kaslr_offset(ulong *kaslr_offset, ulong *phys_base)
d6db87
+calc_kaslr_offset(ulong *ko, ulong *pb)
d6db87
 {
d6db87
 	uint64_t cr3 = 0, idtr = 0, pgd = 0, idtr_paddr;
d6db87
 	ulong divide_error_vmcore;
d6db87
+	ulong kaslr_offset, phys_base;
d6db87
 	ulong kaslr_offset_kdump, phys_base_kdump;
d6db87
 	int ret = FALSE;
d6db87
 	int verbose = CRASHDEBUG(1)? 1: 0;
d6db87
@@ -445,9 +446,9 @@ calc_kaslr_offset(ulong *kaslr_offset, ulong *phys_base)
d6db87
 
d6db87
 	/* Now we can calculate kaslr_offset and phys_base */
d6db87
 	divide_error_vmcore = get_vec0_addr(idtr_paddr);
d6db87
-	*kaslr_offset = divide_error_vmcore - st->divide_error_vmlinux;
d6db87
-	*phys_base = idtr_paddr -
d6db87
-		(st->idt_table_vmlinux + *kaslr_offset - __START_KERNEL_map);
d6db87
+	kaslr_offset = divide_error_vmcore - st->divide_error_vmlinux;
d6db87
+	phys_base = idtr_paddr -
d6db87
+		(st->idt_table_vmlinux + kaslr_offset - __START_KERNEL_map);
d6db87
 
d6db87
 	if (CRASHDEBUG(1)) {
d6db87
 		fprintf(fp, "calc_kaslr_offset: idtr=%lx\n", idtr);
d6db87
@@ -465,9 +466,9 @@ calc_kaslr_offset(ulong *kaslr_offset, ulong *phys_base)
d6db87
 	 * from vmcoreinfo
d6db87
 	 */
d6db87
 	if (get_kaslr_offset_from_vmcoreinfo(
d6db87
-		*kaslr_offset, &kaslr_offset_kdump, &phys_base_kdump)) {
d6db87
-		*kaslr_offset =  kaslr_offset_kdump;
d6db87
-		*phys_base =  phys_base_kdump;
d6db87
+		kaslr_offset, &kaslr_offset_kdump, &phys_base_kdump)) {
d6db87
+		kaslr_offset =  kaslr_offset_kdump;
d6db87
+		phys_base =  phys_base_kdump;
d6db87
 	} else if (CRASHDEBUG(1)) {
d6db87
 		fprintf(fp, "kaslr_helper: failed to determine which kernel was running at crash,\n");
d6db87
 		fprintf(fp, "kaslr_helper: asssuming the kdump 1st kernel.\n");
d6db87
@@ -475,10 +476,13 @@ calc_kaslr_offset(ulong *kaslr_offset, ulong *phys_base)
d6db87
 
d6db87
 	if (CRASHDEBUG(1)) {
d6db87
 		fprintf(fp, "calc_kaslr_offset: kaslr_offset=%lx\n",
d6db87
-			*kaslr_offset);
d6db87
-		fprintf(fp, "calc_kaslr_offset: phys_base=%lx\n", *phys_base);
d6db87
+			kaslr_offset);
d6db87
+		fprintf(fp, "calc_kaslr_offset: phys_base=%lx\n", phys_base);
d6db87
 	}
d6db87
 
d6db87
+	*ko = kaslr_offset;
d6db87
+	*pb = phys_base;
d6db87
+
d6db87
 	ret = TRUE;
d6db87
 quit:
d6db87
 	vt->kernel_pgd[0] = 0;
d6db87
-- 
d6db87
2.26.2
d6db87
d6db87
d6db87
From 8b50d94ada21f403665a5e562f40191f111e0313 Mon Sep 17 00:00:00 2001
d6db87
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
Date: Mon, 27 Jul 2020 19:00:23 +0900
d6db87
Subject: [PATCH 4/4] kaslr: fix failure of calculating kaslr_offset due to an
d6db87
 sadump format restriction
d6db87
d6db87
We faced recently a memory dump collected by sadump where unused part
d6db87
of register values are non-zero. For the crash dump, calculating
d6db87
kaslr_offset fails because it is based on the assumption that unused
d6db87
part of register values in the sadump format are always zero cleared.
d6db87
d6db87
The problem is that used and unused part of register values are
d6db87
rigorously indistinguishable in the sadump format. Although there is
d6db87
kernel data structure that represents a map between logical cpu
d6db87
numbers and lapic ids, they cannot be used in order to calculate
d6db87
kaslr_offset.
d6db87
d6db87
To fix this, we have no choice but use a trial-and-error approach: try
d6db87
to use each entry of register values in order until we find a good
d6db87
pair of cr3 and idtr by which we can refer to linux_banner symbol as
d6db87
expected.
d6db87
d6db87
This fix is for the sadump specific issue, so there is no functional
d6db87
change for the other crash dump formats.
d6db87
d6db87
 [ lijiang: adjust the code indent. ]
d6db87
d6db87
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
d6db87
---
d6db87
 kaslr_helper.c | 39 +++++++++++++++++++++++++++++++++----
d6db87
 sadump.c       | 52 +++++++++++++++++++++++++++-----------------------
d6db87
 2 files changed, 63 insertions(+), 28 deletions(-)
d6db87
d6db87
diff --git a/kaslr_helper.c b/kaslr_helper.c
d6db87
index acbb5c2692e2..bb19e548d04e 100644
d6db87
--- a/kaslr_helper.c
d6db87
+++ b/kaslr_helper.c
d6db87
@@ -406,6 +406,7 @@ calc_kaslr_offset(ulong *ko, ulong *pb)
d6db87
 	if (!machine_type("X86_64"))
d6db87
 		return FALSE;
d6db87
 
d6db87
+retry:
d6db87
 	if (SADUMP_DUMPFILE()) {
d6db87
 		if (!sadump_get_cr3_idtr(&cr3, &idtr))
d6db87
 			return FALSE;
d6db87
@@ -437,12 +438,20 @@ calc_kaslr_offset(ulong *ko, ulong *pb)
d6db87
 	machdep->machspec->pgdir_shift = PGDIR_SHIFT;
d6db87
 	machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD;
d6db87
 	if (!readmem(pgd, PHYSADDR, machdep->pgd, PAGESIZE(),
d6db87
-			"pgd", RETURN_ON_ERROR))
d6db87
-		goto quit;
d6db87
+			"pgd", RETURN_ON_ERROR)) {
d6db87
+		if (SADUMP_DUMPFILE())
d6db87
+			goto retry;
d6db87
+		else
d6db87
+			goto quit;
d6db87
+	}
d6db87
 
d6db87
 	/* Convert virtual address of IDT table to physical address */
d6db87
-	if (!kvtop(NULL, idtr, &idtr_paddr, verbose))
d6db87
-		goto quit;
d6db87
+	if (!kvtop(NULL, idtr, &idtr_paddr, verbose)) {
d6db87
+		if (SADUMP_DUMPFILE())
d6db87
+			goto retry;
d6db87
+		else
d6db87
+			goto quit;
d6db87
+	}
d6db87
 
d6db87
 	/* Now we can calculate kaslr_offset and phys_base */
d6db87
 	divide_error_vmcore = get_vec0_addr(idtr_paddr);
d6db87
@@ -450,6 +459,28 @@ calc_kaslr_offset(ulong *ko, ulong *pb)
d6db87
 	phys_base = idtr_paddr -
d6db87
 		(st->idt_table_vmlinux + kaslr_offset - __START_KERNEL_map);
d6db87
 
d6db87
+	if (SADUMP_DUMPFILE()) {
d6db87
+		char buf[sizeof("Linux version")];
d6db87
+		ulong linux_banner_paddr;
d6db87
+
d6db87
+		if (!kvtop(NULL,
d6db87
+			   st->linux_banner_vmlinux + kaslr_offset,
d6db87
+			   &linux_banner_paddr,
d6db87
+			   verbose))
d6db87
+			goto retry;
d6db87
+
d6db87
+		if (!readmem(linux_banner_paddr,
d6db87
+			     PHYSADDR,
d6db87
+			     buf,
d6db87
+			     sizeof(buf),
d6db87
+			     "linux_banner",
d6db87
+			     RETURN_ON_ERROR))
d6db87
+			goto retry;
d6db87
+
d6db87
+		if (!STRNEQ(buf, "Linux version"))
d6db87
+			goto retry;
d6db87
+	}
d6db87
+
d6db87
 	if (CRASHDEBUG(1)) {
d6db87
 		fprintf(fp, "calc_kaslr_offset: idtr=%lx\n", idtr);
d6db87
 		fprintf(fp, "calc_kaslr_offset: pgd=%lx\n", pgd);
d6db87
diff --git a/sadump.c b/sadump.c
d6db87
index 35f7cf0fcf8f..009e17a4a44a 100644
d6db87
--- a/sadump.c
d6db87
+++ b/sadump.c
d6db87
@@ -1664,29 +1664,32 @@ get_sadump_data(void)
d6db87
 static int
d6db87
 get_sadump_smram_cpu_state_any(struct sadump_smram_cpu_state *smram)
d6db87
 {
d6db87
-        ulong offset;
d6db87
-        struct sadump_header *sh = sd->dump_header;
d6db87
-        int apicid;
d6db87
-        struct sadump_smram_cpu_state scs, zero;
d6db87
-
d6db87
-        offset = sd->sub_hdr_offset + sizeof(uint32_t) +
d6db87
-                 sd->dump_header->nr_cpus * sizeof(struct sadump_apic_state);
d6db87
-
d6db87
-        memset(&zero, 0, sizeof(zero));
d6db87
-
d6db87
-        for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
d6db87
-                if (!read_device(&scs, sizeof(scs), &offset)) {
d6db87
-                        error(INFO, "sadump: cannot read sub header "
d6db87
-                              "cpu_state\n");
d6db87
-                        return FALSE;
d6db87
-                }
d6db87
-                if (memcmp(&scs, &zero, sizeof(scs)) != 0) {
d6db87
-                        *smram = scs;
d6db87
-                        return TRUE;
d6db87
-                }
d6db87
-        }
d6db87
-
d6db87
-        return FALSE;
d6db87
+	ulong offset;
d6db87
+	struct sadump_header *sh = sd->dump_header;
d6db87
+	static int apicid;
d6db87
+	struct sadump_smram_cpu_state scs;
d6db87
+
d6db87
+	if (apicid >= sh->nr_cpus)
d6db87
+		return FALSE;
d6db87
+
d6db87
+	offset = sd->sub_hdr_offset + sizeof(uint32_t) +
d6db87
+		 sd->dump_header->nr_cpus * sizeof(struct sadump_apic_state) +
d6db87
+		 apicid * sizeof(scs);
d6db87
+
d6db87
+	while (apicid < sh->nr_cpus) {
d6db87
+		apicid++;
d6db87
+		if (!read_device(&scs, sizeof(scs), &offset)) {
d6db87
+			error(INFO, "sadump: cannot read sub header "
d6db87
+				"cpu_state\n");
d6db87
+			return FALSE;
d6db87
+		}
d6db87
+		if (scs.Cr3 && (scs.IdtUpper || scs.IdtLower)) {
d6db87
+			*smram = scs;
d6db87
+			return TRUE;
d6db87
+		}
d6db87
+	}
d6db87
+
d6db87
+	return FALSE;
d6db87
 }
d6db87
 
d6db87
 int
d6db87
@@ -1695,7 +1698,8 @@ sadump_get_cr3_idtr(ulong *cr3, ulong *idtr)
d6db87
 	struct sadump_smram_cpu_state scs;
d6db87
 
d6db87
 	memset(&scs, 0, sizeof(scs));
d6db87
-	get_sadump_smram_cpu_state_any(&scs);
d6db87
+	if (!get_sadump_smram_cpu_state_any(&scs))
d6db87
+		return FALSE;
d6db87
 
d6db87
 	*cr3 = scs.Cr3;
d6db87
 	*idtr = ((uint64_t)scs.IdtUpper)<<32 | (uint64_t)scs.IdtLower;
d6db87
-- 
d6db87
2.26.2
d6db87