From patchwork Fri Mar 25 09:29:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 661421 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 p2P9TYmw015335 for ; Fri, 25 Mar 2011 09:29:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933893Ab1CYJ3q (ORCPT ); Fri, 25 Mar 2011 05:29:46 -0400 Received: from ch1outboundpool.messaging.microsoft.com ([216.32.181.181]:46699 "EHLO ch1outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933891Ab1CYJ3e (ORCPT ); Fri, 25 Mar 2011 05:29:34 -0400 Received: from mail117-ch1-R.bigfish.com (216.32.181.171) by CH1EHSOBE004.bigfish.com (10.43.70.54) with Microsoft SMTP Server id 14.1.225.8; Fri, 25 Mar 2011 09:29:30 +0000 Received: from mail117-ch1 (localhost.localdomain [127.0.0.1]) by mail117-ch1-R.bigfish.com (Postfix) with ESMTP id 2EEDC13001BB; Fri, 25 Mar 2011 09:29:30 +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 mail117-ch1 (localhost.localdomain [127.0.0.1]) by mail117-ch1 (MessageSwitch) id 1301045369826624_13007; Fri, 25 Mar 2011 09:29:29 +0000 (UTC) Received: from CH1EHSMHS010.bigfish.com (snatpool1.int.messaging.microsoft.com [10.43.68.247]) by mail117-ch1.bigfish.com (Postfix) with ESMTP id C68FDE9804E; Fri, 25 Mar 2011 09:29:29 +0000 (UTC) Received: from ausb3twp02.amd.com (163.181.249.109) by CH1EHSMHS010.bigfish.com (10.43.70.10) with Microsoft SMTP Server id 14.1.225.8; Fri, 25 Mar 2011 09:29:28 +0000 X-WSS-ID: 0LILX0Y-02-62X-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 2F15BC879C; Fri, 25 Mar 2011 04:29:22 -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; Fri, 25 Mar 2011 04:36:51 -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; Fri, 25 Mar 2011 04:29:26 -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; Fri, 25 Mar 2011 05:29:25 -0400 Received: from lemmy.osrc.amd.com (lemmy.osrc.amd.com [165.204.15.93]) by gwo.osrc.amd.com (Postfix) with ESMTP id C9BEB49C5A5; Fri, 25 Mar 2011 09:29:23 +0000 (GMT) Received: by lemmy.osrc.amd.com (Postfix, from userid 1000) id BD642FFBB7; Fri, 25 Mar 2011 10:29:23 +0100 (CET) From: Joerg Roedel To: Avi Kivity , Marcelo Tosatti CC: , Joerg Roedel Subject: [PATCH 12/13] KVM: SVM: Add checks for IO instructions Date: Fri, 25 Mar 2011 10:29:15 +0100 Message-ID: <1301045356-25257-13-git-send-email-joerg.roedel@amd.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1301045356-25257-1-git-send-email-joerg.roedel@amd.com> References: <1301045356-25257-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]); Fri, 25 Mar 2011 09:29:50 +0000 (UTC) diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 41c0120..0b2e2de 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -317,6 +317,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 4c0939d..879ce78 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2339,6 +2339,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), \ @@ -2468,8 +2469,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 */ @@ -2520,11 +2521,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), @@ -2609,6 +2610,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 847a3f9..1672e3c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3929,6 +3929,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 @@ -4004,6 +4008,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; }