Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752997AbdLKKRq (ORCPT ); Mon, 11 Dec 2017 05:17:46 -0500 Received: from mga07.intel.com ([134.134.136.100]:25477 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752781AbdLKKQE (ORCPT ); Mon, 11 Dec 2017 05:16:04 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,391,1508828400"; d="scan'208";a="1495975" From: Luwei Kang To: kvm@vger.kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, pbonzini@redhat.com, rkrcmar@redhat.com, linux-kernel@vger.kernel.org, joro@8bytes.org, Luwei Kang Subject: [PATCH V4 07/11] KVM: x86: Add a function to disable/enable Intel PT MSRs intercept Date: Mon, 11 Dec 2017 04:30:53 +0800 Message-Id: <1512937857-10477-8-git-send-email-luwei.kang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512937857-10477-1-git-send-email-luwei.kang@intel.com> References: <1512937857-10477-1-git-send-email-luwei.kang@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3087 Lines: 97 Intel Processor Trace MSRs(except IA32_RTIT_CTL) would be passthrough to guest when Intel PT is enable in guest. So we need this function to disable/enable intercept these MSRs. Signed-off-by: Luwei Kang --- arch/x86/kvm/vmx.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index de9e958..e2de089 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4978,6 +4978,41 @@ static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, } } +static void __vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, + u32 msr, int type) +{ + int f = sizeof(unsigned long); + + if (!cpu_has_vmx_msr_bitmap()) + return; + + /* + * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals + * have the write-low and read-high bitmap offsets the wrong way round. + * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. + */ + if (msr <= 0x1fff) { + if (type & MSR_TYPE_R) + /* read-low */ + __set_bit(msr, msr_bitmap + 0x000 / f); + + if (type & MSR_TYPE_W) + /* write-low */ + __set_bit(msr, msr_bitmap + 0x800 / f); + + } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { + msr &= 0x1fff; + if (type & MSR_TYPE_R) + /* read-high */ + __set_bit(msr, msr_bitmap + 0x400 / f); + + if (type & MSR_TYPE_W) + /* write-high */ + __set_bit(msr, msr_bitmap + 0xc00 / f); + + } +} + /* * If a msr is allowed by L0, we should check whether it is allowed by L1. * The corresponding bit will be cleared unless both of L0 and L1 allow it. @@ -5033,6 +5068,39 @@ static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only) msr, MSR_TYPE_R | MSR_TYPE_W); } +static void vmx_enable_intercept_for_msr(u32 msr, bool longmode_only) +{ + if (!longmode_only) + __vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy, + msr, MSR_TYPE_R | MSR_TYPE_W); + __vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode, + msr, MSR_TYPE_R | MSR_TYPE_W); +} + +static void pt_disable_intercept_for_msr(bool flag) +{ + unsigned int i; + unsigned int addr_num = kvm_get_pt_addr_cnt(); + + if (flag) { + vmx_disable_intercept_for_msr(MSR_IA32_RTIT_STATUS, false); + vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE, false); + vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK, false); + vmx_disable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH, false); + for (i = 0; i < addr_num; i++) + vmx_disable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i, + false); + } else { + vmx_enable_intercept_for_msr(MSR_IA32_RTIT_STATUS, false); + vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE, false); + vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK, false); + vmx_enable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH, false); + for (i = 0; i < addr_num; i++) + vmx_enable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i, + false); + } +} + static void vmx_disable_intercept_msr_x2apic(u32 msr, int type, bool apicv_active) { if (apicv_active) { -- 1.8.3.1