Date: Tue, 1 Sep 2020 11:02:43 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r365031 - head/sys/arm64/arm64 Message-ID: <202009011102.081B2hCZ039841@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andrew Date: Tue Sep 1 11:02:43 2020 New Revision: 365031 URL: https://svnweb.freebsd.org/changeset/base/365031 Log: Support stage 2 arm64 pmap in more places Add support for stage 2 pmap to pmap_pte_dirty, pmap_release, and more of pmap_enter. This adds support in all placess I have hit while testing bhyve ehile faulting pages in as needed. Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D26065 Modified: head/sys/arm64/arm64/pmap.c Modified: head/sys/arm64/arm64/pmap.c ============================================================================== --- head/sys/arm64/arm64/pmap.c Tue Sep 1 09:02:43 2020 (r365030) +++ head/sys/arm64/arm64/pmap.c Tue Sep 1 11:02:43 2020 (r365031) @@ -662,13 +662,18 @@ static inline int pmap_pte_dirty(pmap_t pmap, pt_entry_t pte) { - PMAP_ASSERT_STAGE1(pmap); KASSERT((pte & ATTR_SW_MANAGED) != 0, ("pte %#lx is unmanaged", pte)); - KASSERT((pte & (ATTR_S1_AP_RW_BIT | ATTR_SW_DBM)) != 0, - ("pte %#lx is writeable and missing ATTR_SW_DBM", pte)); - return ((pte & (ATTR_S1_AP_RW_BIT | ATTR_SW_DBM)) == - (ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_SW_DBM)); + if (pmap->pm_stage == PM_STAGE1) { + KASSERT((pte & (ATTR_S1_AP_RW_BIT | ATTR_SW_DBM)) != 0, + ("pte %#lx is writeable and missing ATTR_SW_DBM", pte)); + + return ((pte & (ATTR_S1_AP_RW_BIT | ATTR_SW_DBM)) == + (ATTR_S1_AP(ATTR_S1_AP_RW) | ATTR_SW_DBM)); + } + + return ((pte & ATTR_S2_S2AP(ATTR_S2_S2AP_WRITE)) == + ATTR_S2_S2AP(ATTR_S2_S2AP_WRITE)); } static __inline void @@ -1940,20 +1945,27 @@ pmap_release(pmap_t pmap) pmap->pm_stats.resident_count)); KASSERT(vm_radix_is_empty(&pmap->pm_root), ("pmap_release: pmap has reserved page table page(s)")); - PMAP_ASSERT_STAGE1(pmap); set = pmap->pm_asid_set; KASSERT(set != NULL, ("%s: NULL asid set", __func__)); - mtx_lock_spin(&set->asid_set_mutex); - if (COOKIE_TO_EPOCH(pmap->pm_cookie) == set->asid_epoch) { - asid = COOKIE_TO_ASID(pmap->pm_cookie); - KASSERT(asid >= ASID_FIRST_AVAILABLE && - asid < set->asid_set_size, - ("pmap_release: pmap cookie has out-of-range asid")); - bit_clear(set->asid_set, asid); + /* + * Allow the ASID to be reused. In stage 2 VMIDs we don't invalidate + * the entries when removing them so rely on a later tlb invalidation. + * this will happen when updating the VMID generation. Because of this + * we don't reuse VMIDs within a generation. + */ + if (pmap->pm_stage == PM_STAGE1) { + mtx_lock_spin(&set->asid_set_mutex); + if (COOKIE_TO_EPOCH(pmap->pm_cookie) == set->asid_epoch) { + asid = COOKIE_TO_ASID(pmap->pm_cookie); + KASSERT(asid >= ASID_FIRST_AVAILABLE && + asid < set->asid_set_size, + ("pmap_release: pmap cookie has out-of-range asid")); + bit_clear(set->asid_set, asid); + } + mtx_unlock_spin(&set->asid_set_mutex); } - mtx_unlock_spin(&set->asid_set_mutex); m = PHYS_TO_VM_PAGE(pmap->pm_l0_paddr); vm_page_unwire_noq(m); @@ -3464,8 +3476,11 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, v if ((prot & VM_PROT_WRITE) != 0) { new_l3 |= ATTR_SW_DBM; if ((flags & VM_PROT_WRITE) == 0) { - PMAP_ASSERT_STAGE1(pmap); - new_l3 |= ATTR_S1_AP(ATTR_S1_AP_RO); + if (pmap->pm_stage == PM_STAGE1) + new_l3 |= ATTR_S1_AP(ATTR_S1_AP_RO); + else + new_l3 &= + ~ATTR_S2_S2AP(ATTR_S2_S2AP_WRITE); } } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009011102.081B2hCZ039841>