From patchwork Thu Nov 28 02:25:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 11265285 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9A4713A4 for ; Thu, 28 Nov 2019 02:30:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2AB62166E for ; Thu, 28 Nov 2019 02:30:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729248AbfK1CaS (ORCPT ); Wed, 27 Nov 2019 21:30:18 -0500 Received: from mga18.intel.com ([134.134.136.126]:17935 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728387AbfK1CaP (ORCPT ); Wed, 27 Nov 2019 21:30:15 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2019 18:30:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,251,1571727600"; d="scan'208";a="221176239" Received: from allen-box.sh.intel.com ([10.239.159.136]) by orsmga002.jf.intel.com with ESMTP; 27 Nov 2019 18:30:12 -0800 From: Lu Baolu To: Joerg Roedel , David Woodhouse , Alex Williamson Cc: ashok.raj@intel.com, sanjay.k.kumar@intel.com, jacob.jun.pan@linux.intel.com, kevin.tian@intel.com, yi.l.liu@intel.com, yi.y.sun@intel.com, Peter Xu , iommu@lists.linux-foundation.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu , Yi Sun Subject: [PATCH v2 7/8] iommu/vt-d: Identify domains using first level page table Date: Thu, 28 Nov 2019 10:25:49 +0800 Message-Id: <20191128022550.9832-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191128022550.9832-1-baolu.lu@linux.intel.com> References: <20191128022550.9832-1-baolu.lu@linux.intel.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This checks whether a domain should use first level page table for map/unmap. And if so, we should attach the domain to the device in first level translation mode. Cc: Ashok Raj Cc: Jacob Pan Cc: Kevin Tian Cc: Liu Yi L Cc: Yi Sun Cc: Sanjay Kumar Signed-off-by: Lu Baolu --- drivers/iommu/intel-iommu.c | 63 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 695a7a5fbe8e..68b2f98ecd65 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -417,6 +417,11 @@ const struct iommu_ops intel_iommu_ops; static const struct pgtable_ops first_lvl_pgtable_ops; static const struct pgtable_ops second_lvl_pgtable_ops; +static inline bool domain_pgtable_first_lvl(struct dmar_domain *domain) +{ + return domain->ops == &first_lvl_pgtable_ops; +} + static bool translation_pre_enabled(struct intel_iommu *iommu) { return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED); @@ -1702,6 +1707,44 @@ static bool first_lvl_5lp_support(void) return first_level_5lp_supported; } +/* + * Check and return whether first level is used by default for + * DMA translation. + */ +static bool first_level_by_default(void) +{ + struct dmar_drhd_unit *drhd; + struct intel_iommu *iommu; + static int first_level_support = -1; + + if (likely(first_level_support != -1)) + return first_level_support; + + first_level_support = 1; + + rcu_read_lock(); + for_each_active_iommu(iommu, drhd) { + if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) { + first_level_support = 0; + break; + } +#ifdef CONFIG_X86 + /* + * Currently we don't support paging mode missmatching. + * Could be turned on later if there is a case. + */ + if (cpu_feature_enabled(X86_FEATURE_LA57) && + !cap_5lp_support(iommu->cap)) { + first_level_support = 0; + break; + } +#endif /* #ifdef CONFIG_X86 */ + } + rcu_read_unlock(); + + return first_level_support; +} + static struct dmar_domain *alloc_domain(int flags) { struct dmar_domain *domain; @@ -1714,7 +1757,10 @@ static struct dmar_domain *alloc_domain(int flags) domain->nid = NUMA_NO_NODE; domain->flags = flags; domain->has_iotlb_device = false; - domain->ops = &second_lvl_pgtable_ops; + if (first_level_by_default()) + domain->ops = &first_lvl_pgtable_ops; + else + domain->ops = &second_lvl_pgtable_ops; domain->first_lvl_5lp = first_lvl_5lp_support(); spin_lock_init(&domain->page_table_lock); INIT_LIST_HEAD(&domain->devices); @@ -2710,6 +2756,11 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu, if (hw_pass_through && domain_type_is_si(domain)) ret = intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); + else if (domain_pgtable_first_lvl(domain)) + ret = intel_pasid_setup_first_level(iommu, dev, + domain->pgd, PASID_RID2PASID, + domain->iommu_did[iommu->seq_id], + PASID_FLAG_SUPERVISOR_MODE); else ret = intel_pasid_setup_second_level(iommu, domain, dev, PASID_RID2PASID); @@ -5597,8 +5648,14 @@ static int aux_domain_add_dev(struct dmar_domain *domain, goto attach_failed; /* Setup the PASID entry for mediated devices: */ - ret = intel_pasid_setup_second_level(iommu, domain, dev, - domain->default_pasid); + if (domain_pgtable_first_lvl(domain)) + ret = intel_pasid_setup_first_level(iommu, dev, + domain->pgd, domain->default_pasid, + domain->iommu_did[iommu->seq_id], + PASID_FLAG_SUPERVISOR_MODE); + else + ret = intel_pasid_setup_second_level(iommu, domain, dev, + domain->default_pasid); if (ret) goto table_failed; spin_unlock(&iommu->lock);