diff options
| -rw-r--r-- | arch/x86/entry/calling.h | 36 | ||||
| -rw-r--r-- | arch/x86/include/asm/processor-flags.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/tlbflush.h | 6 |
3 files changed, 23 insertions, 21 deletions
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 45a63e00a6af..3f48f695d5e6 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h | |||
| @@ -198,8 +198,11 @@ For 32-bit we have the following conventions - kernel is built with | |||
| 198 | * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two | 198 | * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two |
| 199 | * halves: | 199 | * halves: |
| 200 | */ | 200 | */ |
| 201 | #define PTI_SWITCH_PGTABLES_MASK (1<<PAGE_SHIFT) | 201 | #define PTI_USER_PGTABLE_BIT PAGE_SHIFT |
| 202 | #define PTI_SWITCH_MASK (PTI_SWITCH_PGTABLES_MASK|(1<<X86_CR3_PTI_SWITCH_BIT)) | 202 | #define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT) |
| 203 | #define PTI_USER_PCID_BIT X86_CR3_PTI_PCID_USER_BIT | ||
| 204 | #define PTI_USER_PCID_MASK (1 << PTI_USER_PCID_BIT) | ||
| 205 | #define PTI_USER_PGTABLE_AND_PCID_MASK (PTI_USER_PCID_MASK | PTI_USER_PGTABLE_MASK) | ||
| 203 | 206 | ||
| 204 | .macro SET_NOFLUSH_BIT reg:req | 207 | .macro SET_NOFLUSH_BIT reg:req |
| 205 | bts $X86_CR3_PCID_NOFLUSH_BIT, \reg | 208 | bts $X86_CR3_PCID_NOFLUSH_BIT, \reg |
| @@ -208,7 +211,7 @@ For 32-bit we have the following conventions - kernel is built with | |||
| 208 | .macro ADJUST_KERNEL_CR3 reg:req | 211 | .macro ADJUST_KERNEL_CR3 reg:req |
| 209 | ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID | 212 | ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID |
| 210 | /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */ | 213 | /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */ |
| 211 | andq $(~PTI_SWITCH_MASK), \reg | 214 | andq $(~PTI_USER_PGTABLE_AND_PCID_MASK), \reg |
| 212 | .endm | 215 | .endm |
| 213 | 216 | ||
| 214 | .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req | 217 | .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req |
| @@ -239,15 +242,19 @@ For 32-bit we have the following conventions - kernel is built with | |||
| 239 | /* Flush needed, clear the bit */ | 242 | /* Flush needed, clear the bit */ |
| 240 | btr \scratch_reg, THIS_CPU_user_pcid_flush_mask | 243 | btr \scratch_reg, THIS_CPU_user_pcid_flush_mask |
| 241 | movq \scratch_reg2, \scratch_reg | 244 | movq \scratch_reg2, \scratch_reg |
| 242 | jmp .Lwrcr3_\@ | 245 | jmp .Lwrcr3_pcid_\@ |
| 243 | 246 | ||
| 244 | .Lnoflush_\@: | 247 | .Lnoflush_\@: |
| 245 | movq \scratch_reg2, \scratch_reg | 248 | movq \scratch_reg2, \scratch_reg |
| 246 | SET_NOFLUSH_BIT \scratch_reg | 249 | SET_NOFLUSH_BIT \scratch_reg |
| 247 | 250 | ||
| 251 | .Lwrcr3_pcid_\@: | ||
| 252 | /* Flip the ASID to the user version */ | ||
| 253 | orq $(PTI_USER_PCID_MASK), \scratch_reg | ||
| 254 | |||
| 248 | .Lwrcr3_\@: | 255 | .Lwrcr3_\@: |
| 249 | /* Flip the PGD and ASID to the user version */ | 256 | /* Flip the PGD to the user version */ |
| 250 | orq $(PTI_SWITCH_MASK), \scratch_reg | 257 | orq $(PTI_USER_PGTABLE_MASK), \scratch_reg |
| 251 | mov \scratch_reg, %cr3 | 258 | mov \scratch_reg, %cr3 |
| 252 | .Lend_\@: | 259 | .Lend_\@: |
| 253 | .endm | 260 | .endm |
| @@ -263,17 +270,12 @@ For 32-bit we have the following conventions - kernel is built with | |||
| 263 | movq %cr3, \scratch_reg | 270 | movq %cr3, \scratch_reg |
| 264 | movq \scratch_reg, \save_reg | 271 | movq \scratch_reg, \save_reg |
| 265 | /* | 272 | /* |
| 266 | * Is the "switch mask" all zero? That means that both of | 273 | * Test the user pagetable bit. If set, then the user page tables |
| 267 | * these are zero: | 274 | * are active. If clear CR3 already has the kernel page table |
| 268 | * | 275 | * active. |
| 269 | * 1. The user/kernel PCID bit, and | ||
| 270 | * 2. The user/kernel "bit" that points CR3 to the | ||
| 271 | * bottom half of the 8k PGD | ||
| 272 | * | ||
| 273 | * That indicates a kernel CR3 value, not a user CR3. | ||
| 274 | */ | 276 | */ |
| 275 | testq $(PTI_SWITCH_MASK), \scratch_reg | 277 | bt $PTI_USER_PGTABLE_BIT, \scratch_reg |
| 276 | jz .Ldone_\@ | 278 | jnc .Ldone_\@ |
| 277 | 279 | ||
| 278 | ADJUST_KERNEL_CR3 \scratch_reg | 280 | ADJUST_KERNEL_CR3 \scratch_reg |
| 279 | movq \scratch_reg, %cr3 | 281 | movq \scratch_reg, %cr3 |
| @@ -290,7 +292,7 @@ For 32-bit we have the following conventions - kernel is built with | |||
| 290 | * KERNEL pages can always resume with NOFLUSH as we do | 292 | * KERNEL pages can always resume with NOFLUSH as we do |
| 291 | * explicit flushes. | 293 | * explicit flushes. |
| 292 | */ | 294 | */ |
| 293 | bt $X86_CR3_PTI_SWITCH_BIT, \save_reg | 295 | bt $PTI_USER_PGTABLE_BIT, \save_reg |
| 294 | jnc .Lnoflush_\@ | 296 | jnc .Lnoflush_\@ |
| 295 | 297 | ||
| 296 | /* | 298 | /* |
diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h index 6a60fea90b9d..625a52a5594f 100644 --- a/arch/x86/include/asm/processor-flags.h +++ b/arch/x86/include/asm/processor-flags.h | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #define CR3_NOFLUSH BIT_ULL(63) | 40 | #define CR3_NOFLUSH BIT_ULL(63) |
| 41 | 41 | ||
| 42 | #ifdef CONFIG_PAGE_TABLE_ISOLATION | 42 | #ifdef CONFIG_PAGE_TABLE_ISOLATION |
| 43 | # define X86_CR3_PTI_SWITCH_BIT 11 | 43 | # define X86_CR3_PTI_PCID_USER_BIT 11 |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #else | 46 | #else |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index f9b48ce152eb..3effd3c994af 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
| @@ -81,13 +81,13 @@ static inline u16 kern_pcid(u16 asid) | |||
| 81 | * Make sure that the dynamic ASID space does not confict with the | 81 | * Make sure that the dynamic ASID space does not confict with the |
| 82 | * bit we are using to switch between user and kernel ASIDs. | 82 | * bit we are using to switch between user and kernel ASIDs. |
| 83 | */ | 83 | */ |
| 84 | BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_SWITCH_BIT)); | 84 | BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_PCID_USER_BIT)); |
| 85 | 85 | ||
| 86 | /* | 86 | /* |
| 87 | * The ASID being passed in here should have respected the | 87 | * The ASID being passed in here should have respected the |
| 88 | * MAX_ASID_AVAILABLE and thus never have the switch bit set. | 88 | * MAX_ASID_AVAILABLE and thus never have the switch bit set. |
| 89 | */ | 89 | */ |
| 90 | VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_SWITCH_BIT)); | 90 | VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_PCID_USER_BIT)); |
| 91 | #endif | 91 | #endif |
| 92 | /* | 92 | /* |
| 93 | * The dynamically-assigned ASIDs that get passed in are small | 93 | * The dynamically-assigned ASIDs that get passed in are small |
| @@ -112,7 +112,7 @@ static inline u16 user_pcid(u16 asid) | |||
| 112 | { | 112 | { |
| 113 | u16 ret = kern_pcid(asid); | 113 | u16 ret = kern_pcid(asid); |
| 114 | #ifdef CONFIG_PAGE_TABLE_ISOLATION | 114 | #ifdef CONFIG_PAGE_TABLE_ISOLATION |
| 115 | ret |= 1 << X86_CR3_PTI_SWITCH_BIT; | 115 | ret |= 1 << X86_CR3_PTI_PCID_USER_BIT; |
| 116 | #endif | 116 | #endif |
| 117 | return ret; | 117 | return ret; |
| 118 | } | 118 | } |
