From patchwork Mon Apr 4 10:39:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 685051 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 p34AfbMV021427 for ; Mon, 4 Apr 2011 10:41:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754534Ab1DDKlc (ORCPT ); Mon, 4 Apr 2011 06:41:32 -0400 Received: from tx2ehsobe001.messaging.microsoft.com ([65.55.88.11]:9675 "EHLO TX2EHSOBE002.bigfish.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754511Ab1DDKl3 (ORCPT ); Mon, 4 Apr 2011 06:41:29 -0400 Received: from mail157-tx2-R.bigfish.com (10.9.14.243) by TX2EHSOBE002.bigfish.com (10.9.40.22) with Microsoft SMTP Server id 14.1.225.8; Mon, 4 Apr 2011 10:41:29 +0000 Received: from mail157-tx2 (localhost.localdomain [127.0.0.1]) by mail157-tx2-R.bigfish.com (Postfix) with ESMTP id CD808F814D; Mon, 4 Apr 2011 10:41:17 +0000 (UTC) X-SpamScore: -2 X-BigFish: VPS-2(zzbb2cKzz1202hzz8275bhz32i668h839h62h) X-Spam-TCS-SCL: 1:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:ausb3twp01.amd.com; RD:none; EFVD:NLI Received: from mail157-tx2 (localhost.localdomain [127.0.0.1]) by mail157-tx2 (MessageSwitch) id 1301913663563437_15228; Mon, 4 Apr 2011 10:41:03 +0000 (UTC) Received: from TX2EHSMHS049.bigfish.com (unknown [10.9.14.246]) by mail157-tx2.bigfish.com (Postfix) with ESMTP id 4CF401A60081; Mon, 4 Apr 2011 10:39:49 +0000 (UTC) Received: from ausb3twp01.amd.com (163.181.249.108) by TX2EHSMHS049.bigfish.com (10.9.99.149) with Microsoft SMTP Server id 14.1.225.8; Mon, 4 Apr 2011 10:39:46 +0000 X-WSS-ID: 0LJ4IY8-01-377-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 ausb3twp01.amd.com (Axway MailGate 3.8.1) with ESMTP id 21B25D12BB2; Mon, 4 Apr 2011 05:39:44 -0500 (CDT) Received: from sausexhtp01.amd.com (163.181.3.165) by sausexedgep01.amd.com (163.181.36.54) with Microsoft SMTP Server (TLS) id 8.3.106.1; Mon, 4 Apr 2011 05:39:58 -0500 Received: from storexhtp01.amd.com (172.24.4.3) by sausexhtp01.amd.com (163.181.3.165) with Microsoft SMTP Server (TLS) id 8.3.83.0; Mon, 4 Apr 2011 05:39:45 -0500 Received: from gwo.osrc.amd.com (165.204.16.204) by storexhtp01.amd.com (172.24.4.3) with Microsoft SMTP Server id 8.3.83.0; Mon, 4 Apr 2011 06:39:44 -0400 Received: from lemmy.osrc.amd.com (lemmy.osrc.amd.com [165.204.15.93]) by gwo.osrc.amd.com (Postfix) with ESMTP id 4317349C5AF; Mon, 4 Apr 2011 11:39:41 +0100 (BST) Received: by lemmy.osrc.amd.com (Postfix, from userid 1000) id 31479FFD28; Mon, 4 Apr 2011 12:39:41 +0200 (CEST) From: Joerg Roedel To: Avi Kivity , Marcelo Tosatti CC: , Joerg Roedel Subject: [PATCH 12/15] KVM: SVM: Add intercept checks for remaining twobyte instructions Date: Mon, 4 Apr 2011 12:39:33 +0200 Message-ID: <1301913576-10360-13-git-send-email-joerg.roedel@amd.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1301913576-10360-1-git-send-email-joerg.roedel@amd.com> References: <1301913576-10360-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, 04 Apr 2011 10:41:37 +0000 (UTC) This patch adds intercepts checks for the remaining twobyte instructions to the KVM instruction emulator. Signed-off-by: Joerg Roedel --- arch/x86/include/asm/kvm_emulate.h | 2 ++ arch/x86/kvm/emulate.c | 25 ++++++++++++++++++------- arch/x86/kvm/svm.c | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 9b11edd..a9669d7 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -338,6 +338,8 @@ enum x86_intercept { x86_intercept_wbinvd, x86_intercept_monitor, x86_intercept_mwait, + x86_intercept_rdmsr, + x86_intercept_wrmsr, nr_x86_intercepts }; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8cf7fa3..bc49b2b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2336,12 +2336,9 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt) static int em_rdtsc(struct x86_emulate_ctxt *ctxt) { - unsigned cpl = ctxt->ops->cpl(ctxt->vcpu); struct decode_cache *c = &ctxt->decode; u64 tsc = 0; - if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) - return emulate_gp(ctxt, 0); ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc); c->regs[VCPU_REGS_RAX] = (u32)tsc; c->regs[VCPU_REGS_RDX] = tsc >> 32; @@ -2518,6 +2515,18 @@ static int check_rdtsc(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +static int check_rdpmc(struct x86_emulate_ctxt *ctxt) +{ + u64 cr4 = ctxt->ops->get_cr(4, ctxt->vcpu); + u64 rcx = kvm_register_read(ctxt->vcpu, VCPU_REGS_RCX); + + if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt->vcpu)) || + (rcx > 3)) + return emulate_gp(ctxt, 0); + + return X86EMUL_CONTINUE; +} + #define D(_y) { .flags = (_y) } #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i } #define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \ @@ -2747,8 +2756,10 @@ static struct opcode twobyte_table[256] = { N, N, N, N, N, N, N, N, N, N, N, N, /* 0x30 - 0x3F */ - D(ImplicitOps | Priv), II(ImplicitOps, em_rdtsc, rdtsc), - D(ImplicitOps | Priv), N, + DI(ImplicitOps | Priv, wrmsr), + IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), + DI(ImplicitOps | Priv, rdmsr), + DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific), N, N, N, N, N, N, N, N, N, N, @@ -2766,12 +2777,12 @@ static struct opcode twobyte_table[256] = { X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), /* 0xA0 - 0xA7 */ D(ImplicitOps | Stack), D(ImplicitOps | Stack), - N, D(DstMem | SrcReg | ModRM | BitOp), + DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), D(DstMem | SrcReg | Src2ImmByte | ModRM), D(DstMem | SrcReg | Src2CL | ModRM), N, N, /* 0xA8 - 0xAF */ D(ImplicitOps | Stack), D(ImplicitOps | Stack), - N, D(DstMem | SrcReg | ModRM | BitOp | Lock), + DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock), D(DstMem | SrcReg | Src2ImmByte | ModRM), D(DstMem | SrcReg | Src2CL | ModRM), D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1eb5504..9036289 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3868,6 +3868,9 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) update_cr0_intercept(svm); } +#define PRE_EX(exit) { .exit_code = (exit), \ + .stage = X86_ICPT_PRE_EXCEPT, \ + .valid = true } #define POST_EX(exit) { .exit_code = (exit), \ .stage = X86_ICPT_POST_EXCEPT, \ .valid = true } @@ -3906,8 +3909,18 @@ static struct __x86_intercept { [x86_intercept_rdtscp] = POST_EX(SVM_EXIT_RDTSCP), [x86_intercept_monitor] = POST_MEM(SVM_EXIT_MONITOR), [x86_intercept_mwait] = POST_EX(SVM_EXIT_MWAIT), + [x86_intercept_invlpg] = POST_EX(SVM_EXIT_INVLPG), + [x86_intercept_invd] = POST_EX(SVM_EXIT_INVD), + [x86_intercept_wbinvd] = POST_EX(SVM_EXIT_WBINVD), + [x86_intercept_wrmsr] = POST_EX(SVM_EXIT_MSR), + [x86_intercept_rdtsc] = POST_EX(SVM_EXIT_RDTSC), + [x86_intercept_rdmsr] = POST_EX(SVM_EXIT_MSR), + [x86_intercept_rdpmc] = POST_EX(SVM_EXIT_RDPMC), + [x86_intercept_cpuid] = PRE_EX(SVM_EXIT_CPUID), + [x86_intercept_rsm] = PRE_EX(SVM_EXIT_RSM), }; +#undef PRE_EX #undef POST_EX #undef POST_MEM @@ -3968,6 +3981,12 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, case SVM_EXIT_WRITE_DR0: icpt_info.exit_code += info->modrm_reg; break; + case SVM_EXIT_MSR: + if (info->intercept == x86_intercept_wrmsr) + vmcb->control.exit_info_1 = 1; + else + vmcb->control.exit_info_1 = 0; + break; default: break; }