lkml.org 
[lkml]   [2023]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 6/6] x86/entry/32: Clean up syscall fast exit tests
    Date
    Merge compat and native code and clarify comments.

    Signed-off-by: Brian Gerst <brgerst@gmail.com>
    ---
    arch/x86/entry/common.c | 48 +++++++++++++++-----------------
    arch/x86/entry/entry_64_compat.S | 5 ++--
    2 files changed, 24 insertions(+), 29 deletions(-)

    diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
    index 4d7d6d25dda9..800664325542 100644
    --- a/arch/x86/entry/common.c
    +++ b/arch/x86/entry/common.c
    @@ -241,34 +241,30 @@ __visible noinstr bool do_fast_syscall_32(struct pt_regs *regs)
    if (!__do_fast_syscall_32(regs))
    return false;

    -#ifdef CONFIG_X86_64
    /*
    - * Opportunistic SYSRETL: if possible, try to return using SYSRETL.
    - * SYSRETL is available on all 64-bit CPUs, so we don't need to
    - * bother with SYSEXIT.
    - *
    - * Unlike 64-bit opportunistic SYSRET, we can't check that CX == IP,
    - * because the ECX fixup above will ensure that this is essentially
    - * never the case.
    + * Check that the register state is valid for using SYSRETL/SYSEXIT
    + * to exit to userspace. Otherwise use the slower but fully capable
    + * IRET exit path.
    */
    - return regs->cs == __USER32_CS && regs->ss == __USER_DS &&
    - regs->ip == landing_pad &&
    - (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF)) == 0;
    -#else
    - /*
    - * Opportunistic SYSEXIT: if possible, try to return using SYSEXIT.
    - *
    - * Unlike 64-bit opportunistic SYSRET, we can't check that CX == IP,
    - * because the ECX fixup above will ensure that this is essentially
    - * never the case.
    - *
    - * We don't allow syscalls at all from VM86 mode, but we still
    - * need to check VM, because we might be returning from sys_vm86.
    - */
    - return regs->cs == __USER_CS && regs->ss == __USER_DS &&
    - regs->ip == landing_pad &&
    - (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)) == 0;
    -#endif
    +
    + /* XEN PV guests always use IRET path */
    + if (cpu_feature_enabled(X86_FEATURE_XENPV))
    + return false;
    +
    + /* EIP must point to the VDSO landing pad */
    + if (unlikely(regs->ip != landing_pad))
    + return false;
    +
    + /* CS and SS must match the values set in MSR_STAR */
    + if (unlikely(regs->cs != __USER32_CS || regs->ss != __USER_DS))
    + return false;
    +
    + /* If the TF, RF, or VM flags are set, use IRET */
    + if (unlikely(regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)))
    + return false;
    +
    + /* Use SYSRETL/SYSEXIT to exit to userspace */
    + return true;
    }

    /* Returns true to return using SYSEXIT/SYSRETL, or false to use IRET */
    diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
    index 27c05d08558a..84e21d1ebf10 100644
    --- a/arch/x86/entry/entry_64_compat.S
    +++ b/arch/x86/entry/entry_64_compat.S
    @@ -211,9 +211,8 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwframe, SYM_L_GLOBAL)
    call do_fast_syscall_32

    sysret32_from_system_call:
    - /* XEN PV guests always use IRET path */
    - ALTERNATIVE "testb %al, %al; jz swapgs_restore_regs_and_return_to_usermode", \
    - "jmp swapgs_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV
    + testb %al, %al /* Is SYSRET allowed? */
    + jz swapgs_restore_regs_and_return_to_usermode

    /*
    * Opportunistic SYSRET
    --
    2.41.0
    \
     
     \ /
      Last update: 2023-07-21 18:13    [W:5.202 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site