-----Original Message----- > >> [PATCH v3] Remove the memory encryption mask to obtain the true physical address > > > > I forgot to comment on the subject and the commit log.. > > I'll change this to > > > > x86_64: Add support for AMD Secure Memory Encryption > > > > On 1/29/2019 9:48 PM, Lianbo Jiang wrote: > >> For AMD machine with SME feature, if SME is enabled in the first > >> kernel, the crashed kernel's page table(pgd/pud/pmd/pte) contains > >> the memory encryption mask, so makedumpfile needs to remove the > >> memory encryption mask to obtain the true physical address. > > > > I added a few official words from some documents: > > --- > > 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. > > --- > > > > If these are OK, I'll modify them when merging, so you don't need > > to repost. > > > > It's fine to me. Thank you, Kazu. > > Regards, > Lianbo > > > And, I'm thinking to merge this after the kernel patch gets merged > > into the mainline. Hi Lianbo, I found your patch upstream. Applied to the devel branch. Thank you! Kazu > > > > Thanks for your work. > > Kazu > > > >> > >> Signed-off-by: Lianbo Jiang <lijiang@xxxxxxxxxx> > >> --- > >> Changes since v1: > >> 1. Merge them into a patch. > >> 2. The sme_mask is not an enum number, remove it. > >> 3. Sanity check whether the sme_mask is in vmcoreinfo. > >> 4. Deal with the huge pages case. > >> 5. Cover the 5-level path. > >> > >> Changes since v2: > >> 1. Change the sme_me_mask to entry_mask. > >> 2. No need to remove the mask when makedumpfile prints out the > >> value of the entry. > >> 3. Remove the sme mask from the pte at the end of the __vtop4_x86_64(). > >> 4. Also need to remove the sme mask from page table entry in > >> find_vmemmap_x86_64() > >> > >> 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 537fb78..9977466 100644 > >> --- a/arch/x86_64.c > >> +++ b/arch/x86_64.c > >> @@ -291,6 +291,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. > >> @@ -302,6 +303,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)) { > >> @@ -318,7 +322,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); > >> @@ -331,7 +335,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)) { > >> @@ -345,7 +349,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; > >> } > >> > >> /* > >> @@ -364,13 +368,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); > >> @@ -384,13 +388,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); > >> @@ -403,7 +407,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 > >> @@ -636,6 +640,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 > >> @@ -656,6 +661,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; > >> @@ -686,7 +694,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 */ > >> @@ -699,7 +707,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; > >> @@ -741,7 +749,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 8923538..2237eb8 100644 > >> --- a/makedumpfile.c > >> +++ b/makedumpfile.c > >> @@ -977,6 +977,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; > >> @@ -2276,6 +2278,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); > >> @@ -2672,6 +2675,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 73813ed..e97b2e7 100644 > >> --- a/makedumpfile.h > >> +++ b/makedumpfile.h > >> @@ -1912,6 +1912,7 @@ struct number_table { > >> long NR_FREE_PAGES; > >> long N_ONLINE; > >> long pgtable_l5_enabled; > >> + long sme_mask; > >> > >> /* > >> * Page flags > >> -- > >> 2.17.1 > >> > > > > _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec