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)
Wed, Jan 21, 9:55 PM
Unknown Object (File)
Dec 5 2025, 10:18 PM
Unknown Object (File)
Nov 28 2025, 1:12 AM
Unknown Object (File)
Nov 24 2025, 10:31 PM
Unknown Object (File)
Nov 23 2025, 12:47 PM
Unknown Object (File)
Nov 20 2025, 9:06 AM
Unknown Object (File)
Nov 18 2025, 3:20 PM
Unknown Object (File)
Nov 15 2025, 11:18 PM

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