lkml.org 
[lkml]   [2020]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v10 05/18] x86/entry/64: Switch CR3 before SWAPGS in paranoid entry
    Date
    From: "Chang S. Bae" <chang.seok.bae@intel.com>

    When FSGSBASE is enabled, the GS base handling in paranoid entry will need
    to retrieve the kernel GS base 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 GS base, move the CR3 switch in front of the GS base handling.

    Comment the EBX content while at it.

    No functional change.

    Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
    Reviewed-by: Tony Luck <tony.luck@intel.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: Andi Kleen <ak@linux.intel.com>
    Cc: Vegard Nossum <vegard.nossum@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/x86/entry/entry_64.S | 31 +++++++++++++++++++------------
    1 file changed, 19 insertions(+), 12 deletions(-)

    diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
    index 3adb3c8e2409b..7f27626f8426f 100644
    --- a/arch/x86/entry/entry_64.S
    +++ b/arch/x86/entry/entry_64.S
    @@ -1220,15 +1220,7 @@ SYM_CODE_START_LOCAL(paranoid_entry)
    cld
    PUSH_AND_CLEAR_REGS save_ret=1
    ENCODE_FRAME_POINTER 8
    - movl $1, %ebx
    - movl $MSR_GS_BASE, %ecx
    - rdmsr
    - testl %edx, %edx
    - js 1f /* negative -> in kernel */
    - SWAPGS
    - xorl %ebx, %ebx

    -1:
    /*
    * Always stash CR3 in %r14. This value will be restored,
    * verbatim, at exit. Needed if paranoid_entry interrupted
    @@ -1238,16 +1230,31 @@ SYM_CODE_START_LOCAL(paranoid_entry)
    * 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.
    + *
    + * Switching CR3 does not depend on kernel GS base so it can
    + * be done before switching to the kernel GS base. This is
    + * required for FSGSBASE because the kernel GS base has to
    + * be retrieved from a kernel internal table.
    */
    SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14

    + /* EBX = 1 -> kernel GSBASE active, no restore required */
    + movl $1, %ebx
    /*
    - * The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an
    - * unconditional CR3 write, even in the PTI case. So do an lfence
    - * to prevent GS speculation, regardless of whether PTI is enabled.
    + * The kernel-enforced convention is a negative GS base indicates
    + * a kernel value. No SWAPGS needed on entry and exit.
    */
    - FENCE_SWAPGS_KERNEL_ENTRY
    + movl $MSR_GS_BASE, %ecx
    + rdmsr
    + testl %edx, %edx
    + jns .Lparanoid_entry_swapgs
    + ret

    +.Lparanoid_entry_swapgs:
    + SWAPGS
    + FENCE_SWAPGS_KERNEL_ENTRY
    + /* EBX = 0 -> SWAPGS required on exit */
    + xorl %ebx, %ebx
    ret
    SYM_CODE_END(paranoid_entry)

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-04-24 01:23    [W:4.830 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site