Skip to content

Commit

Permalink
x86/paravirt: Move some functions and defines to alternative.c
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Juergen Gross authored and Borislav Petkov (AMD) committed Dec 10, 2023
1 parent 772ca41 commit 9824b00
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 41 deletions.
16 changes: 16 additions & 0 deletions arch/x86/include/asm/alternative.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 0 additions & 12 deletions arch/x86/include/asm/paravirt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 1 addition & 3 deletions arch/x86/include/asm/paravirt_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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[];
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/include/asm/qspinlock_paravirt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
10 changes: 10 additions & 0 deletions arch/x86/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 9 additions & 21 deletions arch/x86/kernel/paravirt.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,15 @@
#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)
{
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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. */
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/xen/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 9824b00

Please sign in to comment.