Blame SOURCES/0014-x86_64-Fix-for-AMD-SME-issue.patch

56ae9b
From b584eb81ff27e42547d01c521b488aaeaa35b460 Mon Sep 17 00:00:00 2001
56ae9b
From: Lianbo Jiang <lijiang@redhat.com>
56ae9b
Date: Thu, 28 Jul 2022 15:11:20 +0800
56ae9b
Subject: [PATCH 14/28] x86_64: Fix for AMD SME issue
56ae9b
56ae9b
Kernel commit changes(see [1]/[2]) may cause the failure of crash-utility
56ae9b
with the following error:
56ae9b
56ae9b
  #./crash /home/vmlinux /home/vmcore
56ae9b
  ...
56ae9b
  For help, type "help".
56ae9b
  Type "apropos word" to search for commands related to "word"...
56ae9b
56ae9b
  crash: seek error: physical address: 8000760a14000  type: "p4d page"
56ae9b
56ae9b
Let's get the "NUMBER(sme_mask)" from vmcoreinfo, and try to remove
56ae9b
the C-bit from the page table entries, the intention is to get the
56ae9b
true physical address.
56ae9b
56ae9b
Related kernel commits:
56ae9b
[1] aad983913d77 ("x86/mm/encrypt: Simplify sme_populate_pgd() and sme_populate_pgd_large()")
56ae9b
[2] e7d445ab26db ("x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c")
56ae9b
56ae9b
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
56ae9b
---
56ae9b
 defs.h   |  1 +
56ae9b
 x86_64.c | 21 ++++++++++++++++++---
56ae9b
 2 files changed, 19 insertions(+), 3 deletions(-)
56ae9b
56ae9b
diff --git a/defs.h b/defs.h
56ae9b
index 6a1b6f8a16a8..f8fbfdfd1152 100644
56ae9b
--- a/defs.h
56ae9b
+++ b/defs.h
56ae9b
@@ -6206,6 +6206,7 @@ struct machine_specific {
56ae9b
 	ulong cpu_entry_area_end;
56ae9b
 	ulong page_offset_force;
56ae9b
 	char **exception_functions;
56ae9b
+	ulong sme_mask;
56ae9b
 };
56ae9b
 
56ae9b
 #define KSYMS_START    (0x1)
56ae9b
diff --git a/x86_64.c b/x86_64.c
56ae9b
index f4e5d9e77cef..b2a536e4b19c 100644
56ae9b
--- a/x86_64.c
56ae9b
+++ b/x86_64.c
56ae9b
@@ -206,6 +206,10 @@ x86_64_init(int when)
56ae9b
 			machdep->machspec->kernel_image_size = dtol(string, QUIET, NULL);
56ae9b
 			free(string);
56ae9b
 		}
56ae9b
+		if ((string = pc->read_vmcoreinfo("NUMBER(sme_mask)"))) {
56ae9b
+			machdep->machspec->sme_mask = dtol(string, QUIET, NULL);
56ae9b
+			free(string);
56ae9b
+		}
56ae9b
 		if (SADUMP_DUMPFILE() || QEMU_MEM_DUMP_NO_VMCOREINFO() ||
56ae9b
 		    VMSS_DUMPFILE())
56ae9b
 			/* Need for calculation of kaslr_offset and phys_base */
56ae9b
@@ -937,6 +941,7 @@ x86_64_dump_machdep_table(ulong arg)
56ae9b
 			ms->kernel_image_size/MEGABYTES(1));
56ae9b
 	else
56ae9b
 		fprintf(fp, "(uninitialized)\n");
56ae9b
+	fprintf(fp, "                 sme_mask: %lx\n", ms->sme_mask);
56ae9b
 	fprintf(fp, "      physical_mask_shift: %ld\n", ms->physical_mask_shift);
56ae9b
 	fprintf(fp, "              pgdir_shift: %ld\n", ms->pgdir_shift);
56ae9b
 	fprintf(fp, "               GART_start: %lx\n", ms->GART_start);
56ae9b
@@ -1814,7 +1819,7 @@ x86_64_kpgd_offset(ulong kvaddr, int verbose, int IS_XEN)
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "PAGE DIRECTORY: %lx [machine]\n", *pgd);
56ae9b
 		else
56ae9b
-			fprintf(fp, "PAGE DIRECTORY: %lx\n", *pgd);
56ae9b
+			fprintf(fp, "PAGE DIRECTORY: %lx\n", *pgd & ~machdep->machspec->sme_mask);
56ae9b
 	}
56ae9b
 
56ae9b
 	return pgd;
56ae9b
@@ -1851,7 +1856,8 @@ x86_64_upgd_offset_legacy(struct task_context *tc, ulong uvaddr, int verbose, in
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   PGD: %lx => %lx [machine]\n", (ulong)pud, pud_pte);
56ae9b
 		else
56ae9b
-			fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pud, pud_pte);
56ae9b
+			fprintf(fp, "   PGD: %lx => %lx\n",
56ae9b
+				(ulong)pud, pud_pte & ~machdep->machspec->sme_mask);
56ae9b
         }
