lkml.org 
[lkml]   [2021]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 25/24] x86/traps: Rewrite native_load_gs_index in C code
    Date
    From: Lai Jiangshan <laijs@linux.alibaba.com>

    There is no constrain/limition to force native_load_gs_index() to be in
    ASM code.

    Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
    ---
    arch/x86/entry/entry_64.S | 36 ----------------------------
    arch/x86/entry/traps.c | 25 +++++++++++++++++++
    arch/x86/include/asm/special_insns.h | 11 +--------
    arch/x86/mm/extable.c | 15 ++++++++++++
    4 files changed, 41 insertions(+), 46 deletions(-)

    diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
    index 2d17fca1f503..16ee481e9b5f 100644
    --- a/arch/x86/entry/entry_64.S
    +++ b/arch/x86/entry/entry_64.S
    @@ -659,42 +659,6 @@ native_irq_return_ldt:
    SYM_CODE_END(common_interrupt_return)
    _ASM_NOKPROBE(common_interrupt_return)

    -/*
    - * Reload gs selector with exception handling
    - * edi: new selector
    - *
    - * Is in entry.text as it shouldn't be instrumented.
    - */
    -SYM_FUNC_START(asm_load_gs_index)
    - FRAME_BEGIN
    - swapgs
    -SYM_INNER_LABEL(asm_load_gs_index_gs_change, SYM_L_GLOBAL)
    -.Lgs_change:
    - movl %edi, %gs
    -2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
    - swapgs
    - FRAME_END
    - ret
    -SYM_FUNC_END(asm_load_gs_index)
    -EXPORT_SYMBOL(asm_load_gs_index)
    -
    - _ASM_EXTABLE(.Lgs_change, .Lbad_gs)
    - .section .fixup, "ax"
    - /* running with kernelgs */
    -SYM_CODE_START_LOCAL_NOALIGN(.Lbad_gs)
    - swapgs /* switch back to user gs */
    -.macro ZAP_GS
    - /* This can't be a string because the preprocessor needs to see it. */
    - movl $__USER_DS, %eax
    - movl %eax, %gs
    -.endm
    - ALTERNATIVE "", "ZAP_GS", X86_BUG_NULL_SEG
    - xorl %eax, %eax
    - movl %eax, %gs
    - jmp 2b
    -SYM_CODE_END(.Lbad_gs)
    - .previous
    -
    #ifdef CONFIG_XEN_PV
    /*
    * A note on the "critical region" in our callback handler.
    diff --git a/arch/x86/entry/traps.c b/arch/x86/entry/traps.c
    index 52511db6baa6..2a17d74569fd 100644
    --- a/arch/x86/entry/traps.c
    +++ b/arch/x86/entry/traps.c
    @@ -679,6 +679,31 @@ DEFINE_IDTENTRY_RAW(exc_int3)
    }

    #ifdef CONFIG_X86_64
    +
    +/*
    + * Reload gs selector with exception handling
    + * selector: new selector
    + *
    + * Is noinstr as it shouldn't be instrumented.
    + */
    +noinstr void native_load_gs_index(unsigned int selector)
    +{
    + unsigned long flags;
    +
    + local_irq_save(flags);
    + native_swapgs();
    + asm volatile(
    + ".global asm_load_gs_index_gs_change \n"
    + "asm_load_gs_index_gs_change: \n"
    + "1: movl %0, %%gs \n"
    + " swapgs \n"
    + "2: \n"
    + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_clear_gs)
    + :: "r" (selector) : "memory");
    + alternative("", "mfence", X86_BUG_SWAPGS_FENCE);
    + local_irq_restore(flags);
    +}
    +
    /*
    * Help handler running on a per-cpu (IST or entry trampoline) stack
    * to switch to the normal thread stack if the interrupted code was in
    diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
    index 058995bb153c..c5d74ebce527 100644
    --- a/arch/x86/include/asm/special_insns.h
    +++ b/arch/x86/include/asm/special_insns.h
    @@ -120,16 +120,7 @@ static inline void native_wbinvd(void)
    asm volatile("wbinvd": : :"memory");
    }

    -extern asmlinkage void asm_load_gs_index(unsigned int selector);
    -
    -static inline void native_load_gs_index(unsigned int selector)
    -{
    - unsigned long flags;
    -
    - local_irq_save(flags);
    - asm_load_gs_index(selector);
    - local_irq_restore(flags);
    -}
    +extern asmlinkage void native_load_gs_index(unsigned int selector);

    static inline unsigned long __read_cr4(void)
    {
    diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
    index e1664e9f969c..695a580a652a 100644
    --- a/arch/x86/mm/extable.c
    +++ b/arch/x86/mm/extable.c
    @@ -138,6 +138,21 @@ __visible bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
    }
    EXPORT_SYMBOL(ex_handler_clear_fs);

    +__visible bool ex_handler_clear_gs(const struct exception_table_entry *fixup,
    + struct pt_regs *regs, int trapnr,
    + unsigned long error_code,
    + unsigned long fault_addr)
    +{
    + /*
    + * The following native_load_gs_index() should not fault, otherwise
    + * it would be infinite recursion.
    + */
    + if (static_cpu_has(X86_BUG_NULL_SEG))
    + native_load_gs_index(__USER_DS);
    + native_load_gs_index(0);
    + return ex_handler_default(fixup, regs, trapnr, error_code, fault_addr);
    +}
    +
    enum handler_type ex_get_fault_handler_type(unsigned long ip)
    {
    const struct exception_table_entry *e;
    --
    2.19.1.6.gb485710b
    \
     
     \ /
      Last update: 2021-09-02 12:52    [W:4.121 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site