Using the full 64-bit register values is slightly wrong in this case;
32-bit writes of registers would normally zero-extend the value to 64
bits. The difference may be observable after switching (back) to 64-bit
mode (even if as per the spec upper halves of registers are undefined
after a mode switch, in reality they retain their values).

Fixes: 33a7028fec44 ("Nexted VMX: Emulation of guest VMREAD")
Signed-off-by: Jan Beulich <jbeul...@suse.com>
---
Note that the sole affected VMX insn (VMREAD) is invalid to use from
compatibility mode, and hence the more expensive vmx_guest_x86_mode()
doesn't need using here.
---
v2: Add code comment.

--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -378,6 +378,14 @@ static void reg_write(struct cpu_user_re
                       unsigned int index,
                       unsigned long value)
 {
+    /*
+     * Outside of 64-bit mode, make sure we don't store non-zero upper halves
+     * in GPRs.
+     * NB: A long-mode check is sufficient here, as insns this logic is used
+     * for will #UD in compatibility mode (and hence not make it here).
+     */
+    if ( !hvm_long_mode_active(current) )
+        value = (uint32_t)value;
     *decode_gpr(regs, index) = value;
 }
 


Reply via email to