]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
KVM: x86 emulator: limit instructions to 15 bytes
authorAvi Kivity <avi@redhat.com>
Tue, 24 Nov 2009 13:20:15 +0000 (15:20 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 1 Apr 2010 22:55:30 +0000 (15:55 -0700)
commit eb3c79e64a70fb8f7473e30fa07e89c1ecc2c9bb upstream

While we are never normally passed an instruction that exceeds 15 bytes,
smp games can cause us to attempt to interpret one, which will cause
large latencies in non-preempt hosts.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86/include/asm/kvm_x86_emulate.h
arch/x86/kvm/x86_emulate.c

index b7ed2c423116be32942ef23b63e5dc4f09492d9d..7c18e1230f5490f1f7a58bd103302ffcb8bf20b1 100644 (file)
@@ -129,7 +129,7 @@ struct decode_cache {
        u8 seg_override;
        unsigned int d;
        unsigned long regs[NR_VCPU_REGS];
-       unsigned long eip;
+       unsigned long eip, eip_orig;
        /* modrm */
        u8 modrm;
        u8 modrm_mod;
index ef4dfca3ed7e6aba4ca2c742071b83067171e3dd..4b12352d03990ce1455c7364066de778df0f42f4 100644 (file)
@@ -606,6 +606,9 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
 {
        int rc = 0;
 
+       /* x86 instructions are limited to 15 bytes. */
+       if (eip + size - ctxt->decode.eip_orig > 15)
+               return X86EMUL_UNHANDLEABLE;
        eip += ctxt->cs_base;
        while (size--) {
                rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
@@ -864,7 +867,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        /* Shadow copy of register state. Committed on successful emulation. */
 
        memset(c, 0, sizeof(struct decode_cache));
-       c->eip = kvm_rip_read(ctxt->vcpu);
+       c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu);
        ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
        memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);