From patchwork Wed Aug 4 02:44:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohammed Gamal X-Patchwork-Id: 116915 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o742j5Mm000618 for ; Wed, 4 Aug 2010 02:45:05 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757951Ab0HDCpB (ORCPT ); Tue, 3 Aug 2010 22:45:01 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:63970 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757691Ab0HDCpA (ORCPT ); Tue, 3 Aug 2010 22:45:00 -0400 Received: by wyb39 with SMTP id 39so5066232wyb.19 for ; Tue, 03 Aug 2010 19:44:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=HUPxEWyjCY95Te3dpz9ia4DUGgFqiiqC4fIyaSQUWio=; b=RNaNcZef4rJjwh6i7Pthljy6EM99AkbrnyGreSJWs8rPyOgJK8D2dKG8Vdar0aK8eR 08MdajK68mfPbzHI1REiT5llaCBB9uzhdkRkmifF/Dv6CtYpU/YhuZh1h/FohLH1sMDd BOnaZ3NhfD8m8OMWUU39K0zi+py3vnzGBPMpM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=l1SV3b3yvm33E7kLMWbH2MC52Cw+W6cie/2IuOAXCIfpl5p7JM3Ma9Hnmzph3/hT37 UbPyFK0ax6Cpcs7TLAgwnMrTiwJoeestjPw7cLTiQzmtgk9wxB8lcklAtmWLtRnXiv0d mUEaoxKhY409EEJG8P0JSoB25J6NlAoq0dza8= Received: by 10.227.136.2 with SMTP id p2mr7153176wbt.215.1280889899684; Tue, 03 Aug 2010 19:44:59 -0700 (PDT) Received: from localhost.localdomain ([188.51.108.67]) by mx.google.com with ESMTPS id f30sm6732413wbe.12.2010.08.03.19.44.57 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 03 Aug 2010 19:44:59 -0700 (PDT) From: Mohammed Gamal To: avi@redhat.com Cc: mtosatti@redhat.com, kvm@vger.kernel.org, Mohammed Gamal Subject: [PATCH 2/2] x86 emulator: Add into, int, and int3 instructions (opcodes 0xcc-0xce) Date: Wed, 4 Aug 2010 05:44:52 +0300 Message-Id: <1280889892-25751-1-git-send-email-m.gamal005@gmail.com> X-Mailer: git-send-email 1.7.0.4 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 04 Aug 2010 02:45:22 +0000 (UTC) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f03ff26..5afcc32 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1180,6 +1180,67 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt, return rc; } +int emulate_int_real(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, int irq) +{ + struct decode_cache *c = &ctxt->decode; + int rc = X86EMUL_CONTINUE; + struct desc_ptr dt; + gva_t cs_addr; + gva_t eip_addr; + u16 cs, eip; + u32 err; + + /* TODO: Add limit checks */ + c->src.val = ctxt->eflags; + emulate_push(ctxt, ops); + + ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); + + c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); + emulate_push(ctxt, ops); + + c->src.val = c->eip; + emulate_push(ctxt, ops); + + ops->get_idt(&dt, ctxt->vcpu); + + eip_addr = dt.address + (irq << 2); + cs_addr = dt.address + (irq << 2) + 2; + + rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &err); + if (rc != X86EMUL_CONTINUE) + return rc; + + rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &err); + if (rc != X86EMUL_CONTINUE) + return rc; + + rc = load_segment_descriptor(ctxt, ops, cs, VCPU_SREG_CS); + if (rc != X86EMUL_CONTINUE) + return rc; + + c->eip = eip; + + return rc; +} + +static int emulate_int(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, int irq) +{ + switch(ctxt->mode) { + case X86EMUL_MODE_REAL: + return emulate_int_real(ctxt, ops, irq); + case X86EMUL_MODE_VM86: + case X86EMUL_MODE_PROT16: + case X86EMUL_MODE_PROT32: + case X86EMUL_MODE_PROT64: + default: + /* Protected mode interrupts unimplemented yet */ + return X86EMUL_UNHANDLEABLE; + } +} + static int emulate_iret_real(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -2619,6 +2680,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) struct decode_cache *c = &ctxt->decode; int rc = X86EMUL_CONTINUE; int saved_dst_type = c->dst.type; + int irq; /* Used for int 3, int, and into */ ctxt->decode.mem_read.pos = 0; @@ -2963,6 +3025,21 @@ special_insn: if (rc != X86EMUL_CONTINUE) goto done; break; + case 0xcc: /* int3 */ + irq = 3; + goto do_interrupt; + case 0xcd: /* int n */ + irq = c->src.val; + do_interrupt: + rc = emulate_int(ctxt, ops, irq); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xce: /* into */ + if (ctxt->eflags & EFLG_OF) { + irq = 4; + goto do_interrupt; + } case 0xcf: /* iret */ rc = emulate_iret(ctxt, ops);