diff mbox

[06/21] KVM: x86: Emulator MOV-sreg uses incorrect size

Message ID 1414922101-17626-7-git-send-email-namit@cs.technion.ac.il (mailing list archive)
State New, archived
Headers show

Commit Message

Nadav Amit Nov. 2, 2014, 9:54 a.m. UTC
In x86, you cannot MOV-sreg to memory is either 16-bits or 64-bits.  When
destination is registers, and the operand size is 32-bits, the high 16-bits in
modern CPUs is filled with zero.

In contrast, KVM may write to memory 32-bits on MOV-sreg. This patch fixes KVM
behavior, and sets the destination operand size to two, if the destination is
memory.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Paolo Bonzini Nov. 5, 2014, 11:28 a.m. UTC | #1
On 02/11/2014 10:54, Nadav Amit wrote:
> In x86, you cannot MOV-sreg to memory is either 16-bits or 64-bits.  When
> destination is registers, and the operand size is 32-bits, the high 16-bits in
> modern CPUs is filled with zero.
> 
> In contrast, KVM may write to memory 32-bits on MOV-sreg. This patch fixes KVM
> behavior, and sets the destination operand size to two, if the destination is
> memory.

    KVM: x86: Emulation of MOV-sreg to memory uses incorrect size
    
    In x86, you can only MOV-sreg to memory with either 16-bits or 64-bits size.
    In contrast, KVM may write to 32-bits memory on MOV-sreg. This patch fixes KVM
    behavior, and sets the destination operand size to two, if the destination is
    memory.
    
    When destination is registers, and the operand size is 32-bits, the high
    16-bits in modern CPUs is filled with zero.  This is handled correctly.
    
    Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

> Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
> ---
>  arch/x86/kvm/emulate.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 273c37e..f456783 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3187,6 +3187,8 @@ static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
>  		return emulate_ud(ctxt);
>  
>  	ctxt->dst.val = get_segment_selector(ctxt, ctxt->modrm_reg);
> +	if (ctxt->dst.bytes == 4 && ctxt->dst.type == OP_MEM)
> +		ctxt->dst.bytes = 2;
>  	return X86EMUL_CONTINUE;
>  }
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 273c37e..f456783 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3187,6 +3187,8 @@  static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
 		return emulate_ud(ctxt);
 
 	ctxt->dst.val = get_segment_selector(ctxt, ctxt->modrm_reg);
+	if (ctxt->dst.bytes == 4 && ctxt->dst.type == OP_MEM)
+		ctxt->dst.bytes = 2;
 	return X86EMUL_CONTINUE;
 }