lkml.org 
[lkml]   [2020]   [Nov]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 09/12] x86/paravirt: switch iret pvops to ALTERNATIVE
    Date
    The iret paravirt op is rather special as it is using a jmp instead
    of a call instruction. Switch it to ALTERNATIVE.

    Signed-off-by: Juergen Gross <jgross@suse.com>
    ---
    arch/x86/include/asm/paravirt.h | 7 ++++---
    arch/x86/include/asm/paravirt_types.h | 5 +----
    arch/x86/kernel/asm-offsets.c | 5 -----
    arch/x86/kernel/paravirt.c | 26 ++------------------------
    arch/x86/xen/enlighten_pv.c | 3 +--
    5 files changed, 8 insertions(+), 38 deletions(-)

    diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
    index 1dd30c95505d..62fbcd899539 100644
    --- a/arch/x86/include/asm/paravirt.h
    +++ b/arch/x86/include/asm/paravirt.h
    @@ -720,9 +720,10 @@ extern void default_banner(void);
    #define PARA_INDIRECT(addr) *addr(%rip)

    #define INTERRUPT_RETURN \
    - PARA_SITE(PARA_PATCH(PV_CPU_iret), \
    - ANNOTATE_RETPOLINE_SAFE; \
    - jmp PARA_INDIRECT(pv_ops+PV_CPU_iret);)
    + ANNOTATE_RETPOLINE_SAFE; \
    + ALTERNATIVE_2 "jmp *paravirt_iret(%rip);", \
    + "jmp native_iret;", X86_FEATURE_NOT_XENPV, \
    + "jmp xen_iret;", X86_FEATURE_XENPV

    #ifdef CONFIG_DEBUG_ENTRY
    #define SAVE_FLAGS(clobbers) \
    diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
    index b86acbb6449f..b66650dc869e 100644
    --- a/arch/x86/include/asm/paravirt_types.h
    +++ b/arch/x86/include/asm/paravirt_types.h
    @@ -152,10 +152,6 @@ struct pv_cpu_ops {

    u64 (*read_pmc)(int counter);

    - /* Normal iret. Jump to this with the standard iret stack
    - frame set up. */
    - void (*iret)(void);
    -
    void (*start_context_switch)(struct task_struct *prev);
    void (*end_context_switch)(struct task_struct *next);
    #endif
    @@ -295,6 +291,7 @@ struct paravirt_patch_template {

    extern struct pv_info pv_info;
    extern struct paravirt_patch_template pv_ops;
    +extern void (*paravirt_iret)(void);

    #define PARAVIRT_PATCH(x) \
    (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
    diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
    index 736508004b30..ecd3fd6993d1 100644
    --- a/arch/x86/kernel/asm-offsets.c
    +++ b/arch/x86/kernel/asm-offsets.c
    @@ -61,11 +61,6 @@ static void __used common(void)
    OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
    #endif

    -#ifdef CONFIG_PARAVIRT_XXL
    - BLANK();
    - OFFSET(PV_CPU_iret, paravirt_patch_template, cpu.iret);
    -#endif
    -
    #ifdef CONFIG_XEN
    BLANK();
    OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
    diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
    index 9f8aa18aa378..2ab547dd66c3 100644
    --- a/arch/x86/kernel/paravirt.c
    +++ b/arch/x86/kernel/paravirt.c
    @@ -86,25 +86,6 @@ u64 notrace _paravirt_ident_64(u64 x)
    {
    return x;
    }
    -
    -static unsigned paravirt_patch_jmp(void *insn_buff, const void *target,
    - unsigned long addr, unsigned len)
    -{
    - struct branch *b = insn_buff;
    - unsigned long delta = (unsigned long)target - (addr+5);
    -
    - if (len < 5) {
    -#ifdef CONFIG_RETPOLINE
    - WARN_ONCE(1, "Failing to patch indirect JMP in %ps\n", (void *)addr);
    -#endif
    - return len; /* call too long for patch site */
    - }
    -
    - b->opcode = 0xe9; /* jmp */
    - b->delta = delta;
    -
    - return 5;
    -}
    #endif

    DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
    @@ -136,9 +117,6 @@ unsigned paravirt_patch_default(u8 type, void *insn_buff,
    else if (opfunc == _paravirt_ident_64)
    ret = paravirt_patch_ident_64(insn_buff, len);

    - else if (type == PARAVIRT_PATCH(cpu.iret))
    - /* If operation requires a jmp, then jmp */
    - ret = paravirt_patch_jmp(insn_buff, opfunc, addr, len);
    #endif
    else
    /* Otherwise call the function. */
    @@ -316,8 +294,6 @@ struct paravirt_patch_template pv_ops = {

    .cpu.load_sp0 = native_load_sp0,

    - .cpu.iret = native_iret,
    -
    #ifdef CONFIG_X86_IOPL_IOPERM
    .cpu.invalidate_io_bitmap = native_tss_invalidate_io_bitmap,
    .cpu.update_io_bitmap = native_tss_update_io_bitmap,
    @@ -422,6 +398,8 @@ struct paravirt_patch_template pv_ops = {
    NOKPROBE_SYMBOL(native_get_debugreg);
    NOKPROBE_SYMBOL(native_set_debugreg);
    NOKPROBE_SYMBOL(native_load_idt);
    +
    +void (*paravirt_iret)(void) = native_iret;
    #endif

    EXPORT_SYMBOL(pv_ops);
    diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
    index 32b295cc2716..4716383c64a9 100644
    --- a/arch/x86/xen/enlighten_pv.c
    +++ b/arch/x86/xen/enlighten_pv.c
    @@ -1057,8 +1057,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {

    .read_pmc = xen_read_pmc,

    - .iret = xen_iret,
    -
    .load_tr_desc = paravirt_nop,
    .set_ldt = xen_set_ldt,
    .load_gdt = xen_load_gdt,
    @@ -1222,6 +1220,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
    pv_info = xen_info;
    pv_ops.init.patch = paravirt_patch_default;
    pv_ops.cpu = xen_cpu_ops;
    + paravirt_iret = xen_iret;
    xen_init_irq_ops();

    /*
    --
    2.26.2
    \
     
     \ /
      Last update: 2020-11-20 13:10    [W:2.330 / U:0.224 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site