[v3,1/5] x86/paravirt: move some functions and defines to alternative
Commit Message
As a preparation for replacing paravirt patching completely by
alternative patching, move some backend functions and #defines to
alternative code and header.
Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/x86/include/asm/alternative.h | 16 ++++++++++++
arch/x86/include/asm/paravirt.h | 12 ---------
arch/x86/include/asm/paravirt_types.h | 4 +--
arch/x86/include/asm/qspinlock_paravirt.h | 4 +--
arch/x86/kernel/alternative.c | 10 ++++++++
arch/x86/kernel/kvm.c | 4 +--
arch/x86/kernel/paravirt.c | 30 +++++++----------------
arch/x86/xen/irq.c | 2 +-
8 files changed, 41 insertions(+), 41 deletions(-)
Comments
Hi Juergen,
kernel test robot noticed the following build warnings:
[auto build test WARNING on kvm/queue]
[cannot apply to tip/x86/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Juergen-Gross/x86-paravirt-move-some-functions-and-defines-to-alternative/20231019-171709
base: https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue
patch link: https://lore.kernel.org/r/20231019091520.14540-2-jgross%40suse.com
patch subject: [PATCH v3 1/5] x86/paravirt: move some functions and defines to alternative
reproduce: (https://download.01.org/0day-ci/archive/20231019/202310191944.Z8sC9h8O-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310191944.Z8sC9h8O-lkp@intel.com/
# many are suggestions rather than must-fix
ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#32: FILE: arch/x86/include/asm/alternative.h:334:
+#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")
On Thu, Oct 19, 2023 at 11:15:16AM +0200, Juergen Gross wrote:
> +/* Low-level backend functions usable from alternative code replacements. */
> +DEFINE_ASM_FUNC(x86_nop, "", .entry.text);
> +EXPORT_SYMBOL_GPL(x86_nop);
This is all x86 code so you don't really need the "x86_" prefix - "nop"
is perfectly fine.
> +noinstr void x86_BUG(void)
> +{
> + BUG();
> +}
> +EXPORT_SYMBOL_GPL(x86_BUG);
That export is needed for?
Paravirt stuff in modules?
It builds here without it - I guess I need to do an allmodconfig.
On 25.10.23 12:34, Borislav Petkov wrote:
> On Thu, Oct 19, 2023 at 11:15:16AM +0200, Juergen Gross wrote:
>> +/* Low-level backend functions usable from alternative code replacements. */
>> +DEFINE_ASM_FUNC(x86_nop, "", .entry.text);
>> +EXPORT_SYMBOL_GPL(x86_nop);
>
> This is all x86 code so you don't really need the "x86_" prefix - "nop"
> is perfectly fine.
There is
#define nop() asm volatile ("nop")
in arch/x86/include/asm/special_insns.h already.
>
>> +noinstr void x86_BUG(void)
>> +{
>> + BUG();
>> +}
>> +EXPORT_SYMBOL_GPL(x86_BUG);
>
> That export is needed for?
>
> Paravirt stuff in modules?
>
> It builds here without it - I guess I need to do an allmodconfig.
>
It might not be needed now, but are you sure we won't need it in future?
Juergen
On Wed, Oct 25, 2023 at 03:31:07PM +0200, Juergen Gross wrote:
> There is
>
> #define nop() asm volatile ("nop")
>
> in arch/x86/include/asm/special_insns.h already.
Then call it "nop_func" or so.
> It might not be needed now, but are you sure we won't need it in future?
No, I'm not.
What I'm sure of is: stuff should be added to the kernel only when
really needed. Not in the expectation that it might potentially be
needed at some point.
Thx.
On 25.10.23 15:44, Borislav Petkov wrote:
> On Wed, Oct 25, 2023 at 03:31:07PM +0200, Juergen Gross wrote:
>> There is
>>
>> #define nop() asm volatile ("nop")
>>
>> in arch/x86/include/asm/special_insns.h already.
>
> Then call it "nop_func" or so.
Okay.
>
>> It might not be needed now, but are you sure we won't need it in future?
>
> No, I'm not.
>
> What I'm sure of is: stuff should be added to the kernel only when
> really needed. Not in the expectation that it might potentially be
> needed at some point.
Will double check whether it is needed now.
Juergen
On 25.10.23 12:34, Borislav Petkov wrote:
> On Thu, Oct 19, 2023 at 11:15:16AM +0200, Juergen Gross wrote:
>> +/* Low-level backend functions usable from alternative code replacements. */
>> +DEFINE_ASM_FUNC(x86_nop, "", .entry.text);
>> +EXPORT_SYMBOL_GPL(x86_nop);
>
> This is all x86 code so you don't really need the "x86_" prefix - "nop"
> is perfectly fine.
>
>> +noinstr void x86_BUG(void)
>> +{
>> + BUG();
>> +}
>> +EXPORT_SYMBOL_GPL(x86_BUG);
>
> That export is needed for?
>
> Paravirt stuff in modules?
>
> It builds here without it - I guess I need to do an allmodconfig.
>
Turns out it is needed after all. With patch 4 applied I get:
ERROR: modpost: "BUG_func" [arch/x86/events/amd/power.ko] undefined!
ERROR: modpost: "BUG_func" [arch/x86/kernel/cpu/mce/mce-inject.ko] undefined!
ERROR: modpost: "BUG_func" [arch/x86/kernel/cpuid.ko] undefined!
ERROR: modpost: "BUG_func" [arch/x86/kvm/kvm.ko] undefined!
ERROR: modpost: "BUG_func" [arch/x86/kvm/kvm-intel.ko] undefined!
ERROR: modpost: "BUG_func" [arch/x86/kvm/kvm-amd.ko] undefined!
ERROR: modpost: "BUG_func" [fs/nfsd/nfsd.ko] undefined!
ERROR: modpost: "BUG_func" [crypto/aes_ti.ko] undefined!
ERROR: modpost: "BUG_func" [drivers/video/fbdev/uvesafb.ko] undefined!
ERROR: modpost: "BUG_func" [drivers/video/vgastate.ko] undefined!
Juergen
@@ -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 x86_BUG(void);
+void x86_nop(void);
+
#else /* __ASSEMBLY__ */
#ifdef CONFIG_SMP
@@ -726,18 +726,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;
@@ -542,8 +542,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);
@@ -553,7 +551,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 *)x86_nop)
extern struct paravirt_patch_site __parainstructions[],
__parainstructions_end[];
@@ -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 */
@@ -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(x86_nop, "", .entry.text);
+EXPORT_SYMBOL_GPL(x86_nop);
+
+noinstr void x86_BUG(void)
+{
+ BUG();
+}
+EXPORT_SYMBOL_GPL(x86_BUG);
+
/*
* Replace instructions with better alternatives for this CPU type. This runs
* before SMP is initialized to avoid SMP problems with self modifying code.
@@ -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)
@@ -34,14 +34,8 @@
#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 x86_BUG() */
+ ret = paravirt_patch_call(insn_buff, x86_BUG, addr, len);
+ else if (opfunc == x86_nop)
ret = 0;
else
/* Otherwise call the function. */
@@ -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(x86_BUG),
.safe_halt = xen_safe_halt,
.halt = xen_halt,