56ae9b
 
56ae9b
 	return pud_pte;
56ae9b
@@ -1882,7 +1888,8 @@ x86_64_upgd_offset(struct task_context *tc, ulong uvaddr, int verbose, int IS_XE
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   PGD: %lx => %lx [machine]\n", (ulong)pgd, pgd_pte);
56ae9b
 		else
56ae9b
-			fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd, pgd_pte);
56ae9b
+			fprintf(fp, "   PGD: %lx => %lx\n",
56ae9b
+				(ulong)pgd, pgd_pte & ~machdep->machspec->sme_mask);
56ae9b
         }
56ae9b
 
56ae9b
 	return pgd_pte;
56ae9b
@@ -1900,9 +1907,11 @@ x86_64_p4d_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	ulong p4d_pte;
56ae9b
 
56ae9b
 	p4d_paddr = pgd_pte & PHYSICAL_PAGE_MASK;
56ae9b
+	p4d_paddr &= ~machdep->machspec->sme_mask;
56ae9b
 	FILL_P4D(p4d_paddr, PHYSADDR, PAGESIZE());
56ae9b
 	p4d = ((ulong *)p4d_paddr) + p4d_index(vaddr);
56ae9b
 	p4d_pte = ULONG(machdep->machspec->p4d + PAGEOFFSET(p4d));
56ae9b
+	p4d_pte &= ~machdep->machspec->sme_mask;
56ae9b
         if (verbose) {
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   P4D: %lx => %lx [machine]\n", (ulong)p4d, p4d_pte);
56ae9b
@@ -1925,6 +1934,7 @@ x86_64_pud_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	ulong pud_pte;
56ae9b
 
56ae9b
 	pud_paddr = pgd_pte & PHYSICAL_PAGE_MASK;
56ae9b
+	pud_paddr &= ~machdep->machspec->sme_mask;
56ae9b
 
56ae9b
 	if (IS_XEN) {
56ae9b
 		pud_paddr = xen_m2p(pud_paddr);
56ae9b
@@ -1935,6 +1945,7 @@ x86_64_pud_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	FILL_PUD(pud_paddr, PHYSADDR, PAGESIZE());
56ae9b
 	pud = ((ulong *)pud_paddr) + pud_index(vaddr);
56ae9b
 	pud_pte = ULONG(machdep->pud + PAGEOFFSET(pud));
56ae9b
+	pud_pte &= ~machdep->machspec->sme_mask;
56ae9b
 	if (verbose) {
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   PUD: %lx => %lx [machine]\n", (ulong)pud, pud_pte);
56ae9b
@@ -1957,6 +1968,7 @@ x86_64_pmd_offset(ulong pud_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	ulong pmd_pte;
56ae9b
 
56ae9b
 	pmd_paddr = pud_pte & PHYSICAL_PAGE_MASK;
56ae9b
+	pmd_paddr &= ~machdep->machspec->sme_mask;
56ae9b
 
56ae9b
 	if (IS_XEN) {
56ae9b
 		pmd_paddr = xen_m2p(pmd_paddr);
56ae9b
@@ -1967,6 +1979,7 @@ x86_64_pmd_offset(ulong pud_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	FILL_PMD(pmd_paddr, PHYSADDR, PAGESIZE());
56ae9b
 	pmd = ((ulong *)pmd_paddr) + pmd_index(vaddr);
56ae9b
 	pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(pmd));
56ae9b
+	pmd_pte &= ~machdep->machspec->sme_mask;
56ae9b
         if (verbose) {
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   PMD: %lx => %lx [machine]\n", (ulong)pmd, pmd_pte);
56ae9b
@@ -1988,6 +2001,7 @@ x86_64_pte_offset(ulong pmd_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	ulong pte;
56ae9b
 
56ae9b
 	pte_paddr = pmd_pte & PHYSICAL_PAGE_MASK;
56ae9b
+	pte_paddr &= ~machdep->machspec->sme_mask;
56ae9b
 
56ae9b
 	if (IS_XEN) {
56ae9b
 		pte_paddr = xen_m2p(pte_paddr);
56ae9b
@@ -1998,6 +2012,7 @@ x86_64_pte_offset(ulong pmd_pte, ulong vaddr, int verbose, int IS_XEN)
56ae9b
 	FILL_PTBL(pte_paddr, PHYSADDR, PAGESIZE());
56ae9b
 	ptep = ((ulong *)pte_paddr) + pte_index(vaddr);
56ae9b
 	pte = ULONG(machdep->ptbl + PAGEOFFSET(ptep));
56ae9b
+	pte &= ~machdep->machspec->sme_mask;
56ae9b
 	if (verbose) {
56ae9b
 		if (IS_XEN)
56ae9b
 			fprintf(fp, "   PTE: %lx => %lx [machine]\n", (ulong)ptep, pte);
56ae9b
-- 
56ae9b
2.37.1
56ae9b