Page MenuHomeFreeBSD

amd64/arm64: Eliminate unnecessary demotions in pmap_protect()
ClosedPublic

Authored by alc on Jul 5 2024, 6:55 PM.
Tags
None
Referenced Files
Unknown Object (File)
Aug 21 2025, 11:03 AM
Unknown Object (File)
Aug 17 2025, 7:31 AM
Unknown Object (File)
Aug 14 2025, 12:46 PM
Unknown Object (File)
Aug 12 2025, 7:34 PM
Unknown Object (File)
Aug 2 2025, 11:23 AM
Unknown Object (File)
Jul 21 2025, 1:43 PM
Unknown Object (File)
Jul 21 2025, 1:40 PM
Unknown Object (File)
Jul 21 2025, 7:17 AM

Details

Summary

In pmap_protect(), when the mapping isn't changing, we don't need to perform a superpage demotion, even though the requested change doesn't cover the entire superpage.

Test Plan

Consider the first of @andrew 's recent test programs:

// panic: pmap_demote_l3c: missing ATTR_CONTIGUOUS

#include <sys/mman.h>

#include <assert.h>
#include <stddef.h>

int
main(int argc, char *argv[])
{
        char *addr;

        addr = mmap(NULL, 0x1000000, PROT_READ | PROT_WRITE,
            MAP_ANON | MAP_PRIVATE, -1, 0);
        assert(addr != MAP_FAILED);

        mlock(addr, 0x800000);
        mprotect(addr, 0x400000, PROT_READ | PROT_WRITE);
        mprotect(addr, 0x2000, PROT_WRITE);
        mprotect(addr, 0x400000, PROT_READ | PROT_WRITE);
        return (0);
}

At first, I was surprised that this program was performing a demotion before crashing on arm64, because vm_map_protect() tries to avoid pointless calls to pmap_protect(). However, the absence of PROT_READ from the second mprotect() is seen by vm_map_protect() as removing read access at the machine-independent level, and so it calls pmap_protect().

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable