Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1151924ybk; Thu, 14 May 2020 01:35:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxley2v+PujVSaPPAEFkhmRjp7pEaKA06WE9fAGbRXyR5hVNq2mC3lihkmOBKcAOC9aC19d X-Received: by 2002:a05:6402:1b0e:: with SMTP id by14mr2834657edb.329.1589445328567; Thu, 14 May 2020 01:35:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589445328; cv=none; d=google.com; s=arc-20160816; b=uqTcyXT5hOPMETDQZfqbdSvuVMTdJ1nnSGpZs1bSXdhG3u6cZ+4wTFJi07qObrt5GU vA/12asK9sxaxnRY5IEvKPSRYgNdHRe7UGJWKle3Sm+rCuejLx8/hoIR5Kx2n0XQTsrO 5NBeNl7dvYYipJhOmEfeo0ab3xwKxifz9/iZYz8NJMNX/pgtx8EARKbOxdMp29I/xahL jS4NsH1DRGyq7zS9nVL4YW9swKPEzeijEZQ2bKWIB4sf6+p8pBR3p2p8xvyVNuRVEylx B5GYiT96VwrfIBhEkNj1CEkhaqBGsPRbnhib59r0fjesHpudGDyaU50dz3vX9WFfAxC3 BIGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=CwFUjv0594dWQ1RSycKveaGFLwVUEQNpIO0ye2c0MBM=; b=iQLT030cCikUNu52YAo5GecdG6WppYAOJBr9yXtHjJJB8r4ZZZFW8H+JYo6HXn6TvQ 2FVIV/MGH2T+or7njvFGNwRf5E3KqOZqKM3D1qeMoKZZOF1f3/z/8633LEJLkx9fv2GC CZUwduHpw1hA4f8kTd22z6WFttbXu/7Ac3tapE8cnPAYWUCi5URhsUGrUu2v61yVsKh+ yPehQLwjrFJg4tCy8fDGa+7tSFP55IP0TL4USEmGfxfaVpzLx4477Q57OVho6t3Pfp3g dx6grNXKm72AAe71JX7Rav4kY5pelVf3hlOshQn8Wr9Neh0FbanlTf75K8a6rxWWs/Qf GzjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u23si1142599edx.101.2020.05.14.01.35.06; Thu, 14 May 2020 01:35:28 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726010AbgENIbs (ORCPT + 99 others); Thu, 14 May 2020 04:31:48 -0400 Received: from mga18.intel.com ([134.134.136.126]:12089 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727050AbgENIbp (ORCPT ); Thu, 14 May 2020 04:31:45 -0400 IronPort-SDR: CybOFdpDg/q3KVVdWkAs9JoMpKoUNfTvip2jy772PjVK4r6l3bwTkIWBUwfmbmHpYPOeKIq7+E Nv7VJF9XY3iw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 01:31:45 -0700 IronPort-SDR: 1+ordkhGBNpAcHCPzkHvlYddkq04iMxDBIFq59y2JBiAQHfKAWxnDoFRnMplx05jUTosTgHiev PSZK1Fh2Lr6A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,390,1583222400"; d="scan'208";a="341540032" Received: from sqa-gate.sh.intel.com (HELO clx-ap-likexu.tsp.org) ([10.239.48.212]) by orsmga001.jf.intel.com with ESMTP; 14 May 2020 01:31:42 -0700 From: Like Xu To: Peter Zijlstra , Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Thomas Gleixner , ak@linux.intel.com, wei.w.wang@intel.com, Like Xu Subject: [PATCH v11 10/11] KVM: x86/pmu: Check guest LBR availability in case host reclaims them Date: Thu, 14 May 2020 16:30:53 +0800 Message-Id: <20200514083054.62538-11-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200514083054.62538-1-like.xu@linux.intel.com> References: <20200514083054.62538-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When the guest LBR event exists and the LBR stack is available (defined as 'event->oncpu != -1'), the LBR records msrs access would not be intercepted but passthrough to the vcpu before vm-entry. This kind of availability check is always performed before vm-entry, but as late as possible to avoid reclaiming resources from any higher priority event. A negative check result would bring the registers interception back, and it also prevents real registers accesses and potential data leakage. The KVM emits a pr_warn() on the host when the guest LBR is unavailable. The administer is supposed to reminder users that the guest result may be inaccurate if someone is using LBR to record hypervisor on the host side. Suggested-by: Wei Wang Signed-off-by: Like Xu --- arch/x86/kvm/pmu.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 38 ++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 4 +++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 78f0cfe1622f..bb3f3ef3386e 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -42,6 +42,7 @@ struct kvm_pmu_ops { void (*reset)(struct kvm_vcpu *vcpu); void (*deliver_pmi)(struct kvm_vcpu *vcpu); void (*lbr_cleanup)(struct kvm_vcpu *vcpu); + void (*availability_check)(struct kvm_vcpu *vcpu); }; static inline bool event_is_oncpu(struct perf_event *event) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index ea4faae56473..db185dca903d 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -646,6 +646,43 @@ static void intel_pmu_lbr_cleanup(struct kvm_vcpu *vcpu) intel_pmu_free_lbr_event(vcpu); } +static bool intel_pmu_lbr_is_availabile(struct kvm_vcpu *vcpu) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + + if (!pmu->lbr_event) + return false; + + if (event_is_oncpu(pmu->lbr_event)) { + intel_pmu_intercept_lbr_msrs(vcpu, false); + } else { + intel_pmu_intercept_lbr_msrs(vcpu, true); + return false; + } + + return true; +} + +/* + * Higher priority host perf events (e.g. cpu pinned) could reclaim the + * pmu resources (e.g. LBR) that were assigned to the guest. This is + * usually done via ipi calls (more details in perf_install_in_context). + * + * Before entering the non-root mode (with irq disabled here), double + * confirm that the pmu features enabled to the guest are not reclaimed + * by higher priority host events. Otherwise, disallow vcpu's access to + * the reclaimed features. + */ +static void intel_pmu_availability_check(struct kvm_vcpu *vcpu) +{ + lockdep_assert_irqs_disabled(); + + if (lbr_is_enabled(vcpu) && !intel_pmu_lbr_is_availabile(vcpu) && + (vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR)) + pr_warn_ratelimited("kvm: vcpu-%d: LBR is temporarily unavailable.\n", + vcpu->vcpu_id); +} + struct kvm_pmu_ops intel_pmu_ops = { .find_arch_event = intel_find_arch_event, .find_fixed_event = intel_find_fixed_event, @@ -662,4 +699,5 @@ struct kvm_pmu_ops intel_pmu_ops = { .reset = intel_pmu_reset, .deliver_pmi = intel_pmu_deliver_pmi, .lbr_cleanup = intel_pmu_lbr_cleanup, + .availability_check = intel_pmu_availability_check, }; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9969d663826a..80d036c5f64a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6696,8 +6696,10 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) pt_guest_enter(vmx); - if (vcpu_to_pmu(vcpu)->version) + if (vcpu_to_pmu(vcpu)->version) { atomic_switch_perf_msrs(vmx); + kvm_x86_ops.pmu_ops->availability_check(vcpu); + } atomic_switch_umwait_control_msr(vmx); -- 2.21.3