KVM: x86 emulator: limit instructions to 15 bytes
authorAvi Kivity <avi@redhat.com>
Tue, 24 Nov 2009 11:20:15 +0000 (13:20 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 1 Apr 2010 22:52:23 +0000 (15:52 -0700)
commit eb3c79e64a70fb8f7473e30fa07e89c1ecc2c9bb upstream

[ <cebbert@redhat.com>: backport to 2.6.27 ]

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/kvm/x86_emulate.c
include/asm-x86/kvm_x86_emulate.h

index f2f9046..1dc1cfd 100644 (file)
@@ -581,6 +581,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++);
@@ -839,7 +842,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 = ctxt->vcpu->arch.rip;
+       c->eip = c->eip_orig = ctxt->vcpu->arch.rip;
        ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
        memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
 
index 4e8c1e4..fcbb680 100644 (file)
@@ -128,7 +128,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;