[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 12/15] x86/paravirt: switch iret pvops to ALTERNATIVE



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@xxxxxxxx>
---
V3:
- use ALTERNATIVE_TERNARY
---
 arch/x86/include/asm/paravirt.h       |  6 +++---
 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, 7 insertions(+), 38 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index c6496a82fad1..36cd71fa097f 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -749,9 +749,9 @@ 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_TERNARY("jmp *paravirt_iret(%rip);",                \
+               X86_FEATURE_XENPV, "jmp xen_iret;", "jmp native_iret;")
 
 #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 45bd21647dd8..0afdac83f926 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -151,10 +151,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
@@ -294,6 +290,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 44e5b0fe28cb..0553a339d850 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.