MFC r349117, r349122, r349183, r349897, r349943, r350004, r350029, r350038,
r350191, r350202, r350422, r350427, r350525
r349117:
Three enhancements to arm64's pmap_protect(): Implement protection changes on superpage mappings. Previously, a superpage mapping was unconditionally demoted by pmap_protect(), even if the protection change applied to the entire superpage mapping. Precompute the bit mask describing the protection changes rather than recomputing it for every page table entry that is changed. Skip page table entries that already have the requested protection changes in place.
r349122:
Three changes to arm64's pmap_unwire(): Implement wiring changes on superpage mappings. Previously, a superpage mapping was unconditionally demoted by pmap_unwire(), even if the wiring change applied to the entire superpage mapping. Rewrite a comment to use the arm64 names for bits in a page table entry. Previously, the bits were referred to by their x86 names. Use atomic_"op"_64() instead of atomic_"op"_long() to update a page table entry in order to match the prevailing style in this file.
r349183:
Correct an error in r349122. pmap_unwire() should update the pmap's wired count, not its resident count.
r349897: (by markj)
Rename pmap_page_dirty() to pmap_pte_dirty(). This is a precursor to implementing dirty bit management.
r349943: (by markj)
Apply some light cleanup to uses of pmap_pte_dirty(). - Check for ATTR_SW_MANAGED before anything else. - Use pmap_pte_dirty() in pmap_remove_pages().
r350004: (by markj)
Implement software access and dirty bit management for arm64. Previously the arm64 pmap did no reference or modification tracking; all mappings were treated as referenced and all read-write mappings were treated as dirty. This change implements software management of these attributes. Dirty bit management is implemented to emulate ARMv8.1's optional hardware dirty bit modifier management, following a suggestion from alc. In particular, a mapping with ATTR_SW_DBM set is logically writeable and is dirty if the ATTR_AP_RW_BIT bit is clear. Mappings with ATTR_AP_RW_BIT set are write-protected, and a write access will trigger a permission fault. pmap_fault() handles permission faults for such mappings and marks the page dirty by clearing ATTR_AP_RW_BIT, thus mapping the page read-write.
r350029: (by markj)
Propagate attribute changes during demotion. After r349117 and r349122, some mapping attribute changes do not trigger superpage demotion. However, pmap_demote_l2() was not updated to ensure that the replacement L3 entries carry any attribute changes that occurred since promotion.
r350038: (by markj)
Always use the software DBM bit for now. r350004 added most of the machinery needed to support hardware DBM management, but it did not intend to actually enable use of the hardware DBM bit.
r350191:
Introduce pmap_store(), and use it to replace pmap_load_store() in places where the page table entry was previously invalid. (Note that I did not replace pmap_load_store() when it was followed by a TLB invalidation, even if we are not using the return value from pmap_load_store().) Correct an error in pmap_enter(). A test for determining when to set PGA_WRITEABLE was always true, even if the mapping was read only. In pmap_enter_l2(), when replacing an empty kernel page table page by a superpage mapping, clear the old l2 entry and issue a TLB invalidation. My reading of the ARM architecture manual leads me to believe that the TLB could hold an intermediate entry referencing the empty kernel page table page even though it contains no valid mappings. Replace a couple direct uses of atomic_clear_64() by the new pmap_clear_bits(). In a couple comments, replace the term "paging-structure caches", which is an Intel-specific term for the caches that hold intermediate entries in the page table, with wording that is more consistent with the ARM architecture manual.
r350202:
With the introduction of software dirty bit emulation for managed mappings, we should test ATTR_SW_DBM, not ATTR_AP_RW, to determine whether to set PGA_WRITEABLE. In effect, we are currently setting PGA_WRITEABLE based on whether the dirty bit is preset, not whether the mapping is writeable. Correct this mistake.
r350422: (by markj)
Remove an unneeded trunc_page() in pmap_fault().
r350427: (by markj)
Have arm64's pmap_fault() handle WnR faults on dirty PTEs. If we take a WnR permission fault on a managed, writeable and dirty PTE, simply return success without calling the main fault handler. This situation can occur if multiple threads simultaneously access a clean writeable mapping and trigger WnR faults; losers of the race to mark the PTE dirty would end up calling the main fault handler, which had no work to do.
r350525: (by markj)
Use ATTR_DBM even when hardware dirty bit management is not enabled. The ARMv8 reference manual only states that the bit is reserved in this case; following Linux's example, use it instead of a software-defined bit for the purpose of indicating that a managed mapping is writable.