diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 228763b5e9..5dbd1d8a12 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -2112,12 +2112,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next) /* Ensure that the vcpu has an up-to-date time base. */ update_vcpu_system_time(next); - reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail); + reset_stack_and_call_ind(nextd->arch.ctxt_switch->tail); } void continue_running(struct vcpu *same) { - reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail); + reset_stack_and_call_ind(same->domain->arch.ctxt_switch->tail); } int __sync_local_execstate(void) diff --git a/xen/arch/x86/include/asm/current.h b/xen/arch/x86/include/asm/current.h index ba82b413e2..2f723bcf1b 100644 --- a/xen/arch/x86/include/asm/current.h +++ b/xen/arch/x86/include/asm/current.h @@ -196,10 +196,10 @@ unsigned long get_stack_dump_bottom (unsigned long sp); switch_stack_and_jump(fn, "jmp %c", "i") /* The constraint may only specify non-call-clobbered registers. */ -#define reset_stack_and_jump_ind(fn) \ +#define reset_stack_and_call_ind(fn) \ ({ \ (void)((fn) == (void (*)(void))NULL); \ - switch_stack_and_jump(fn, "INDIRECT_JMP %", "b"); \ + switch_stack_and_jump(fn, "INDIRECT_CALL %", "b"); \ }) /* diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 801d241337..9c256746ba 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -637,6 +637,14 @@ ENTRY(dom_crash_sync_extable) #ifdef CONFIG_PV ENTRY(continue_pv_domain) ENDBR64 + + /* + * For speculative type confusion reasons, we're CALLed rather than + * JMPed to. Drop the return address. + */ + add $8, %rsp + ALTERNATIVE "", "mov $2, %eax; incsspd %eax", X86_FEATURE_XEN_SHSTK + call check_wakeup_from_wait ret_from_intr: GET_CURRENT(bx)