mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-22 20:43:56 +08:00
x86/paravirt: Switch iret pvops to ALTERNATIVE
The iret paravirt op is rather special as it is using a jmp instead of a call instruction. Switch it to ALTERNATIVE. Signed-off-by: Juergen Gross <jgross@suse.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20210311142319.4723-12-jgross@suse.com
This commit is contained in:
parent
0b8d366a94
commit
ae755b5a45
@ -747,9 +747,9 @@ extern void default_banner(void);
|
||||
#define PARA_INDIRECT(addr) *addr(%rip)
|
||||
|
||||
#define INTERRUPT_RETURN \
|
||||
PARA_SITE(PARA_PATCH(PV_CPU_iret), \
|
||||
ANNOTATE_RETPOLINE_SAFE; \
|
||||
jmp PARA_INDIRECT(pv_ops+PV_CPU_iret);)
|
||||
ANNOTATE_RETPOLINE_SAFE; \
|
||||
ALTERNATIVE_TERNARY("jmp *paravirt_iret(%rip);", \
|
||||
X86_FEATURE_XENPV, "jmp xen_iret;", "jmp native_iret;")
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENTRY
|
||||
#define SAVE_FLAGS(clobbers) \
|
||||
|
@ -151,10 +151,6 @@ struct pv_cpu_ops {
|
||||
|
||||
u64 (*read_pmc)(int counter);
|
||||
|
||||
/* Normal iret. Jump to this with the standard iret stack
|
||||
frame set up. */
|
||||
void (*iret)(void);
|
||||
|
||||
void (*start_context_switch)(struct task_struct *prev);
|
||||
void (*end_context_switch)(struct task_struct *next);
|
||||
#endif
|
||||
@ -294,6 +290,7 @@ struct paravirt_patch_template {
|
||||
|
||||
extern struct pv_info pv_info;
|
||||
extern struct paravirt_patch_template pv_ops;
|
||||
extern void (*paravirt_iret)(void);
|
||||
|
||||
#define PARAVIRT_PATCH(x) \
|
||||
(offsetof(struct paravirt_patch_template, x) / sizeof(void *))
|
||||
|
@ -61,11 +61,6 @@ static void __used common(void)
|
||||
OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
BLANK();
|
||||
OFFSET(PV_CPU_iret, paravirt_patch_template, cpu.iret);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
BLANK();
|
||||
OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
|
||||
|
@ -86,25 +86,6 @@ u64 notrace _paravirt_ident_64(u64 x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned paravirt_patch_jmp(void *insn_buff, const void *target,
|
||||
unsigned long addr, unsigned len)
|
||||
{
|
||||
struct branch *b = insn_buff;
|
||||
unsigned long delta = (unsigned long)target - (addr+5);
|
||||
|
||||
if (len < 5) {
|
||||
#ifdef CONFIG_RETPOLINE
|
||||
WARN_ONCE(1, "Failing to patch indirect JMP in %ps\n", (void *)addr);
|
||||
#endif
|
||||
return len; /* call too long for patch site */
|
||||
}
|
||||
|
||||
b->opcode = 0xe9; /* jmp */
|
||||
b->delta = delta;
|
||||
|
||||
return 5;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
|
||||
@ -136,9 +117,6 @@ unsigned paravirt_patch_default(u8 type, void *insn_buff,
|
||||
else if (opfunc == _paravirt_ident_64)
|
||||
ret = paravirt_patch_ident_64(insn_buff, len);
|
||||
|
||||
else if (type == PARAVIRT_PATCH(cpu.iret))
|
||||
/* If operation requires a jmp, then jmp */
|
||||
ret = paravirt_patch_jmp(insn_buff, opfunc, addr, len);
|
||||
#endif
|
||||
else
|
||||
/* Otherwise call the function. */
|
||||
@ -313,8 +291,6 @@ struct paravirt_patch_template pv_ops = {
|
||||
|
||||
.cpu.load_sp0 = native_load_sp0,
|
||||
|
||||
.cpu.iret = native_iret,
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
.cpu.invalidate_io_bitmap = native_tss_invalidate_io_bitmap,
|
||||
.cpu.update_io_bitmap = native_tss_update_io_bitmap,
|
||||
@ -419,6 +395,8 @@ struct paravirt_patch_template pv_ops = {
|
||||
NOKPROBE_SYMBOL(native_get_debugreg);
|
||||
NOKPROBE_SYMBOL(native_set_debugreg);
|
||||
NOKPROBE_SYMBOL(native_load_idt);
|
||||
|
||||
void (*paravirt_iret)(void) = native_iret;
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(pv_ops);
|
||||
|
@ -1070,8 +1070,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
|
||||
|
||||
.read_pmc = xen_read_pmc,
|
||||
|
||||
.iret = xen_iret,
|
||||
|
||||
.load_tr_desc = paravirt_nop,
|
||||
.set_ldt = xen_set_ldt,
|
||||
.load_gdt = xen_load_gdt,
|
||||
@ -1235,6 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
||||
pv_info = xen_info;
|
||||
pv_ops.init.patch = paravirt_patch_default;
|
||||
pv_ops.cpu = xen_cpu_ops;
|
||||
paravirt_iret = xen_iret;
|
||||
xen_init_irq_ops();
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user