]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/paravirt: Move some functions and defines to alternative.c
authorJuergen Gross <jgross@suse.com>
Wed, 29 Nov 2023 13:33:29 +0000 (14:33 +0100)
committerBorislav Petkov (AMD) <bp@alien8.de>
Sun, 10 Dec 2023 19:30:31 +0000 (20:30 +0100)
As a preparation for replacing paravirt patching completely by
alternative patching, move some backend functions and #defines to
the alternatives code and header.

Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20231129133332.31043-3-jgross@suse.com
arch/x86/include/asm/alternative.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/qspinlock_paravirt.h
arch/x86/kernel/alternative.c
arch/x86/kernel/kvm.c
arch/x86/kernel/paravirt.c
arch/x86/xen/irq.c

index 65f79092c9d9e1a77830e992f877082593ffd9d1..ce788ab4e77ca650c53ef01bf8c5a259395c35dc 100644 (file)
@@ -330,6 +330,22 @@ static inline int alternatives_text_reserved(void *start, void *end)
  */
 #define ASM_NO_INPUT_CLOBBER(clbr...) "i" (0) : clbr
 
+/* Macro for creating assembler functions avoiding any C magic. */
+#define DEFINE_ASM_FUNC(func, instr, sec)              \
+       asm (".pushsection " #sec ", \"ax\"\n"          \
+            ".global " #func "\n\t"                    \
+            ".type " #func ", @function\n\t"           \
+            ASM_FUNC_ALIGN "\n"                        \
+            #func ":\n\t"                              \
+            ASM_ENDBR                                  \
+            instr "\n\t"                               \
+            ASM_RET                                    \
+            ".size " #func ", . - " #func "\n\t"       \
+            ".popsection")
+
+void BUG_func(void);
+void nop_func(void);
+
 #else /* __ASSEMBLY__ */
 
 #ifdef CONFIG_SMP
index aa76ac7c806c8c522f850b80bba5c616c9da9cab..f18bfa7f307090308be32f97bf502330ea2a2915 100644 (file)
@@ -720,18 +720,6 @@ static __always_inline unsigned long arch_local_irq_save(void)
 #undef PVOP_VCALL4
 #undef PVOP_CALL4
 
-#define DEFINE_PARAVIRT_ASM(func, instr, sec)          \
-       asm (".pushsection " #sec ", \"ax\"\n"          \
-            ".global " #func "\n\t"                    \
-            ".type " #func ", @function\n\t"           \
-            ASM_FUNC_ALIGN "\n"                        \
-            #func ":\n\t"                              \
-            ASM_ENDBR                                  \
-            instr "\n\t"                               \
-            ASM_RET                                    \
-            ".size " #func ", . - " #func "\n\t"       \
-            ".popsection")
-
 extern void default_banner(void);
 void native_pv_lock_init(void) __init;
 
index 483e19e5ca7a34456195822ac4423ab338ff65b4..166e9618158fb555ca12947cc50df9ebc5cec895 100644 (file)
@@ -540,8 +540,6 @@ int paravirt_disable_iospace(void);
        __PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),    \
                     PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
 
-void _paravirt_nop(void);
-void paravirt_BUG(void);
 unsigned long paravirt_ret0(void);
 #ifdef CONFIG_PARAVIRT_XXL
 u64 _paravirt_ident_64(u64);
@@ -551,7 +549,7 @@ void pv_native_irq_enable(void);
 unsigned long pv_native_read_cr2(void);
 #endif
 
-#define paravirt_nop   ((void *)_paravirt_nop)
+#define paravirt_nop   ((void *)nop_func)
 
 extern struct paravirt_patch_site __parainstructions[],
        __parainstructions_end[];
index 85b6e3609cb9262da1f60f337f1423f369cb2fb2..ef9697f20129af1bcb54bc75dc37095d4837e6b8 100644 (file)
@@ -56,8 +56,8 @@ __PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, ".spinlock.text");
        "pop    %rdx\n\t"                                               \
        FRAME_END
 
-DEFINE_PARAVIRT_ASM(__raw_callee_save___pv_queued_spin_unlock,
-                   PV_UNLOCK_ASM, .spinlock.text);
+DEFINE_ASM_FUNC(__raw_callee_save___pv_queued_spin_unlock,
+               PV_UNLOCK_ASM, .spinlock.text);
 
 #else /* CONFIG_64BIT */
 
index be35c8ccf8267b874ca691874440cab799968e9f..ca25dd280b8c1d4c9906b1ebdc54388e629663f0 100644 (file)
@@ -385,6 +385,16 @@ apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
        }
 }
 
