diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 855147d7f3..1774966305 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2411,6 +2411,8 @@ void asmlinkage entry_from_pv(struct cpu_user_regs *regs) regs->ssx = l ? FLAT_KERNEL_SS : FLAT_USER_SS32; regs->csx = l ? FLAT_KERNEL_CS64 : FLAT_USER_CS32; + regs->rcx = regs->rip; + regs->r11 = regs->rflags; if ( guest_kernel_mode(curr, regs) ) pv_hypercall(regs); diff --git a/xen/arch/x86/x86_64/entry-fred.S b/xen/arch/x86/x86_64/entry-fred.S index 2fa57beb93..e9c84423da 100644 --- a/xen/arch/x86/x86_64/entry-fred.S +++ b/xen/arch/x86/x86_64/entry-fred.S @@ -4,6 +4,7 @@ #include #include +#include .section .text.entry, "ax", @progbits @@ -26,7 +27,16 @@ FUNC(entry_FRED_R3, 4096) END(entry_FRED_R3) FUNC(eretu_exit_to_guest) - POP_GPRS + /* + * PV guests aren't aware of FRED. If Xen in IDT mode would have used + * a SYSRET instruction, preserve the legacy behaviour for %rcx/%r11 + */ + testb $TRAP_syscall >> 8, UREGS_entry_vector + 1(%rsp) + + POP_GPRS /* Preserves flags */ + + cmovnz EFRAME_rip(%rsp), %rcx + cmovnz EFRAME_eflags(%rsp), %r11 /* * Exceptions here are handled by redirecting either to