From: Jan Beulich Date: Fri, 4 Oct 2019 15:57:03 +0000 (+0200) Subject: x86emul: adjust MOVSXD source operand handling X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~1335 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=89a854301e815a6f43a695605a5a261d964fcc6b;p=xen.git x86emul: adjust MOVSXD source operand handling XED commit 1b2fd94425 ("Update MOVSXD to modern behavior") points out that as of SDM rev 064 MOVSXD is specified to read only 16 bits from memory (or register) when used without REX.W and with operand size override. Since the upper 16 bits of the value read won't be used anyway in this case, make the emulation uniformly follow this more compatible behavior when not emulating an AMD-like CPU, at the risk of missing an exception when emulating on/for older hardware (the boundary at SandyBridge noted in said commit looks questionable - I've observed the "new" behavior also on Westmere, and a discussion there lead to Mark finding that even Merom has this behavior already). Signed-off-by: Jan Beulich Acked-by: Andrew Cooper Release-acked-by: Juergen Gross --- diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 22c29b8280..8f50a4f2de 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -4051,8 +4051,12 @@ x86_emulate( /* movsxd */ if ( ea.type == OP_REG ) src.val = *ea.reg; - else if ( (rc = read_ulong(ea.mem.seg, ea.mem.off, - &src.val, 4, ctxt, ops)) ) + else if ( (rc = read_ulong(ea.mem.seg, ea.mem.off, &src.val, + (op_bytes == 2 && + !(ctxt->cpuid->x86_vendor & + (X86_VENDOR_AMD | X86_VENDOR_HYGON)) + ? 2 : 4), + ctxt, ops)) ) goto done; dst.val = (int32_t)src.val; }