Blame SOURCES/kexec-tools-2.0.19-makedumpfiles-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch

603de6
From d222b01e516bba73ef9fefee4146734a5f260fa1 Mon Sep 17 00:00:00 2001
603de6
From: Lianbo Jiang <lijiang@redhat.com>
603de6
Date: Wed, 30 Jan 2019 10:48:53 +0800
603de6
Subject: [PATCH] [PATCH] x86_64: Add support for AMD Secure Memory Encryption
603de6
603de6
On AMD machine with Secure Memory Encryption (SME) feature, if SME is
603de6
enabled, page tables contain a specific attribute bit (C-bit) in their
603de6
entries to indicate whether a page is encrypted or unencrypted.
603de6
603de6
So get NUMBER(sme_mask) from vmcoreinfo, which stores the value of
603de6
the C-bit position, and drop it to obtain the true physical address.
603de6
603de6
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
603de6
---
603de6
 arch/x86_64.c  | 30 +++++++++++++++++++-----------
603de6
 makedumpfile.c |  4 ++++
603de6
 makedumpfile.h |  1 +
603de6
 3 files changed, 24 insertions(+), 11 deletions(-)
603de6
603de6
diff --git a/arch/x86_64.c b/arch/x86_64.c
603de6
index 9db1f8139f28..46e93366f0be 100644
603de6
--- a/makedumpfile-1.6.5/arch/x86_64.c
603de6
+++ b/makedumpfile-1.6.5/arch/x86_64.c
603de6
@@ -297,6 +297,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 	unsigned long page_dir, pgd, pud_paddr, pud_pte, pmd_paddr, pmd_pte;
603de6
 	unsigned long pte_paddr, pte;
603de6
 	unsigned long p4d_paddr, p4d_pte;
603de6
+	unsigned long entry_mask = ENTRY_MASK;
603de6
 
603de6
 	/*
603de6
 	 * Get PGD.
603de6
@@ -308,6 +309,9 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 			return NOT_PADDR;
603de6
 	}
603de6
 
603de6
+	if (NUMBER(sme_mask) != NOT_FOUND_NUMBER)
603de6
+		entry_mask &= ~(NUMBER(sme_mask));
603de6
+
603de6
 	if (check_5level_paging()) {
603de6
 		page_dir += pgd5_index(vaddr) * sizeof(unsigned long);
603de6
 		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
603de6
@@ -324,7 +328,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 		/*
603de6
 		 * Get P4D.
603de6
 		 */
603de6
-		p4d_paddr  = pgd & ENTRY_MASK;
603de6
+		p4d_paddr = pgd & entry_mask;
603de6
 		p4d_paddr += p4d_index(vaddr) * sizeof(unsigned long);
603de6
 		if (!readmem(PADDR, p4d_paddr, &p4d_pte, sizeof p4d_pte)) {
603de6
 			ERRMSG("Can't get p4d_pte (p4d_paddr:%lx).\n", p4d_paddr);
603de6
@@ -337,7 +341,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 			ERRMSG("Can't get a valid p4d_pte.\n");
603de6
 			return NOT_PADDR;
603de6
 		}
603de6
-		pud_paddr  = p4d_pte & ENTRY_MASK;
603de6
+		pud_paddr = p4d_pte & entry_mask;
603de6
 	}else {
603de6
 		page_dir += pgd_index(vaddr) * sizeof(unsigned long);
603de6
 		if (!readmem(PADDR, page_dir, &pgd, sizeof pgd)) {
603de6
@@ -351,7 +355,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 			ERRMSG("Can't get a valid pgd.\n");
603de6
 			return NOT_PADDR;
603de6
 		}
603de6
-		pud_paddr  = pgd & ENTRY_MASK;
603de6
+		pud_paddr = pgd & entry_mask;
603de6
 	}
603de6
 
603de6
 	/*
603de6
@@ -370,13 +374,13 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 		return NOT_PADDR;
603de6
 	}
603de6
 	if (pud_pte & _PAGE_PSE)	/* 1GB pages */
603de6
-		return (pud_pte & ENTRY_MASK & PUD_MASK) +
603de6
+		return (pud_pte & entry_mask & PUD_MASK) +
603de6
 			(vaddr & ~PUD_MASK);
603de6
 
603de6
 	/*
603de6
 	 * Get PMD.
603de6
 	 */
603de6
-	pmd_paddr  = pud_pte & ENTRY_MASK;
603de6
+	pmd_paddr = pud_pte & entry_mask;
603de6
 	pmd_paddr += pmd_index(vaddr) * sizeof(unsigned long);
603de6
 	if (!readmem(PADDR, pmd_paddr, &pmd_pte, sizeof pmd_pte)) {
603de6
 		ERRMSG("Can't get pmd_pte (pmd_paddr:%lx).\n", pmd_paddr);
603de6
@@ -390,13 +394,13 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 		return NOT_PADDR;
603de6
 	}
603de6
 	if (pmd_pte & _PAGE_PSE)	/* 2MB pages */
603de6
-		return (pmd_pte & ENTRY_MASK & PMD_MASK) +
603de6
+		return (pmd_pte & entry_mask & PMD_MASK) +
603de6
 			(vaddr & ~PMD_MASK);
603de6
 
603de6
 	/*
603de6
 	 * Get PTE.
603de6
 	 */
603de6
-	pte_paddr  = pmd_pte & ENTRY_MASK;
603de6
+	pte_paddr = pmd_pte & entry_mask;
603de6
 	pte_paddr += pte_index(vaddr) * sizeof(unsigned long);
