Implement pmap_page_is_mapped() correctly on arm64 and riscv.
We must also check for large mappings. pmap_page_is_mapped() is mostly used in assertions, so the problem was not very noticeable. Reviewed by: alc MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D21824
This commit is contained in:
parent
d3588766e1
commit
d4586dd328
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352826
@ -4240,6 +4240,27 @@ pmap_page_wired_mappings(vm_page_t m)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the given page is mapped individually or as part of
|
||||
* a 2mpage. Otherwise, returns false.
|
||||
*/
|
||||
bool
|
||||
pmap_page_is_mapped(vm_page_t m)
|
||||
{
|
||||
struct rwlock *lock;
|
||||
bool rv;
|
||||
|
||||
if ((m->oflags & VPO_UNMANAGED) != 0)
|
||||
return (false);
|
||||
lock = VM_PAGE_TO_PV_LIST_LOCK(m);
|
||||
rw_rlock(lock);
|
||||
rv = !TAILQ_EMPTY(&m->md.pv_list) ||
|
||||
((m->flags & PG_FICTITIOUS) == 0 &&
|
||||
!TAILQ_EMPTY(&pa_to_pvh(VM_PAGE_TO_PHYS(m))->pv_list));
|
||||
rw_runlock(lock);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy all managed, non-wired mappings in the given user-space
|
||||
* pmap. This pmap cannot be active on any processor besides the
|
||||
|
@ -150,6 +150,7 @@ vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
void *pmap_mapdev_attr(vm_offset_t pa, vm_size_t size, vm_memattr_t ma);
|
||||
bool pmap_page_is_mapped(vm_page_t m);
|
||||
bool pmap_ps_enabled(pmap_t pmap);
|
||||
|
||||
void *pmap_mapdev(vm_offset_t, vm_size_t);
|
||||
@ -167,8 +168,6 @@ int pmap_fault(pmap_t, uint64_t, uint64_t);
|
||||
|
||||
struct pcb *pmap_switch(struct thread *, struct thread *);
|
||||
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
static inline int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
|
||||
{
|
||||
|
@ -146,6 +146,7 @@ void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
bool pmap_page_is_mapped(vm_page_t m);
|
||||
bool pmap_ps_enabled(pmap_t);
|
||||
|
||||
void *pmap_mapdev(vm_offset_t, vm_size_t);
|
||||
@ -159,8 +160,6 @@ void pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
|
||||
bool pmap_get_tables(pmap_t, vm_offset_t, pd_entry_t **, pd_entry_t **,
|
||||
pt_entry_t **);
|
||||
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
int pmap_fault_fixup(pmap_t, vm_offset_t, vm_prot_t);
|
||||
|
||||
static inline int
|
||||
|
@ -3541,6 +3541,27 @@ pmap_page_wired_mappings(vm_page_t m)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the given page is mapped individually or as part of
|
||||
* a 2mpage. Otherwise, returns false.
|
||||
*/
|
||||
bool
|
||||
pmap_page_is_mapped(vm_page_t m)
|
||||
{
|
||||
struct rwlock *lock;
|
||||
bool rv;
|
||||
|
||||
if ((m->oflags & VPO_UNMANAGED) != 0)
|
||||
return (false);
|
||||
lock = VM_PAGE_TO_PV_LIST_LOCK(m);
|
||||
rw_rlock(lock);
|
||||
rv = !TAILQ_EMPTY(&m->md.pv_list) ||
|
||||
((m->flags & PG_FICTITIOUS) == 0 &&
|
||||
!TAILQ_EMPTY(&pa_to_pvh(VM_PAGE_TO_PHYS(m))->pv_list));
|
||||
rw_runlock(lock);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_remove_pages_pv(pmap_t pmap, vm_page_t m, pv_entry_t pv,
|
||||
struct spglist *free, bool superpage)
|
||||
|
Loading…
Reference in New Issue
Block a user