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
This commit is contained in:
committed by
Dominique Martinet
parent
c21485d427
commit
03802052ed
@ -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 pfn;
|
||||||
uintptr_t va;
|
uintptr_t va;
|
||||||
pgd_t *pgd;
|
pgd_t *pgd;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) && defined(CONFIG_X86_64_SMP)
|
||||||
|
p4d_t *p4d;
|
||||||
|
#endif
|
||||||
pud_t *pud;
|
pud_t *pud;
|
||||||
pmd_t *pmd;
|
pmd_t *pmd;
|
||||||
pte_t *pte;
|
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:
|
retry:
|
||||||
pgd = pgd_offset(current->mm, va);
|
pgd = pgd_offset(current->mm, va);
|
||||||
if (!pgd_none(*pgd) && !pgd_bad(*pgd) && pgd_present(*pgd)) {
|
if (!pgd_none(*pgd) && !pgd_bad(*pgd) && pgd_present(*pgd)) {
|
||||||
pud = pud_offset(pgd, va);
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) && defined(CONFIG_X86_64_SMP)
|
||||||
if (!pud_none(*pud) && !pud_bad(*pud) && pud_present(*pud)) {
|
p4d = p4d_offset(pgd, va);
|
||||||
pmd = pmd_offset(pud, va);
|
if (!p4d_none(*p4d) && !p4d_bad(*p4d) && p4d_present(*p4d)) {
|
||||||
if (!pmd_none(*pmd) && !pmd_bad(*pmd) && pmd_present(*pmd)) {
|
pud = pud_offset(p4d, va);
|
||||||
pte = pte_offset_map(pmd, va);
|
#else
|
||||||
if (!pte_none(*pte) && pte_present(*pte)) {
|
pud = pud_offset(pgd, va);
|
||||||
pfn = (uintptr_t)pte_pfn(*pte) << PAGE_SHIFT;
|
#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)
|
#define PFN_PRESENT ((uintptr_t)1 << 0)
|
||||||
pfn |= PFN_VALID | PFN_PRESENT;
|
pfn |= PFN_VALID | PFN_PRESENT;
|
||||||
|
|
||||||
/* Check if mapping is write-combined */
|
/* Check if mapping is write-combined */
|
||||||
#ifdef POSTK_DEBUG_ARCH_DEP_12
|
#ifdef POSTK_DEBUG_ARCH_DEP_12
|
||||||
if (pte_is_write_combined(*pte)) {
|
if (pte_is_write_combined(*pte)) {
|
||||||
pfn |= PFN_WRITE_COMBINED;
|
pfn |= PFN_WRITE_COMBINED;
|
||||||
}
|
}
|
||||||
#else /* POSTK_DEBUG_ARCH_DEP_12 */
|
#else /* POSTK_DEBUG_ARCH_DEP_12 */
|
||||||
if ((pte_flags(*pte) & _PAGE_PWT) &&
|
if ((pte_flags(*pte) & _PAGE_PWT) &&
|
||||||
!(pte_flags(*pte) & _PAGE_PCD)) {
|
!(pte_flags(*pte) & _PAGE_PCD)) {
|
||||||
pfn |= _PAGE_PWT;
|
pfn |= _PAGE_PWT;
|
||||||
}
|
}
|
||||||
#endif /* POSTK_DEBUG_ARCH_DEP_12 */
|
#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 */
|
/* If not present, try to fault it */
|
||||||
|
|||||||
Reference in New Issue
Block a user