Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/mm: Tabulate the page table encoding definitions

I got lost in trying to figure out which bits were enabled
in one of the PTE masks, so let's make it pretty
obvious at the definition site already:

#define PAGE_NONE __pg( 0| 0| 0|___A| 0| 0| 0|___G)
#define PAGE_SHARED __pg(__PP|__RW|_USR|___A|__NX| 0| 0| 0)
#define PAGE_SHARED_EXEC __pg(__PP|__RW|_USR|___A| 0| 0| 0| 0)
#define PAGE_COPY_NOEXEC __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
#define PAGE_COPY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0)
#define PAGE_COPY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
#define PAGE_READONLY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0)
#define PAGE_READONLY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0)

#define __PAGE_KERNEL (__PP|__RW| 0|___A|__NX|___D| 0|___G)
#define __PAGE_KERNEL_EXEC (__PP|__RW| 0|___A| 0|___D| 0|___G)
#define _KERNPG_TABLE_NOENC (__PP|__RW| 0|___A| 0|___D| 0| 0)
#define _KERNPG_TABLE (__PP|__RW| 0|___A| 0|___D| 0| 0| _ENC)
#define _PAGE_TABLE_NOENC (__PP|__RW|_USR|___A| 0|___D| 0| 0)
#define _PAGE_TABLE (__PP|__RW|_USR|___A| 0|___D| 0| 0| _ENC)
#define __PAGE_KERNEL_RO (__PP| 0| 0|___A|__NX|___D| 0|___G)
#define __PAGE_KERNEL_RX (__PP| 0| 0|___A| 0|___D| 0|___G)
#define __PAGE_KERNEL_NOCACHE (__PP|__RW| 0|___A|__NX|___D| 0|___G| __NC)
#define __PAGE_KERNEL_VVAR (__PP| 0|_USR|___A|__NX|___D| 0|___G)
#define __PAGE_KERNEL_LARGE (__PP|__RW| 0|___A|__NX|___D|_PSE|___G)
#define __PAGE_KERNEL_LARGE_EXEC (__PP|__RW| 0|___A| 0|___D|_PSE|___G)
#define __PAGE_KERNEL_WP (__PP|__RW| 0|___A|__NX|___D| 0|___G| __WP)

Especially security relevant bits like 'NX' or coherence related bits like 'G'
are now super easy to read based on a single grep.

