Skip to content

Commit 96b2371

Browse files
ChangSeokBaeKAGA-KOKO
authored andcommitted
x86/entry/64: Switch CR3 before SWAPGS in paranoid entry
When FSGSBASE is enabled, the GSBASE handling in paranoid entry will need to retrieve the kernel GSBASE which requires that the kernel page table is active. As the CR3 switch to the kernel page tables (PTI is active) does not depend on kernel GSBASE, move the CR3 switch in front of the GSBASE handling. Comment the EBX content while at it. No functional change. [ tglx: Rewrote changelog and comments ] Signed-off-by: Chang S. Bae <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 978e134 commit 96b2371

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

arch/x86/entry/entry_64.S

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -807,13 +807,6 @@ SYM_CODE_START_LOCAL(paranoid_entry)
807807
cld
808808
PUSH_AND_CLEAR_REGS save_ret=1
809809
ENCODE_FRAME_POINTER 8
810-
movl $1, %ebx
811-
movl $MSR_GS_BASE, %ecx
812-
rdmsr
813-
testl %edx, %edx
814-
js 1f /* negative -> in kernel */
815-
SWAPGS
816-
xorl %ebx, %ebx
817810

818811
1:
819812
/*
@@ -825,16 +818,38 @@ SYM_CODE_START_LOCAL(paranoid_entry)
825818
* This is also why CS (stashed in the "iret frame" by the
826819
* hardware at entry) can not be used: this may be a return
827820
* to kernel code, but with a user CR3 value.
821+
*
822+
* Switching CR3 does not depend on kernel GSBASE so it can
823+
* be done before switching to the kernel GSBASE. This is
824+
* required for FSGSBASE because the kernel GSBASE has to
825+
* be retrieved from a kernel internal table.
828826
*/
829827
SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
830828

829+
/* EBX = 1 -> kernel GSBASE active, no restore required */
830+
movl $1, %ebx
831+
/*
832+
* The kernel-enforced convention is a negative GSBASE indicates
833+
* a kernel value. No SWAPGS needed on entry and exit.
834+
*/
835+
movl $MSR_GS_BASE, %ecx
836+
rdmsr
837+
testl %edx, %edx
838+
jns .Lparanoid_entry_swapgs
839+
ret
840+
841+
.Lparanoid_entry_swapgs:
842+
SWAPGS
843+
831844
/*
832845
* The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an
833846
* unconditional CR3 write, even in the PTI case. So do an lfence
834847
* to prevent GS speculation, regardless of whether PTI is enabled.
835848
*/
836849
FENCE_SWAPGS_KERNEL_ENTRY
837850

851+
/* EBX = 0 -> SWAPGS required on exit */
852+
xorl %ebx, %ebx
838853
ret
839854
SYM_CODE_END(paranoid_entry)
840855

@@ -852,7 +867,8 @@ SYM_CODE_END(paranoid_entry)
852867
*/
853868
SYM_CODE_START_LOCAL(paranoid_exit)
854869
UNWIND_HINT_REGS
855-
testl %ebx, %ebx /* swapgs needed? */
870+
/* If EBX is 0, SWAPGS is required */
871+
testl %ebx, %ebx
856872
jnz .Lparanoid_exit_no_swapgs
857873
/* Always restore stashed CR3 value (see paranoid_entry) */
858874
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14

0 commit comments

Comments
 (0)