From patchwork Mon Mar 28 10:46:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 668051 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2SAlY5r016204 for ; Mon, 28 Mar 2011 10:47:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753250Ab1C1Kr3 (ORCPT ); Mon, 28 Mar 2011 06:47:29 -0400 Received: from va3ehsobe006.messaging.microsoft.com ([216.32.180.16]:44445 "EHLO VA3EHSOBE006.bigfish.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753192Ab1C1KrF (ORCPT ); Mon, 28 Mar 2011 06:47:05 -0400 Received: from mail3-va3-R.bigfish.com (10.7.14.247) by VA3EHSOBE006.bigfish.com (10.7.40.26) with Microsoft SMTP Server id 14.1.225.8; Mon, 28 Mar 2011 10:47:01 +0000 Received: from mail3-va3 (localhost.localdomain [127.0.0.1]) by mail3-va3-R.bigfish.com (Postfix) with ESMTP id 14CCC430151; Mon, 28 Mar 2011 10:47:01 +0000 (UTC) X-SpamScore: -2 X-BigFish: VPS-2(zzbb2cKzz1202hzz8275bhz32i668h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:ausb3twp02.amd.com; RD:none; EFVD:NLI Received: from mail3-va3 (localhost.localdomain [127.0.0.1]) by mail3-va3 (MessageSwitch) id 1301309220612390_12145; Mon, 28 Mar 2011 10:47:00 +0000 (UTC) Received: from VA3EHSMHS028.bigfish.com (unknown [10.7.14.242]) by mail3-va3.bigfish.com (Postfix) with ESMTP id 90A23100004D; Mon, 28 Mar 2011 10:47:00 +0000 (UTC) Received: from ausb3twp02.amd.com (163.181.249.109) by VA3EHSMHS028.bigfish.com (10.7.99.38) with Microsoft SMTP Server id 14.1.225.22; Mon, 28 Mar 2011 10:47:00 +0000 X-WSS-ID: 0LIRKM6-02-05I-02 X-M-MSG: Received: from sausexedgep01.amd.com (sausexedgep01-ext.amd.com [163.181.249.72]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by ausb3twp02.amd.com (Tumbleweed MailGate 3.7.2) with ESMTP id 2D102C87F3; Mon, 28 Mar 2011 05:46:54 -0500 (CDT) Received: from sausexhtp02.amd.com (163.181.3.152) by sausexedgep01.amd.com (163.181.36.54) with Microsoft SMTP Server (TLS) id 8.3.106.1; Mon, 28 Mar 2011 05:54:33 -0500 Received: from storexhtp02.amd.com (172.24.4.4) by sausexhtp02.amd.com (163.181.3.152) with Microsoft SMTP Server (TLS) id 8.3.83.0; Mon, 28 Mar 2011 05:46:58 -0500 Received: from gwo.osrc.amd.com (165.204.16.204) by storexhtp02.amd.com (172.24.4.4) with Microsoft SMTP Server id 8.3.83.0; Mon, 28 Mar 2011 06:46:57 -0400 Received: from lemmy.osrc.amd.com (lemmy.osrc.amd.com [165.204.15.93]) by gwo.osrc.amd.com (Postfix) with ESMTP id 7156749C5A9; Mon, 28 Mar 2011 11:46:55 +0100 (BST) Received: by lemmy.osrc.amd.com (Postfix, from userid 1000) id 673C1FFB8B; Mon, 28 Mar 2011 12:46:55 +0200 (CEST) From: Joerg Roedel To: Avi Kivity , Marcelo Tosatti CC: , Joerg Roedel Subject: [PATCH 12/13] KVM: SVM: Add checks for IO instructions Date: Mon, 28 Mar 2011 12:46:49 +0200 Message-ID: <1301309210-11120-13-git-send-email-joerg.roedel@amd.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1301309210-11120-1-git-send-email-joerg.roedel@amd.com> References: <1301309210-11120-1-git-send-email-joerg.roedel@amd.com> MIME-Version: 1.0 X-OriginatorOrg: amd.com 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.6 (demeter1.kernel.org [140.211.167.41]); Mon, 28 Mar 2011 10:47:34 +0000 (UTC) diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index db0bbc2..53bfc99 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -335,6 +335,10 @@ enum x86_intercept { x86_intercept_mwait, x86_intercept_rdmsr, x86_intercept_wrmsr, + x86_intercept_in, + x86_intercept_ins, + x86_intercept_out, + x86_intercept_outs, nr_x86_intercepts }; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index af04be4..ecfea47 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2359,6 +2359,7 @@ static int em_mov(struct x86_emulate_ctxt *ctxt) { .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i } #define D2bv(_f) D((_f) | ByteOp), D(_f) +#define D2bvI(_f, _i) DI((_f) | ByteOp, _i), DI((_f), _i) #define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e) #define D6ALU(_f) D2bv((_f) | DstMem | SrcReg | ModRM), \ @@ -2488,8 +2489,8 @@ static struct opcode opcode_table[256] = { I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op), I(SrcImmByte | Mov | Stack, em_push), I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op), - D2bv(DstDI | Mov | String), /* insb, insw/insd */ - D2bv(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */ + D2bvI(DstDI | Mov | String, ins), /* insb, insw/insd */ + D2bvI(SrcSI | ImplicitOps | String, outs), /* outsb, outsw/outsd */ /* 0x70 - 0x7F */ X16(D(SrcImmByte)), /* 0x80 - 0x87 */ @@ -2540,11 +2541,11 @@ static struct opcode opcode_table[256] = { N, N, N, N, N, N, N, N, /* 0xE0 - 0xE7 */ X4(D(SrcImmByte)), - D2bv(SrcImmUByte | DstAcc), D2bv(SrcAcc | DstImmUByte), + D2bvI(SrcImmUByte | DstAcc, in), D2bvI(SrcAcc | DstImmUByte, out), /* 0xE8 - 0xEF */ D(SrcImm | Stack), D(SrcImm | ImplicitOps), D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), - D2bv(SrcNone | DstAcc), D2bv(SrcAcc | ImplicitOps), + D2bvI(SrcNone | DstAcc, in), D2bvI(SrcAcc | ImplicitOps, out), /* 0xF0 - 0xF7 */ N, DI(ImplicitOps, icebp), N, N, DI(ImplicitOps | Priv, hlt), D(ImplicitOps), @@ -2629,6 +2630,7 @@ static struct opcode twobyte_table[256] = { #undef EXT #undef D2bv +#undef D2bvI #undef I2bv #undef D6ALU diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 67997b3..3701ded 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3926,6 +3926,10 @@ static struct __x86_intercept { [x86_intercept_iret] = PRE_EX(SVM_EXIT_IRET), [x86_intercept_icebp] = PRE_EX(SVM_EXIT_ICEBP), [x86_intercept_hlt] = POST_EX(SVM_EXIT_HLT), + [x86_intercept_in] = POST_EX(SVM_EXIT_IOIO), + [x86_intercept_ins] = POST_EX(SVM_EXIT_IOIO), + [x86_intercept_out] = POST_EX(SVM_EXIT_IOIO), + [x86_intercept_outs] = POST_EX(SVM_EXIT_IOIO), }; #undef PRE_EX @@ -4002,6 +4006,38 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, */ if (info->rep_prefix != REPE_PREFIX) goto out; + case SVM_EXIT_IOIO: { + u64 exit_info; + u32 bytes; + + exit_info = (vcpu->arch.regs[VCPU_REGS_RDX] & 0xffff) << 16; + + if (info->intercept == x86_intercept_in || + info->intercept == x86_intercept_ins) { + exit_info |= SVM_IOIO_TYPE_MASK; + bytes = info->src_bytes; + } else { + bytes = info->dst_bytes; + } + + if (info->intercept == x86_intercept_outs || + info->intercept == x86_intercept_ins) + exit_info |= SVM_IOIO_STR_MASK; + + if (info->rep_prefix) + exit_info |= SVM_IOIO_REP_MASK; + + bytes = min(bytes, 4u); + + exit_info |= bytes << SVM_IOIO_SIZE_SHIFT; + + exit_info |= (u32)info->ad_bytes << (SVM_IOIO_ASIZE_SHIFT - 1); + + vmcb->control.exit_info_1 = exit_info; + vmcb->control.exit_info_2 = info->next_rip; + + break; + } default: break; }