Message ID | 20231019091520.14540-2-jgross@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86/paravirt: Get rid of paravirt patching | expand |
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
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 9c4da699e11a..67e50bd40bb8 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -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 diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6c8ff12140ae..ed5c7342f2ef 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -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; diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 772d03487520..9f84dc074f88 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -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[]; diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h index 85b6e3609cb9..ef9697f20129 100644 --- a/arch/x86/include/asm/qspinlock_paravirt.h +++ b/arch/x86/include/asm/qspinlock_paravirt.h @@ -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 */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 73be3931e4f0..1c8dd8e05f3f 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -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. diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b8ab9ee5896c..4ca59dccc15a 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -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) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 97f1436c1a20..32792b033de2 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -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. */ diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 6092fea7d651..5d132f5a5d7d 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c @@ -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,