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