Blame SOURCES/github_b97e7fd4e826_to_8b50d94ada21.patch

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