[makedumpfile PATCH] sadump: Fix a problem of PTI enabled kernel

Takao Indoh indou.takao at jp.fujitsu.com
Thu Jan 25 16:22:26 PST 2018


This patch fixes a problme that a dumpfile of sadump cannot be handled by
makedumpfile when Page Table Isolation(PTI) is enabled.

When PTI is enabled, bit 12 of CR3 register is used to split user space and
kernel space. Also bit 11:0 is used for Process Context IDentifiers(PCID).  To
open a dump file of sadump, a value of CR3 is used to calculate KASLR offset and
phys_base, therefore this patch fixes to mask CR3 register value collectly for
PTI enabled kernel.

Signed-off-by: Takao Indoh <indou.takao at jp.fujitsu.com>
---
 makedumpfile.c | 2 ++
 makedumpfile.h | 2 ++
 sadump_info.c  | 9 ++++++++-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 64b404a..247a056 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1557,6 +1557,8 @@ get_symbol_info(void)
 	SYMBOL_INIT(divide_error, "divide_error");
 	SYMBOL_INIT(idt_table, "idt_table");
 	SYMBOL_INIT(saved_command_line, "saved_command_line");
+	SYMBOL_INIT(pti_init, "pti_init");
+	SYMBOL_INIT(kaiser_init, "kaiser_init");
 
 	return TRUE;
 }
diff --git a/makedumpfile.h b/makedumpfile.h
index 57cf4d9..8ee4d29 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1608,6 +1608,8 @@ struct symbol_table {
 	unsigned long long	divide_error;
 	unsigned long long	idt_table;
 	unsigned long long	saved_command_line;
+	unsigned long long	pti_init;
+	unsigned long long	kaiser_init;
 
 	/*
 	 * symbols on ppc64 arch
diff --git a/sadump_info.c b/sadump_info.c
index 148d4ba..dd50d48 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -1362,6 +1362,9 @@ finish:
  *    kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
  *    get kaslr_offset and phys_base from vmcoreinfo.
  */
+#define PTI_USER_PGTABLE_BIT		(info->page_shift)
+#define PTI_USER_PGTABLE_MASK		(1 << PTI_USER_PGTABLE_BIT)
+#define CR3_PCID_MASK			0xFFFull
 int
 calc_kaslr_offset(void)
 {
@@ -1389,7 +1392,11 @@ calc_kaslr_offset(void)
 	}
 
 	idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower;
-	cr3 = smram.Cr3;
+	if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) ||
+	    (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL))
+		cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
+	else
+		cr3 = smram.Cr3 & ~CR3_PCID_MASK;
 
 	/* Convert virtual address of IDT table to physical address */
 	if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR)
-- 
1.8.3.1





More information about the kexec mailing list