mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
x86/paravirt: Move some functions and defines to alternative.c
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
This commit is contained in:
parent
772ca41353
commit
9824b00c2b
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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[];
|
||||
|
@ -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(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.
|
||||
|
@ -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 BUG_func() */
|
||||
ret = paravirt_patch_call(insn_buff, BUG_func, addr, len);
|
||||
else if (opfunc == nop_func)
|
||||
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(BUG_func),
|
||||
|
||||
.safe_halt = xen_safe_halt,
|
||||
.halt = xen_halt,
|
||||
|
Loading…
Reference in New Issue
Block a user