]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
KVM: x86: Decoding guest instructions which cross page boundary may fail
authorNadav Amit <namit@cs.technion.ac.il>
Thu, 2 Oct 2014 22:10:04 +0000 (01:10 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 24 Oct 2014 11:21:18 +0000 (13:21 +0200)
Once an instruction crosses a page boundary, the size read from the second page
disregards the common case that part of the operand resides on the first page.
As a result, fetch of long insturctions may fail, and thereby cause the
decoding to fail as well.

Cc: stable@vger.kernel.org
Fixes: 5cfc7e0f5e5e1adf998df94f8e36edaf5d30d38e
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c

index c0deaff8d9f04d6bdc89f50ddb79343bf5ca56e1..02c8ea804aaf5e13d0e5fceb284d6b0a0b906157 100644 (file)
@@ -778,8 +778,10 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
 static __always_inline int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt,
                                               unsigned size)
 {
-       if (unlikely(ctxt->fetch.end - ctxt->fetch.ptr < size))
-               return __do_insn_fetch_bytes(ctxt, size);
+       unsigned done_size = ctxt->fetch.end - ctxt->fetch.ptr;
+
+       if (unlikely(done_size < size))
+               return __do_insn_fetch_bytes(ctxt, size - done_size);
        else
                return X86EMUL_CONTINUE;
 }