Backport from the makedumpfile devel branch in upstream.
commit d222b01e516bba73ef9fefee4146734a5f260fa1 (HEAD -> devel) Author: Lianbo Jiang lijiang@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@redhat.com
Signed-off-by: Lianbo Jiang lijiang@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@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@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
On Mon, Jun 3, 2019 at 10:44 PM Lianbo Jiang lijiang@redhat.com wrote:
Backport from the makedumpfile devel branch in upstream.
commit d222b01e516bba73ef9fefee4146734a5f260fa1 (HEAD -> devel) Author: Lianbo Jiang lijiang@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@redhat.com>Signed-off-by: Lianbo Jiang lijiang@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@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@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
Acked-by: Kairui Song kasong@redhat.com