+/* Low-level backend functions usable from alternative code replacements. */
+DEFINE_ASM_FUNC(nop_func, "", .entry.text);
+EXPORT_SYMBOL_GPL(nop_func);
+
+noinstr void BUG_func(void)
+{
+       BUG();
+}
+EXPORT_SYMBOL_GPL(BUG_func);
+
 /*
  * Replace instructions with better alternatives for this CPU type. This runs
  * before SMP is initialized to avoid SMP problems with self modifying code.
index 0ddb3bd0f1aac7cda767c240bb21bfdfbff39d62..c461c1a4b6afb998fbe7f5a336ce4b16e0421a5e 100644 (file)
@@ -803,8 +803,8 @@ extern bool __raw_callee_save___kvm_vcpu_is_preempted(long);
  "cmpb   $0, " __stringify(KVM_STEAL_TIME_preempted) "+steal_time(%rax)\n\t" \
  "setne  %al\n\t"
 
-DEFINE_PARAVIRT_ASM(__raw_callee_save___kvm_vcpu_is_preempted,
-                   PV_VCPU_PREEMPTED_ASM, .text);
+DEFINE_ASM_FUNC(__raw_callee_save___kvm_vcpu_is_preempted,
+               PV_VCPU_PREEMPTED_ASM, .text);
 #endif
 
 static void __init kvm_guest_init(void)
index 97f1436c1a20348a567ea439aeaa41881448d625..acc5b1004f0fb96c6b37c8858f076f01d73f8bbf 100644 (file)
 #include <asm/io_bitmap.h>
 #include <asm/gsseg.h>
 
-/*
- * nop stub, which must not clobber anything *including the stack* to
- * avoid confusing the entry prologues.
- */
-DEFINE_PARAVIRT_ASM(_paravirt_nop, "", .entry.text);
-
 /* stub always returning 0. */
-DEFINE_PARAVIRT_ASM(paravirt_ret0, "xor %eax,%eax", .entry.text);
+DEFINE_ASM_FUNC(paravirt_ret0, "xor %eax,%eax", .entry.text);
 
 void __init default_banner(void)
 {
@@ -49,12 +43,6 @@ void __init default_banner(void)
               pv_info.name);
 }
 
-/* Undefined instruction for dealing with missing ops pointers. */
-noinstr void paravirt_BUG(void)
-{
-       BUG();
-}
-
 static unsigned paravirt_patch_call(void *insn_buff, const void *target,
                                    unsigned long addr, unsigned len)
 {
@@ -64,11 +52,11 @@ static unsigned paravirt_patch_call(void *insn_buff, const void *target,
 }
 
 #ifdef CONFIG_PARAVIRT_XXL
-DEFINE_PARAVIRT_ASM(_paravirt_ident_64, "mov %rdi, %rax", .text);
-DEFINE_PARAVIRT_ASM(pv_native_save_fl, "pushf; pop %rax", .noinstr.text);
-DEFINE_PARAVIRT_ASM(pv_native_irq_disable, "cli", .noinstr.text);
-DEFINE_PARAVIRT_ASM(pv_native_irq_enable, "sti", .noinstr.text);
-DEFINE_PARAVIRT_ASM(pv_native_read_cr2, "mov %cr2, %rax", .noinstr.text);
+DEFINE_ASM_FUNC(_paravirt_ident_64, "mov %rdi, %rax", .text);
+DEFINE_ASM_FUNC(pv_native_save_fl, "pushf; pop %rax", .noinstr.text);
+DEFINE_ASM_FUNC(pv_native_irq_disable, "cli", .noinstr.text);
+DEFINE_ASM_FUNC(pv_native_irq_enable, "sti", .noinstr.text);
+DEFINE_ASM_FUNC(pv_native_read_cr2, "mov %cr2, %rax", .noinstr.text);
 #endif
 
 DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
@@ -96,9 +84,9 @@ unsigned int paravirt_patch(u8 type, void *insn_buff, unsigned long addr,
        unsigned ret;
 
        if (opfunc == NULL)
-               /* 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)
+               /* If there's no function, patch it with BUG_func() */
+               ret = paravirt_patch_call(insn_buff, BUG_func, addr, len);
+       else if (opfunc == nop_func)
                ret = 0;
        else
                /* Otherwise call the function. */
index 6092fea7d65164a953c87899f96baac26a53f7dc..39982f955cfe933ae33bf9db509372511eec8915 100644 (file)
@@ -45,7 +45,7 @@ static const typeof(pv_ops) xen_irq_ops __initconst = {
                /* Initial interrupt flag handling only called while interrupts off. */
                .save_fl = __PV_IS_CALLEE_SAVE(paravirt_ret0),
                .irq_disable = __PV_IS_CALLEE_SAVE(paravirt_nop),
-               .irq_enable = __PV_IS_CALLEE_SAVE(paravirt_BUG),
+               .irq_enable = __PV_IS_CALLEE_SAVE(BUG_func),
 
                .safe_halt = xen_safe_halt,
                .halt = xen_halt,