We do the underscore gymnastics to not pollute the kernel's symbol namespace,
and the longest line still fits into 80 columns, so this should be readable
for everyone.

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+70 -65
+70 -65
arch/x86/include/asm/pgtable_types.h
··· 110 110 111 111 #define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE) 112 112 113 - #define _PAGE_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |\ 114 - _PAGE_ACCESSED | _PAGE_DIRTY) 115 - #define _KERNPG_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | \ 116 - _PAGE_ACCESSED | _PAGE_DIRTY) 117 - 118 113 /* 119 114 * Set of bits not changed in pte_modify. The pte's 120 115 * protection key is treated like _PAGE_RW, for ··· 131 136 */ 132 137 #ifndef __ASSEMBLY__ 133 138 enum page_cache_mode { 134 - _PAGE_CACHE_MODE_WB = 0, 135 - _PAGE_CACHE_MODE_WC = 1, 139 + _PAGE_CACHE_MODE_WB = 0, 140 + _PAGE_CACHE_MODE_WC = 1, 136 141 _PAGE_CACHE_MODE_UC_MINUS = 2, 137 - _PAGE_CACHE_MODE_UC = 3, 138 - _PAGE_CACHE_MODE_WT = 4, 139 - _PAGE_CACHE_MODE_WP = 5, 140 - _PAGE_CACHE_MODE_NUM = 8 142 + _PAGE_CACHE_MODE_UC = 3, 143 + _PAGE_CACHE_MODE_WT = 4, 144 + _PAGE_CACHE_MODE_WP = 5, 145 + 146 + _PAGE_CACHE_MODE_NUM = 8 141 147 }; 142 148 #endif 143 149 144 - #define _PAGE_CACHE_MASK (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT) 150 + #define _PAGE_ENC (_AT(pteval_t, sme_me_mask)) 151 + 152 + #define _PAGE_CACHE_MASK (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT) 153 + 145 154 #define _PAGE_NOCACHE (cachemode2protval(_PAGE_CACHE_MODE_UC)) 146 155 #define _PAGE_CACHE_WP (cachemode2protval(_PAGE_CACHE_MODE_WP)) 147 156 148 - #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) 149 - #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ 150 - _PAGE_ACCESSED | _PAGE_NX) 157 + #define __PP _PAGE_PRESENT 158 + #define __RW _PAGE_RW 159 + #define _USR _PAGE_USER 160 + #define ___A _PAGE_ACCESSED 161 + #define ___D _PAGE_DIRTY 162 + #define ___G _PAGE_GLOBAL 163 + #define __NX _PAGE_NX 151 164 152 - #define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \ 153 - _PAGE_USER | _PAGE_ACCESSED) 154 - #define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ 155 - _PAGE_ACCESSED | _PAGE_NX) 156 - #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ 157 - _PAGE_ACCESSED) 158 - #define PAGE_COPY PAGE_COPY_NOEXEC 159 - #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \ 160 - _PAGE_ACCESSED | _PAGE_NX) 161 - #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ 162 - _PAGE_ACCESSED) 165 + #define _ENC _PAGE_ENC 166 + #define __WP _PAGE_CACHE_WP 167 + #define __NC _PAGE_NOCACHE 168 + #define _PSE _PAGE_PSE 163 169 164 - #define __PAGE_KERNEL_EXEC \ 165 - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) 166 - #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX) 170 + #define pgprot_val(x) ((x).pgprot) 171 + #define __pgprot(x) ((pgprot_t) { (x) } ) 172 + #define __pg(x) __pgprot(x) 167 173 168 - #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) 169 - #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) 170 - #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_NOCACHE) 171 - #define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER) 172 - #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) 173 - #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) 174 - #define __PAGE_KERNEL_WP (__PAGE_KERNEL | _PAGE_CACHE_WP) 174 + #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) 175 175 176 - #define __PAGE_KERNEL_IO (__PAGE_KERNEL) 177 - #define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE) 176 + #define PAGE_NONE __pg( 0| 0| 0|___A| 0| 0| 0|___G) 177 + #define PAGE_SHARED __pg(__PP|__RW|_USR|___A|__NX| 0| 0| 0) 178 + #define PAGE_SHARED_EXEC __pg(__PP|__RW|_USR|___A| 0| 0| 0| 0) 179 + #define PAGE_COPY_NOEXEC __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0) 180 + #define PAGE_COPY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0) 181 + #define PAGE_COPY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0) 182 + #define PAGE_READONLY __pg(__PP| 0|_USR|___A|__NX| 0| 0| 0) 183 + #define PAGE_READONLY_EXEC __pg(__PP| 0|_USR|___A| 0| 0| 0| 0) 184 + 185 + #define __PAGE_KERNEL (__PP|__RW| 0|___A|__NX|___D| 0|___G) 186 + #define __PAGE_KERNEL_EXEC (__PP|__RW| 0|___A| 0|___D| 0|___G) 187 + #define _KERNPG_TABLE_NOENC (__PP|__RW| 0|___A| 0|___D| 0| 0) 188 + #define _KERNPG_TABLE (__PP|__RW| 0|___A| 0|___D| 0| 0| _ENC) 189 + #define _PAGE_TABLE_NOENC (__PP|__RW|_USR|___A| 0|___D| 0| 0) 190 + #define _PAGE_TABLE (__PP|__RW|_USR|___A| 0|___D| 0| 0| _ENC) 191 + #define __PAGE_KERNEL_RO (__PP| 0| 0|___A|__NX|___D| 0|___G) 192 + #define __PAGE_KERNEL_RX (__PP| 0| 0|___A| 0|___D| 0|___G) 193 + #define __PAGE_KERNEL_NOCACHE (__PP|__RW| 0|___A|__NX|___D| 0|___G| __NC) 194 + #define __PAGE_KERNEL_VVAR (__PP| 0|_USR|___A|__NX|___D| 0|___G) 195 + #define __PAGE_KERNEL_LARGE (__PP|__RW| 0|___A|__NX|___D|_PSE|___G) 196 + #define __PAGE_KERNEL_LARGE_EXEC (__PP|__RW| 0|___A| 0|___D|_PSE|___G) 197 + #define __PAGE_KERNEL_WP (__PP|__RW| 0|___A|__NX|___D| 0|___G| __WP) 198 + 199 + 200 + #define __PAGE_KERNEL_IO __PAGE_KERNEL 201 + #define __PAGE_KERNEL_IO_NOCACHE __PAGE_KERNEL_NOCACHE 202 + 178 203 179 204 #ifndef __ASSEMBLY__ 180 205 181 - #define _PAGE_ENC (_AT(pteval_t, sme_me_mask)) 206 + #define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _ENC) 207 + #define __PAGE_KERNEL_ENC_WP (__PAGE_KERNEL_WP | _ENC) 208 + #define __PAGE_KERNEL_NOENC (__PAGE_KERNEL | 0) 209 + #define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP | 0) 182 210 183 - #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ 184 - _PAGE_DIRTY | _PAGE_ENC) 185 - #define _PAGE_TABLE (_KERNPG_TABLE | _PAGE_USER) 211 + #define __pgprot_mask(x) __pgprot((x) & __default_kernel_pte_mask) 186 212 187 - #define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _PAGE_ENC) 188 - #define __PAGE_KERNEL_ENC_WP (__PAGE_KERNEL_WP | _PAGE_ENC) 213 + #define PAGE_KERNEL __pgprot_mask(__PAGE_KERNEL | _ENC) 214 + #define PAGE_KERNEL_NOENC __pgprot_mask(__PAGE_KERNEL | 0) 215 + #define PAGE_KERNEL_RO __pgprot_mask(__PAGE_KERNEL_RO | _ENC) 216 + #define PAGE_KERNEL_EXEC __pgprot_mask(__PAGE_KERNEL_EXEC | _ENC) 217 + #define PAGE_KERNEL_EXEC_NOENC __pgprot_mask(__PAGE_KERNEL_EXEC | 0) 218 + #define PAGE_KERNEL_RX __pgprot_mask(__PAGE_KERNEL_RX | _ENC) 219 + #define PAGE_KERNEL_NOCACHE __pgprot_mask(__PAGE_KERNEL_NOCACHE | _ENC) 220 + #define PAGE_KERNEL_LARGE __pgprot_mask(__PAGE_KERNEL_LARGE | _ENC) 221 + #define PAGE_KERNEL_LARGE_EXEC __pgprot_mask(__PAGE_KERNEL_LARGE_EXEC | _ENC) 222 + #define PAGE_KERNEL_VVAR __pgprot_mask(__PAGE_KERNEL_VVAR | _ENC) 189 223 190 - #define __PAGE_KERNEL_NOENC (__PAGE_KERNEL) 191 - #define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP) 192 - 193 - #define default_pgprot(x) __pgprot((x) & __default_kernel_pte_mask) 194 - 195 - #define PAGE_KERNEL default_pgprot(__PAGE_KERNEL | _PAGE_ENC) 196 - #define PAGE_KERNEL_NOENC default_pgprot(__PAGE_KERNEL) 197 - #define PAGE_KERNEL_RO default_pgprot(__PAGE_KERNEL_RO | _PAGE_ENC) 198 - #define PAGE_KERNEL_EXEC default_pgprot(__PAGE_KERNEL_EXEC | _PAGE_ENC) 199 - #define PAGE_KERNEL_EXEC_NOENC default_pgprot(__PAGE_KERNEL_EXEC) 200 - #define PAGE_KERNEL_RX default_pgprot(__PAGE_KERNEL_RX | _PAGE_ENC) 201 - #define PAGE_KERNEL_NOCACHE default_pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) 202 - #define PAGE_KERNEL_LARGE default_pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) 203 - #define PAGE_KERNEL_LARGE_EXEC default_pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) 204 - #define PAGE_KERNEL_VVAR default_pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) 205 - 206 - #define PAGE_KERNEL_IO default_pgprot(__PAGE_KERNEL_IO) 207 - #define PAGE_KERNEL_IO_NOCACHE default_pgprot(__PAGE_KERNEL_IO_NOCACHE) 224 + #define PAGE_KERNEL_IO __pgprot_mask(__PAGE_KERNEL_IO) 225 + #define PAGE_KERNEL_IO_NOCACHE __pgprot_mask(__PAGE_KERNEL_IO_NOCACHE) 208 226 209 227 #endif /* __ASSEMBLY__ */ 210 228 ··· 456 448 { 457 449 return native_pte_val(pte) & PTE_FLAGS_MASK; 458 450 } 459 - 460 - #define pgprot_val(x) ((x).pgprot) 461 - #define __pgprot(x) ((pgprot_t) { (x) } ) 462 451 463 452 extern uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM]; 464 453 extern uint8_t __pte2cachemode_tbl[8];