Merge tag 'x86-mm-2021-04-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[platform/kernel/linux-rpi.git] / arch / x86 / kernel / paravirt.c
index 197a126..04cafc0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/highmem.h>
 #include <linux/kprobes.h>
 #include <linux/pgtable.h>
+#include <linux/static_call.h>
 
 #include <asm/bug.h>
 #include <asm/paravirt.h>
@@ -52,7 +53,10 @@ void __init default_banner(void)
 }
 
 /* Undefined instruction for dealing with missing ops pointers. */
-static const unsigned char ud2a[] = { 0x0f, 0x0b };
+static void paravirt_BUG(void)
+{
+       BUG();
+}
 
 struct branch {
        unsigned char opcode;
@@ -85,25 +89,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);
@@ -114,8 +99,8 @@ void __init native_pv_lock_init(void)
                static_branch_disable(&virt_spin_lock_key);
 }
 
-unsigned paravirt_patch_default(u8 type, void *insn_buff,
-                               unsigned long addr, unsigned len)
+unsigned int paravirt_patch(u8 type, void *insn_buff, unsigned long addr,
+                           unsigned int len)
 {
        /*
         * Neat trick to map patch type back to the call within the
@@ -125,20 +110,10 @@ unsigned paravirt_patch_default(u8 type, void *insn_buff,
        unsigned ret;
 
        if (opfunc == NULL)
-               /* If there's no function, patch it with a ud2a (BUG) */
-               ret = paravirt_patch_insns(insn_buff, len, ud2a, ud2a+sizeof(ud2a));
+               /* If there's no function, patch it with paravirt_BUG() */
+               ret = paravirt_patch_call(insn_buff, paravirt_BUG, addr, len);
        else if (opfunc == _paravirt_nop)
                ret = 0;
-
-#ifdef CONFIG_PARAVIRT_XXL
-       /* identity functions just return their single argument */
-       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. */
                ret = paravirt_patch_call(insn_buff, opfunc, addr, len);
@@ -146,19 +121,6 @@ unsigned paravirt_patch_default(u8 type, void *insn_buff,
        return ret;
 }
 
-unsigned paravirt_patch_insns(void *insn_buff, unsigned len,
-                             const char *start, const char *end)
-{
-       unsigned insn_len = end - start;
-
-       /* Alternative instruction is too large for the patch site and we cannot continue: */
-       BUG_ON(insn_len > len || start == NULL);
-
-       memcpy(insn_buff, start, insn_len);
-
-       return insn_len;
-}
-
 struct static_key paravirt_steal_enabled;
 struct static_key paravirt_steal_rq_enabled;
 
@@ -167,6 +129,14 @@ static u64 native_steal_clock(int cpu)
        return 0;
 }
 
+DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
+DEFINE_STATIC_CALL(pv_sched_clock, native_sched_clock);
+
+void paravirt_set_sched_clock(u64 (*func)(void))
+{
+       static_call_update(pv_sched_clock, func);
+}
+
 /* These are in entry.S */
 extern void native_iret(void);
 
@@ -269,13 +239,6 @@ struct pv_info pv_info = {
 #define PTE_IDENT      __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
 
 struct paravirt_patch_template pv_ops = {
-       /* Init ops. */
-       .init.patch             = native_patch,
-
-       /* Time ops. */
-       .time.sched_clock       = native_sched_clock,
-       .time.steal_clock       = native_steal_clock,
-
        /* Cpu ops. */
        .cpu.io_delay           = native_io_delay,
 
@@ -308,8 +271,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,
@@ -414,6 +375,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);