From 03878fba4af14fab942c2ce8ed2d6d18c204a603 Mon Sep 17 00:00:00 2001 From: Teddy Astie Date: Fri, 22 May 2026 14:33:16 +0200 Subject: [PATCH] x86/pv32: Fix bogus CR2 in pagefault for gate emulation __{put,get}_guest() returns -EFAULT on access faults which causes the injected CR2 to be off by 14 bytes (as EFAULT is 14) which is incorrect. Fix the computation by relying on __copy_{from,to}_guest_pv() which reports the number of remaining bytes instead of a negative errno, such that we can compute the offset properly. Fixes: 70ad570b2799 ("x86/64: paravirt 32-on-64 call gate support") Signed-off-by: Teddy Astie Reviewed-by: Jan Beulich --- xen/arch/x86/pv/emul-gate-op.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/pv/emul-gate-op.c b/xen/arch/x86/pv/emul-gate-op.c index c2c699fbff..d0f7f06e01 100644 --- a/xen/arch/x86/pv/emul-gate-op.c +++ b/xen/arch/x86/pv/emul-gate-op.c @@ -286,12 +286,14 @@ void pv_emulate_gate_op(struct cpu_user_regs *regs) if ( !jump ) { unsigned int ss, esp, *stkp; + uint32_t value; int rc; #define push(item) do \ { \ + value = (item); \ --stkp; \ esp -= 4; \ - rc = __put_guest(item, stkp); \ + rc = __copy_to_guest_pv(stkp, &value, sizeof(value)); \ if ( rc ) \ { \ pv_inject_page_fault(PFEC_write_access, \ @@ -359,7 +361,7 @@ void pv_emulate_gate_op(struct cpu_user_regs *regs) unsigned int parm; --ustkp; - rc = __get_guest(parm, ustkp); + rc = __copy_from_guest_pv(&parm, ustkp, sizeof(parm)); if ( rc ) { pv_inject_page_fault(0, (unsigned long)(ustkp + 1) - rc);