x86/entry: Add some paranoid entry/exit CR3 handling comments
Andi Kleen was just asking me about the NMI CR3 handling and why we restore it unconditionally. I was *sure* we had documented it well. We did not. Add some documentation. We have common entry code where the CR3 value is stashed, but three places in two big code paths where we restore it. I put bulk of the comments in this common path and then refer to it from the other spots. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: luto@kernel.org Cc: bp@alien8.de Cc: "H. Peter Anvin" <hpa@zytor.come Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Link: https://lkml.kernel.org/r/20181012232118.3EAAE77B@viggo.jf.intel.com
This commit is contained in:
Родитель
b59167ac7b
Коммит
16561f27f9
|
@ -1187,6 +1187,18 @@ ENTRY(paranoid_entry)
|
||||||
xorl %ebx, %ebx
|
xorl %ebx, %ebx
|
||||||
|
|
||||||
1:
|
1:
|
||||||
|
/*
|
||||||
|
* Always stash CR3 in %r14. This value will be restored,
|
||||||
|
* verbatim, at exit. Needed if kernel is interrupted
|
||||||
|
* after switching to the user CR3 value but before
|
||||||
|
* returning to userspace.
|
||||||
|
*
|
||||||
|
* This is also why CS (stashed in the "iret frame" by the
|
||||||
|
* hardware at entry) can not be used: this may be a return
|
||||||
|
* to kernel code, but with a user CR3 value. The %ebx flag
|
||||||
|
* for SWAPGS is also unusable for CR3 because there is a
|
||||||
|
* window with a user GS and a kernel CR3.
|
||||||
|
*/
|
||||||
SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
|
SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -1211,11 +1223,13 @@ ENTRY(paranoid_exit)
|
||||||
testl %ebx, %ebx /* swapgs needed? */
|
testl %ebx, %ebx /* swapgs needed? */
|
||||||
jnz .Lparanoid_exit_no_swapgs
|
jnz .Lparanoid_exit_no_swapgs
|
||||||
TRACE_IRQS_IRETQ
|
TRACE_IRQS_IRETQ
|
||||||
|
/* Always restore stashed CR3 value (see paranoid_entry) */
|
||||||
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
|
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
|
||||||
SWAPGS_UNSAFE_STACK
|
SWAPGS_UNSAFE_STACK
|
||||||
jmp .Lparanoid_exit_restore
|
jmp .Lparanoid_exit_restore
|
||||||
.Lparanoid_exit_no_swapgs:
|
.Lparanoid_exit_no_swapgs:
|
||||||
TRACE_IRQS_IRETQ_DEBUG
|
TRACE_IRQS_IRETQ_DEBUG
|
||||||
|
/* Always restore stashed CR3 value (see paranoid_entry) */
|
||||||
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
|
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
|
||||||
.Lparanoid_exit_restore:
|
.Lparanoid_exit_restore:
|
||||||
jmp restore_regs_and_return_to_kernel
|
jmp restore_regs_and_return_to_kernel
|
||||||
|
@ -1626,6 +1640,7 @@ end_repeat_nmi:
|
||||||
movq $-1, %rsi
|
movq $-1, %rsi
|
||||||
call do_nmi
|
call do_nmi
|
||||||
|
|
||||||
|
/* Always restore stashed CR3 value (see paranoid_entry) */
|
||||||
RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
|
RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
|
||||||
|
|
||||||
testl %ebx, %ebx /* swapgs needed? */
|
testl %ebx, %ebx /* swapgs needed? */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче