Fix pmap_is_prefaultable() on arm64 and riscv

The current implementations never correctly return TRUE. In all cases,
when they currently return TRUE, they should have returned FALSE.  And,
in some cases, when they currently return FALSE, they should have
returned TRUE.  Except for its effects on performance, specifically,
additional page faults and pointless calls to pmap_enter_quick() that
abort, this error is harmless.  That is why it has gone unnoticed.

Add a comment to the amd64, arm64, and riscv implementations
describing how their return values are computed.

Reviewed by:	kib, markj
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D33659
This commit is contained in:
Alan Cox 2021-12-24 21:54:01 -06:00
parent 23ba59fbfb
commit e161dfa918
3 changed files with 19 additions and 4 deletions

View File

@ -8567,6 +8567,11 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
boolean_t rv;
PG_V = pmap_valid_bit(pmap);
/*
* Return TRUE if and only if the PTE for the specified virtual
* address is allocated but invalid.
*/
rv = FALSE;
PMAP_LOCK(pmap);
pde = pmap_pde(pmap, addr);

View File

@ -5246,15 +5246,21 @@ pmap_is_modified(vm_page_t m)
boolean_t
pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
{
pd_entry_t *pde;
pt_entry_t *pte;
boolean_t rv;
int lvl;
/*
* Return TRUE if and only if the L3 entry for the specified virtual
* address is allocated but invalid.
*/
rv = FALSE;
PMAP_LOCK(pmap);
pte = pmap_pte(pmap, addr, &lvl);
if (pte != NULL && pmap_load(pte) != 0) {
rv = TRUE;
pde = pmap_pde(pmap, addr, &lvl);
if (pde != NULL && lvl == 2) {
pte = pmap_l2_to_l3(pde, addr);
rv = pmap_load(pte) == 0;
}
PMAP_UNLOCK(pmap);
return (rv);

View File

@ -3850,10 +3850,14 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
pt_entry_t *l3;
boolean_t rv;
/*
* Return TRUE if and only if the L3 entry for the specified virtual
* address is allocated but invalid.
*/
rv = FALSE;
PMAP_LOCK(pmap);
l3 = pmap_l3(pmap, addr);
if (l3 != NULL && pmap_load(l3) != 0) {
if (l3 != NULL && pmap_load(l3) == 0) {
rv = TRUE;
}
PMAP_UNLOCK(pmap);