From 03802052edce2cbc6448ed6c7158f95ad9b92695 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Thu, 25 Oct 2018 10:24:56 +0900 Subject: [PATCH] mcctrl: add handling for one more level of page tables newer linux got a 5 level page table now, try to handle that. Some of the macros will be no-op (e.g. loop only on one iteration) on architecture/kernels with only 4 levels but the code needs to be there to compile Change-Id: Ifc6304cbb066dce7d4e30962687ae05d7e034730 --- executer/kernel/mcctrl/syscall.c | 50 ++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index 1db62fda..342b3845 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -1728,6 +1728,9 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf uintptr_t pfn; uintptr_t va; pgd_t *pgd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) && defined(CONFIG_X86_64_SMP) + p4d_t *p4d; +#endif pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -1752,31 +1755,42 @@ static int pager_req_pfn(ihk_os_t os, uintptr_t handle, off_t off, uintptr_t ppf retry: pgd = pgd_offset(current->mm, va); if (!pgd_none(*pgd) && !pgd_bad(*pgd) && pgd_present(*pgd)) { - pud = pud_offset(pgd, va); - if (!pud_none(*pud) && !pud_bad(*pud) && pud_present(*pud)) { - pmd = pmd_offset(pud, va); - if (!pmd_none(*pmd) && !pmd_bad(*pmd) && pmd_present(*pmd)) { - pte = pte_offset_map(pmd, va); - if (!pte_none(*pte) && pte_present(*pte)) { - pfn = (uintptr_t)pte_pfn(*pte) << PAGE_SHIFT; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) && defined(CONFIG_X86_64_SMP) + p4d = p4d_offset(pgd, va); + if (!p4d_none(*p4d) && !p4d_bad(*p4d) && p4d_present(*p4d)) { + pud = pud_offset(p4d, va); +#else + pud = pud_offset(pgd, va); +#endif + if (!pud_none(*pud) && !pud_bad(*pud) && + pud_present(*pud)) { + pmd = pmd_offset(pud, va); + if (!pmd_none(*pmd) && !pmd_bad(*pmd) && + pmd_present(*pmd)) { + pte = pte_offset_map(pmd, va); + if (!pte_none(*pte) && pte_present(*pte)) { + pfn = (uintptr_t)pte_pfn(*pte) << PAGE_SHIFT; #define PFN_PRESENT ((uintptr_t)1 << 0) - pfn |= PFN_VALID | PFN_PRESENT; - - /* Check if mapping is write-combined */ + pfn |= PFN_VALID | PFN_PRESENT; + + /* Check if mapping is write-combined */ #ifdef POSTK_DEBUG_ARCH_DEP_12 - if (pte_is_write_combined(*pte)) { - pfn |= PFN_WRITE_COMBINED; - } + if (pte_is_write_combined(*pte)) { + pfn |= PFN_WRITE_COMBINED; + } #else /* POSTK_DEBUG_ARCH_DEP_12 */ - if ((pte_flags(*pte) & _PAGE_PWT) && - !(pte_flags(*pte) & _PAGE_PCD)) { - pfn |= _PAGE_PWT; - } + if ((pte_flags(*pte) & _PAGE_PWT) && + !(pte_flags(*pte) & _PAGE_PCD)) { + pfn |= _PAGE_PWT; + } #endif /* POSTK_DEBUG_ARCH_DEP_12 */ + } + pte_unmap(pte); } - pte_unmap(pte); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) && defined(CONFIG_X86_64_SMP) } +#endif } /* If not present, try to fault it */