1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun.. _arch_page_table_helpers: 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun=============================== 6*4882a593SmuzhiyunArchitecture Page Table Helpers 7*4882a593Smuzhiyun=============================== 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunGeneric MM expects architectures (with MMU) to provide helpers to create, access 10*4882a593Smuzhiyunand modify page table entries at various level for different memory functions. 11*4882a593SmuzhiyunThese page table helpers need to conform to a common semantics across platforms. 12*4882a593SmuzhiyunFollowing tables describe the expected semantics which can also be tested during 13*4882a593Smuzhiyunboot via CONFIG_DEBUG_VM_PGTABLE option. All future changes in here or the debug 14*4882a593Smuzhiyuntest need to be in sync. 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun====================== 17*4882a593SmuzhiyunPTE Page Table Helpers 18*4882a593Smuzhiyun====================== 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 21*4882a593Smuzhiyun| pte_same | Tests whether both PTE entries are the same | 22*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 23*4882a593Smuzhiyun| pte_bad | Tests a non-table mapped PTE | 24*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 25*4882a593Smuzhiyun| pte_present | Tests a valid mapped PTE | 26*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 27*4882a593Smuzhiyun| pte_young | Tests a young PTE | 28*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 29*4882a593Smuzhiyun| pte_dirty | Tests a dirty PTE | 30*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 31*4882a593Smuzhiyun| pte_write | Tests a writable PTE | 32*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 33*4882a593Smuzhiyun| pte_special | Tests a special PTE | 34*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 35*4882a593Smuzhiyun| pte_protnone | Tests a PROT_NONE PTE | 36*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 37*4882a593Smuzhiyun| pte_devmap | Tests a ZONE_DEVICE mapped PTE | 38*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 39*4882a593Smuzhiyun| pte_soft_dirty | Tests a soft dirty PTE | 40*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 41*4882a593Smuzhiyun| pte_swp_soft_dirty | Tests a soft dirty swapped PTE | 42*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 43*4882a593Smuzhiyun| pte_mkyoung | Creates a young PTE | 44*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 45*4882a593Smuzhiyun| pte_mkold | Creates an old PTE | 46*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 47*4882a593Smuzhiyun| pte_mkdirty | Creates a dirty PTE | 48*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 49*4882a593Smuzhiyun| pte_mkclean | Creates a clean PTE | 50*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 51*4882a593Smuzhiyun| pte_mkwrite | Creates a writable PTE | 52*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 53*4882a593Smuzhiyun| pte_wrprotect | Creates a write protected PTE | 54*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 55*4882a593Smuzhiyun| pte_mkspecial | Creates a special PTE | 56*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 57*4882a593Smuzhiyun| pte_mkdevmap | Creates a ZONE_DEVICE mapped PTE | 58*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 59*4882a593Smuzhiyun| pte_mksoft_dirty | Creates a soft dirty PTE | 60*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 61*4882a593Smuzhiyun| pte_clear_soft_dirty | Clears a soft dirty PTE | 62*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 63*4882a593Smuzhiyun| pte_swp_mksoft_dirty | Creates a soft dirty swapped PTE | 64*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 65*4882a593Smuzhiyun| pte_swp_clear_soft_dirty | Clears a soft dirty swapped PTE | 66*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 67*4882a593Smuzhiyun| pte_mknotpresent | Invalidates a mapped PTE | 68*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 69*4882a593Smuzhiyun| ptep_get_and_clear | Clears a PTE | 70*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 71*4882a593Smuzhiyun| ptep_get_and_clear_full | Clears a PTE | 72*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 73*4882a593Smuzhiyun| ptep_test_and_clear_young | Clears young from a PTE | 74*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 75*4882a593Smuzhiyun| ptep_set_wrprotect | Converts into a write protected PTE | 76*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 77*4882a593Smuzhiyun| ptep_set_access_flags | Converts into a more permissive PTE | 78*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun====================== 81*4882a593SmuzhiyunPMD Page Table Helpers 82*4882a593Smuzhiyun====================== 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 85*4882a593Smuzhiyun| pmd_same | Tests whether both PMD entries are the same | 86*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 87*4882a593Smuzhiyun| pmd_bad | Tests a non-table mapped PMD | 88*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 89*4882a593Smuzhiyun| pmd_leaf | Tests a leaf mapped PMD | 90*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 91*4882a593Smuzhiyun| pmd_huge | Tests a HugeTLB mapped PMD | 92*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 93*4882a593Smuzhiyun| pmd_trans_huge | Tests a Transparent Huge Page (THP) at PMD | 94*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 95*4882a593Smuzhiyun| pmd_present | Tests a valid mapped PMD | 96*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 97*4882a593Smuzhiyun| pmd_young | Tests a young PMD | 98*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 99*4882a593Smuzhiyun| pmd_dirty | Tests a dirty PMD | 100*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 101*4882a593Smuzhiyun| pmd_write | Tests a writable PMD | 102*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 103*4882a593Smuzhiyun| pmd_special | Tests a special PMD | 104*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 105*4882a593Smuzhiyun| pmd_protnone | Tests a PROT_NONE PMD | 106*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 107*4882a593Smuzhiyun| pmd_devmap | Tests a ZONE_DEVICE mapped PMD | 108*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 109*4882a593Smuzhiyun| pmd_soft_dirty | Tests a soft dirty PMD | 110*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 111*4882a593Smuzhiyun| pmd_swp_soft_dirty | Tests a soft dirty swapped PMD | 112*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 113*4882a593Smuzhiyun| pmd_mkyoung | Creates a young PMD | 114*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 115*4882a593Smuzhiyun| pmd_mkold | Creates an old PMD | 116*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 117*4882a593Smuzhiyun| pmd_mkdirty | Creates a dirty PMD | 118*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 119*4882a593Smuzhiyun| pmd_mkclean | Creates a clean PMD | 120*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 121*4882a593Smuzhiyun| pmd_mkwrite | Creates a writable PMD | 122*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 123*4882a593Smuzhiyun| pmd_wrprotect | Creates a write protected PMD | 124*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 125*4882a593Smuzhiyun| pmd_mkspecial | Creates a special PMD | 126*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 127*4882a593Smuzhiyun| pmd_mkdevmap | Creates a ZONE_DEVICE mapped PMD | 128*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 129*4882a593Smuzhiyun| pmd_mksoft_dirty | Creates a soft dirty PMD | 130*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 131*4882a593Smuzhiyun| pmd_clear_soft_dirty | Clears a soft dirty PMD | 132*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 133*4882a593Smuzhiyun| pmd_swp_mksoft_dirty | Creates a soft dirty swapped PMD | 134*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 135*4882a593Smuzhiyun| pmd_swp_clear_soft_dirty | Clears a soft dirty swapped PMD | 136*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 137*4882a593Smuzhiyun| pmd_mkinvalid | Invalidates a mapped PMD [1] | 138*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 139*4882a593Smuzhiyun| pmd_set_huge | Creates a PMD huge mapping | 140*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 141*4882a593Smuzhiyun| pmd_clear_huge | Clears a PMD huge mapping | 142*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 143*4882a593Smuzhiyun| pmdp_get_and_clear | Clears a PMD | 144*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 145*4882a593Smuzhiyun| pmdp_get_and_clear_full | Clears a PMD | 146*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 147*4882a593Smuzhiyun| pmdp_test_and_clear_young | Clears young from a PMD | 148*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 149*4882a593Smuzhiyun| pmdp_set_wrprotect | Converts into a write protected PMD | 150*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 151*4882a593Smuzhiyun| pmdp_set_access_flags | Converts into a more permissive PMD | 152*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun====================== 155*4882a593SmuzhiyunPUD Page Table Helpers 156*4882a593Smuzhiyun====================== 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 159*4882a593Smuzhiyun| pud_same | Tests whether both PUD entries are the same | 160*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 161*4882a593Smuzhiyun| pud_bad | Tests a non-table mapped PUD | 162*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 163*4882a593Smuzhiyun| pud_leaf | Tests a leaf mapped PUD | 164*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 165*4882a593Smuzhiyun| pud_huge | Tests a HugeTLB mapped PUD | 166*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 167*4882a593Smuzhiyun| pud_trans_huge | Tests a Transparent Huge Page (THP) at PUD | 168*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 169*4882a593Smuzhiyun| pud_present | Tests a valid mapped PUD | 170*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 171*4882a593Smuzhiyun| pud_young | Tests a young PUD | 172*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 173*4882a593Smuzhiyun| pud_dirty | Tests a dirty PUD | 174*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 175*4882a593Smuzhiyun| pud_write | Tests a writable PUD | 176*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 177*4882a593Smuzhiyun| pud_devmap | Tests a ZONE_DEVICE mapped PUD | 178*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 179*4882a593Smuzhiyun| pud_mkyoung | Creates a young PUD | 180*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 181*4882a593Smuzhiyun| pud_mkold | Creates an old PUD | 182*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 183*4882a593Smuzhiyun| pud_mkdirty | Creates a dirty PUD | 184*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 185*4882a593Smuzhiyun| pud_mkclean | Creates a clean PUD | 186*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 187*4882a593Smuzhiyun| pud_mkwrite | Creates a writable PUD | 188*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 189*4882a593Smuzhiyun| pud_wrprotect | Creates a write protected PUD | 190*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 191*4882a593Smuzhiyun| pud_mkdevmap | Creates a ZONE_DEVICE mapped PUD | 192*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 193*4882a593Smuzhiyun| pud_mkinvalid | Invalidates a mapped PUD [1] | 194*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 195*4882a593Smuzhiyun| pud_set_huge | Creates a PUD huge mapping | 196*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 197*4882a593Smuzhiyun| pud_clear_huge | Clears a PUD huge mapping | 198*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 199*4882a593Smuzhiyun| pudp_get_and_clear | Clears a PUD | 200*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 201*4882a593Smuzhiyun| pudp_get_and_clear_full | Clears a PUD | 202*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 203*4882a593Smuzhiyun| pudp_test_and_clear_young | Clears young from a PUD | 204*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 205*4882a593Smuzhiyun| pudp_set_wrprotect | Converts into a write protected PUD | 206*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 207*4882a593Smuzhiyun| pudp_set_access_flags | Converts into a more permissive PUD | 208*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun========================== 211*4882a593SmuzhiyunHugeTLB Page Table Helpers 212*4882a593Smuzhiyun========================== 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 215*4882a593Smuzhiyun| pte_huge | Tests a HugeTLB | 216*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 217*4882a593Smuzhiyun| pte_mkhuge | Creates a HugeTLB | 218*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 219*4882a593Smuzhiyun| huge_pte_dirty | Tests a dirty HugeTLB | 220*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 221*4882a593Smuzhiyun| huge_pte_write | Tests a writable HugeTLB | 222*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 223*4882a593Smuzhiyun| huge_pte_mkdirty | Creates a dirty HugeTLB | 224*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 225*4882a593Smuzhiyun| huge_pte_mkwrite | Creates a writable HugeTLB | 226*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 227*4882a593Smuzhiyun| huge_pte_wrprotect | Creates a write protected HugeTLB | 228*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 229*4882a593Smuzhiyun| huge_ptep_get_and_clear | Clears a HugeTLB | 230*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 231*4882a593Smuzhiyun| huge_ptep_set_wrprotect | Converts into a write protected HugeTLB | 232*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 233*4882a593Smuzhiyun| huge_ptep_set_access_flags | Converts into a more permissive HugeTLB | 234*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun======================== 237*4882a593SmuzhiyunSWAP Page Table Helpers 238*4882a593Smuzhiyun======================== 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 241*4882a593Smuzhiyun| __pte_to_swp_entry | Creates a swapped entry (arch) from a mapped PTE | 242*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 243*4882a593Smuzhiyun| __swp_to_pte_entry | Creates a mapped PTE from a swapped entry (arch) | 244*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 245*4882a593Smuzhiyun| __pmd_to_swp_entry | Creates a swapped entry (arch) from a mapped PMD | 246*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 247*4882a593Smuzhiyun| __swp_to_pmd_entry | Creates a mapped PMD from a swapped entry (arch) | 248*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 249*4882a593Smuzhiyun| is_migration_entry | Tests a migration (read or write) swapped entry | 250*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 251*4882a593Smuzhiyun| is_write_migration_entry | Tests a write migration swapped entry | 252*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 253*4882a593Smuzhiyun| make_migration_entry_read | Converts into read migration swapped entry | 254*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 255*4882a593Smuzhiyun| make_migration_entry | Creates a migration swapped entry (read or write)| 256*4882a593Smuzhiyun+---------------------------+--------------------------------------------------+ 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun[1] https://lore.kernel.org/linux-mm/20181017020930.GN30832@redhat.com/ 259