Skip to content

Commit 21e9445

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
x86/mm: Optimize RESTORE_CR3
Most NMI/paranoid exceptions will not in fact change pagetables and would thus not require TLB flushing, however RESTORE_CR3 uses flushing CR3 writes. Restores to kernel PCIDs can be NOFLUSH, because we explicitly flush the kernel mappings and now that we track which user PCIDs need flushing we can avoid those too when possible. This does mean RESTORE_CR3 needs an additional scratch_reg, luckily both sites have plenty available. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andy Lutomirski <luto@kernel.org> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: David Laight <David.Laight@aculab.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Eduardo Valentin <eduval@amazon.com> Cc: Greg KH <gregkh@linuxfoundation.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Juergen Gross <jgross@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Will Deacon <will.deacon@arm.com> Cc: aliguori@amazon.com Cc: daniel.gruss@iaik.tugraz.at Cc: hughd@google.com Cc: keescook@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 6fd166a commit 21e9445

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

arch/x86/entry/calling.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,34 @@ For 32-bit we have the following conventions - kernel is built with
281281
.Ldone_\@:
282282
.endm
283283

284-
.macro RESTORE_CR3 save_reg:req
284+
.macro RESTORE_CR3 scratch_reg:req save_reg:req
285285
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
286+
287+
ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID
288+
289+
/*
290+
* KERNEL pages can always resume with NOFLUSH as we do
291+
* explicit flushes.
292+
*/
293+
bt $X86_CR3_PTI_SWITCH_BIT, \save_reg
294+
jnc .Lnoflush_\@
295+
296+
/*
297+
* Check if there's a pending flush for the user ASID we're
298+
* about to set.
299+
*/
300+
movq \save_reg, \scratch_reg
301+
andq $(0x7FF), \scratch_reg
302+
bt \scratch_reg, THIS_CPU_user_pcid_flush_mask
303+
jnc .Lnoflush_\@
304+
305+
btr \scratch_reg, THIS_CPU_user_pcid_flush_mask
306+
jmp .Lwrcr3_\@
307+
308+
.Lnoflush_\@:
309+
SET_NOFLUSH_BIT \save_reg
310+
311+
.Lwrcr3_\@:
286312
/*
287313
* The CR3 write could be avoided when not changing its value,
288314
* but would require a CR3 read *and* a scratch register.
@@ -301,7 +327,7 @@ For 32-bit we have the following conventions - kernel is built with
301327
.endm
302328
.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
303329
.endm
304-
.macro RESTORE_CR3 save_reg:req
330+
.macro RESTORE_CR3 scratch_reg:req save_reg:req
305331
.endm
306332

307333
#endif

arch/x86/entry/entry_64.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ ENTRY(paranoid_exit)
12881288
testl %ebx, %ebx /* swapgs needed? */
12891289
jnz .Lparanoid_exit_no_swapgs
12901290
TRACE_IRQS_IRETQ
1291-
RESTORE_CR3 save_reg=%r14
1291+
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
12921292
SWAPGS_UNSAFE_STACK
12931293
jmp .Lparanoid_exit_restore
12941294
.Lparanoid_exit_no_swapgs:
@@ -1730,7 +1730,7 @@ end_repeat_nmi:
17301730
movq $-1, %rsi
17311731
call do_nmi
17321732

1733-
RESTORE_CR3 save_reg=%r14
1733+
RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
17341734

17351735
testl %ebx, %ebx /* swapgs needed? */
17361736
jnz nmi_restore

0 commit comments

Comments
 (0)