From d7a209ef00aa9cf7bb561ea7a82444bbf7cf271c Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 23 Feb 2023 13:55:00 -0500 Subject: [PATCH 50/52] mips: Assert that pmap_emulate_*() do not encounter largepage mappings Such mappings are unmanaged and thus must always be referenced and dirty. tlb_update() doesn't handle such mappings properly since it may use the wrong PTE. --- sys/mips/mips/pmap_mips64.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/pmap_mips64.c b/sys/mips/mips/pmap_mips64.c index 6f94927ead27..92e8fbdc646f 100644 --- a/sys/mips/mips/pmap_mips64.c +++ b/sys/mips/mips/pmap_mips64.c @@ -5651,9 +5651,16 @@ pmap_emulate_modified(pmap_t pmap, vm_offset_t va) PMAP_LOCK(pmap); pde = pmap_pde(pmap, va); - if (pde_is_superpage(pde)) + if (pde_is_superpage(pde)) { + /* + * tlb_update() doesn't handle the case where a mapping spans + * multiple PDEs, but such mappings should always have the + * dirty bit set. + */ + if (!pde_is_1m_superpage(pde)) + panic("%s: unmanaged largepage mapping", __func__); pte = (pt_entry_t *)pde; - else { + } else { pte = pmap_pde_to_pte(pde, va); } if (pte == NULL) @@ -5701,6 +5708,13 @@ pmap_emulate_referenced(pmap_t pmap, vm_offset_t va) goto dofault; } if (pde_is_superpage(pde)) { + /* + * tlb_update() doesn't handle the case where a mapping spans + * multiple PDEs, but such mappings should always have the + * reference bit set. + */ + if (!pde_is_1m_superpage(pde)) + panic("%s: unmanaged largepage mapping", __func__); pte = (pt_entry_t *)pde; } else { pte = pmap_pde_to_pte(pde, va); -- 2.41.0