603de6
 	if (!readmem(PADDR, pte_paddr, &pte, sizeof pte)) {
603de6
 		ERRMSG("Can't get pte (pte_paddr:%lx).\n", pte_paddr);
603de6
@@ -409,7 +413,7 @@ __vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
603de6
 		ERRMSG("Can't get a valid pte.\n");
603de6
 		return NOT_PADDR;
603de6
 	}
603de6
-	return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
603de6
+	return (pte & entry_mask) + PAGEOFFSET(vaddr);
603de6
 }
603de6
 
603de6
 unsigned long long
603de6
@@ -642,6 +646,7 @@ find_vmemmap_x86_64()
603de6
 	unsigned long pmd, tpfn;
603de6
 	unsigned long pvaddr = 0;
603de6
 	unsigned long data_addr = 0, last_data_addr = 0, start_data_addr = 0;
603de6
+	unsigned long pmask = PMASK;
603de6
 	/*
603de6
 	 * data_addr is the paddr of the page holding the page structs.
603de6
 	 * We keep lists of contiguous pages and the pfn's that their
603de6
@@ -662,6 +667,9 @@ find_vmemmap_x86_64()
603de6
 		return FAILED;
603de6
 	}
603de6
 
603de6
+	if (NUMBER(sme_mask) != NOT_FOUND_NUMBER)
603de6
+		pmask &= ~(NUMBER(sme_mask));
603de6
+
603de6
 	pagestructsize = size_table.page;
603de6
 	hugepagesize = PTRS_PER_PMD * info->page_size;
603de6
 	vaddr_base = info->vmemmap_start;
603de6
@@ -692,7 +700,7 @@ find_vmemmap_x86_64()
603de6
 		}
603de6
 
603de6
 		/* mask the pgd entry for the address of the pud page */
603de6
-		pud_addr &= PMASK;
603de6
+		pud_addr &= pmask;
603de6
 		if (pud_addr == 0)
603de6
 			  continue;
603de6
 		/* read the entire pud page */
603de6
@@ -705,7 +713,7 @@ find_vmemmap_x86_64()
603de6
 		/* pudp points to an entry in the pud page */
603de6
 		for (pudp = (unsigned long *)pud_page, pudindex = 0;
603de6
 					pudindex < PTRS_PER_PUD; pudindex++, pudp++) {
603de6
-			pmd_addr = *pudp & PMASK;
603de6
+			pmd_addr = *pudp & pmask;
603de6
 			/* read the entire pmd page */
603de6
 			if (pmd_addr == 0)
603de6
 				continue;
603de6
@@ -747,7 +755,7 @@ find_vmemmap_x86_64()
603de6
 				 * - we discontiguous page is a string of valids
603de6
 				 */
603de6
 				if (pmd) {
603de6
-					data_addr = (pmd & PMASK);
603de6
+					data_addr = (pmd & pmask);
603de6
 					if (start_range) {
603de6
 						/* first-time kludge */
603de6
 						start_data_addr = data_addr;
603de6
diff --git a/makedumpfile.c b/makedumpfile.c
603de6
index 7dfe70fb8792..590f759c84f1 100644
603de6
--- a/makedumpfile-1.6.5/makedumpfile.c
603de6
+++ b/makedumpfile-1.6.5/makedumpfile.c
603de6
@@ -993,6 +993,8 @@ next_page:
603de6
 	read_size = MIN(info->page_size - PAGEOFFSET(paddr), size);
603de6
 
603de6
 	pgaddr = PAGEBASE(paddr);
603de6
+	if (NUMBER(sme_mask) != NOT_FOUND_NUMBER)
603de6
+		pgaddr = pgaddr & ~(NUMBER(sme_mask));
603de6
 	pgbuf = cache_search(pgaddr, read_size);
603de6
 	if (!pgbuf) {
603de6
 		++cache_miss;
603de6
@@ -2292,6 +2294,7 @@ write_vmcoreinfo_data(void)
603de6
 	WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
603de6
 	WRITE_NUMBER("N_ONLINE", N_ONLINE);
603de6
 	WRITE_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled);
603de6
+	WRITE_NUMBER("sme_mask", sme_mask);
603de6
 
603de6
 	WRITE_NUMBER("PG_lru", PG_lru);
603de6
 	WRITE_NUMBER("PG_private", PG_private);
603de6
@@ -2695,6 +2698,7 @@ read_vmcoreinfo(void)
603de6
 	READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
603de6
 	READ_NUMBER("N_ONLINE", N_ONLINE);
603de6
 	READ_NUMBER("pgtable_l5_enabled", pgtable_l5_enabled);
603de6
+	READ_NUMBER("sme_mask", sme_mask);
603de6
 
603de6
 	READ_NUMBER("PG_lru", PG_lru);
603de6
 	READ_NUMBER("PG_private", PG_private);
603de6
diff --git a/makedumpfile.h b/makedumpfile.h
603de6
index 2e73beca48c5..5ad38e9ae40c 100644
603de6
--- a/makedumpfile-1.6.5/makedumpfile.h
603de6
+++ b/makedumpfile-1.6.5/makedumpfile.h
603de6
@@ -1913,6 +1913,7 @@ struct number_table {
603de6
 	long	NR_FREE_PAGES;
603de6
 	long	N_ONLINE;
603de6
 	long	pgtable_l5_enabled;
603de6
+	long	sme_mask;
603de6
 
603de6
 	/*
603de6
  	* Page flags
603de6
-- 
603de6
2.17.1
603de6