/* We only try to do i/d cache coherency on stuff that looks like *reasonably"normal"PTEs.WecurrentlyrequireaPTEtobepresent *andweavoid_PAGE_SPECIALandcacheinhibitedpte.Wealsoonlydothat *onuserspacePTEs
*/ staticinlineint pte_looks_normal(pte_t pte, unsignedlong addr)
{
if (pte_present(pte) && !pte_special(pte)) { if (pte_ci(pte)) return0; if (!is_kernel_addr(addr)) return1;
} return0;
}
/* Embedded type MMU with HW exec support. This is a bit more complicated *aswedon'thavetwobitstosparefor_PAGE_EXECand_PAGE_HWEXECso *insteadwe"filterout"theexecpermissionfornoncleanpages. * *Thisisalsocalledonceforthefolio.Soonlyworkwithfolio->flagshere.
*/ staticinline pte_t set_pte_filter(pte_t pte, unsignedlong addr)
{ struct folio *folio;
if (radix_enabled()) return pte;
if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) return set_pte_filter_hash(pte, addr);
/* No exec permission in the first place, move on */ if (!pte_exec(pte) || !pte_looks_normal(pte, addr)) return pte;
/* If you set _PAGE_EXEC on weird pages you're on your own */
folio = maybe_pte_to_folio(pte); if (unlikely(!folio)) return pte;
/* If the page clean, we move on */ if (test_bit(PG_dcache_clean, &folio->flags)) return pte;
/* If it's an exec fault, we flush the cache and make it clean */ if (is_exec_fault()) {
flush_dcache_icache_folio(folio);
set_bit(PG_dcache_clean, &folio->flags); return pte;
}
/* Else, we filter out _PAGE_EXEC */ return pte_exprotect(pte);
}
if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) return pte;
/* So here, we only care about exec faults, as we use them *torecoverlost_PAGE_EXECandperformI$/D$coherency *ifnecessary.Alsoif_PAGE_EXECisalreadyset,samedeal, *wejustbailout
*/ if (dirty || pte_exec(pte) || !is_exec_fault()) return pte;
#ifdef CONFIG_DEBUG_VM /* So this is an exec fault, _PAGE_EXEC is not set. If it was *anerrorwewouldhavebailedoutearlierindo_page_fault() *butlet'smakesureofit
*/ if (WARN_ON(!(vma->vm_flags & VM_EXEC))) return pte; #endif/* CONFIG_DEBUG_VM */
/* If you set _PAGE_EXEC on weird pages you're on your own */
folio = maybe_pte_to_folio(pte); if (unlikely(!folio)) goto bail;
/* If the page is already clean, we move on */ if (test_bit(PG_dcache_clean, &folio->flags)) goto bail;
/* Clean the page and set PG_dcache_clean */
flush_dcache_icache_folio(folio);
set_bit(PG_dcache_clean, &folio->flags);
/* Note: mm->context.id might not yet have been assigned as *thiscontextmightnothavebeenactivatedyetwhenthis *iscalled.Filtertheptevalueandusethefilteredvalue *tosetupalltheptesintherange.
*/
pte = set_pte_filter(pte, addr);
/* *Wedon'tneedtocallarch_enter/leave_lazy_mmu_mode() *becauseweexpectset_ptestobeonlybeusedonnotpresent *andnothw_validptes.Hencethereisnotranslationcacheflush *involvedthatneedtobebatched.
*/ for (;;) {
#ifdefined(CONFIG_SPLIT_PTE_PTLOCKS) || defined(CONFIG_SPLIT_PMD_PTLOCKS) /* We need the same lock to protect the PMD table and the two PTE tables. */ #error"8M hugetlb folios are incompatible with split page table locks" #endif
if (sz == SZ_8M) { /* Flag both PMD entries as 8M and fill both page tables */
*pmdp = __pmd(pmd_val(*pmdp) | _PMD_PAGE_8M);
*(pmdp + 1) = __pmd(pmd_val(*(pmdp + 1)) | _PMD_PAGE_8M);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.13Bemerkung:
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.