Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp828443ybc; Tue, 19 Nov 2019 09:54:58 -0800 (PST) X-Google-Smtp-Source: APXvYqzt3CrZTVFqhxEdKjLUpCdt9ClrfhgFBnucDsC8TIyZiezjv5RiZxkB6UhjCZ/qE95dZaJp X-Received: by 2002:a17:906:ccc6:: with SMTP id ot6mr22135708ejb.137.1574186098022; Tue, 19 Nov 2019 09:54:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574186098; cv=none; d=google.com; s=arc-20160816; b=aXOVrDhu6JAZKzJbDbEpz+3s/cMVP29nzwnV2HaNZgzSNpjyedmAzAAqcibdudvL4F jN/QqaYfGZaC5RGaHWhWBe4Aju96frJEDGUav+duJemMyPxCu28/TTg21GygyJPoliE5 nh2BE+qg69Ekf0bDtaBQ9PKgAX7BBFndtd/6jRFfdsLOtTjs4hKF6hdz8f+xJ760libD cbkKgGES+eUxn8dTTYPHmSqCEBgpfOPBthF2SnxTDuegqmnKgT7YFq8Vy1k4OJ8pfImG N8W39o8xjWclJKZ//zSshYuxhWwfa3Z57ZibfCnQ465lB4jn6KzKwj63okmg8cjxC0UM AOAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=syCPwlDsuLEWHYg/6o4l/xx2eD5MyMXVqfSPNBQN/fA=; b=ZkWEn3S4wLU3azzYoDr1Qk7RqZsn6j4MkgkwhlckK2bgMLTnrQd9CcotAM2/cKGXcI NyHoG2TDNtKO3Ss3GXtptoq7qW+ta8MJZS65sE9bIAK3WmXe3hNmQzL9sLjVlJVbmZj7 xHmwUPoXCx3kPNLNzaUhifNM5Izey1A3/dfneOmHzrSi/L0WHGQt5K7yOC7SktfSH2+V DOZmtTMdgNtrbeGE4rbtNiyx36L5PUkHeKwic33SPv8o813YbOmmbN6puKGc6LKq8quU 6X0hds8H0yuW5vbA4EkV9lD7i0jM1IuzSTa3iSeICkE5t0pufVjuqJrEI5EngJBZ4z6R LQHw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id f19si15110060eda.435.2019.11.19.09.54.34; Tue, 19 Nov 2019 09:54:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S1727527AbfKSRwZ (ORCPT + 99 others); Tue, 19 Nov 2019 12:52:25 -0500 Received: from mga14.intel.com ([192.55.52.115]:17665 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727289AbfKSRwA (ORCPT ); Tue, 19 Nov 2019 12:52:00 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Nov 2019 09:51:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,218,1571727600"; d="scan'208";a="209488269" Received: from jacob-builder.jf.intel.com ([10.7.199.155]) by orsmga006.jf.intel.com with ESMTP; 19 Nov 2019 09:51:58 -0800 From: Jacob Pan To: iommu@lists.linux-foundation.org, LKML , Joerg Roedel , "Lu Baolu" , David Woodhouse Cc: "Tian, Kevin" , Raj Ashok , "Yi Liu" , Eric Auger , "Mehta, Sohil" , Jacob Pan Subject: [PATCH v3 1/8] iommu/vt-d: Fix CPU and IOMMU SVM feature matching checks Date: Tue, 19 Nov 2019 09:56:25 -0800 Message-Id: <1574186193-30457-2-git-send-email-jacob.jun.pan@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1574186193-30457-1-git-send-email-jacob.jun.pan@linux.intel.com> References: <1574186193-30457-1-git-send-email-jacob.jun.pan@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Shared Virtual Memory(SVM) is based on a collective set of hardware features detected at runtime. There are requirements for matching CPU and IOMMU capabilities. The current code checks CPU and IOMMU feature set for SVM support but the result is never stored nor used. Therefore, SVM can still be used even when these checks failed. The consequences can be: 1. CPU uses 5-level paging mode for virtual address of 57 bits, but IOMMU can only support 4-level paging mode with 48 bits address for DMA. 2. 1GB page size is used by CPU but IOMMU does not support it. VT-d unrecoverable faults may be generated. The best solution to fix these problems is to prevent them in the first place. This patch consolidates code for checking PASID, CPU vs. IOMMU paging mode compatibility, as well as provides specific error messages for each failed checks. On sane hardware configurations, these error message shall never appear in kernel log. Signed-off-by: Jacob Pan Acked-by: Lu Baolu --- drivers/iommu/intel-iommu.c | 10 ++-------- drivers/iommu/intel-svm.c | 40 +++++++++++++++++++++++++++------------- include/linux/intel-iommu.h | 5 ++++- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 3f974919d3bd..d598168e410d 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3289,10 +3289,7 @@ static int __init init_dmars(void) if (!ecap_pass_through(iommu->ecap)) hw_pass_through = 0; -#ifdef CONFIG_INTEL_IOMMU_SVM - if (pasid_supported(iommu)) - intel_svm_init(iommu); -#endif + intel_svm_check(iommu); } /* @@ -4471,10 +4468,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru) if (ret) goto out; -#ifdef CONFIG_INTEL_IOMMU_SVM - if (pasid_supported(iommu)) - intel_svm_init(iommu); -#endif + intel_svm_check(iommu); if (dmaru->ignored) { /* diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 9b159132405d..716c543488f6 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -23,19 +23,6 @@ static irqreturn_t prq_event_thread(int irq, void *d); -int intel_svm_init(struct intel_iommu *iommu) -{ - if (cpu_feature_enabled(X86_FEATURE_GBPAGES) && - !cap_fl1gp_support(iommu->cap)) - return -EINVAL; - - if (cpu_feature_enabled(X86_FEATURE_LA57) && - !cap_5lp_support(iommu->cap)) - return -EINVAL; - - return 0; -} - #define PRQ_ORDER 0 int intel_svm_enable_prq(struct intel_iommu *iommu) @@ -99,6 +86,33 @@ int intel_svm_finish_prq(struct intel_iommu *iommu) return 0; } +static inline bool intel_svm_capable(struct intel_iommu *iommu) +{ + return iommu->flags & VTD_FLAG_SVM_CAPABLE; +} + +void intel_svm_check(struct intel_iommu *iommu) +{ + if (!pasid_supported(iommu)) + return; + + if (cpu_feature_enabled(X86_FEATURE_GBPAGES) && + !cap_fl1gp_support(iommu->cap)) { + pr_err("%s SVM disabled, incompatible 1GB page capability\n", + iommu->name); + return; + } + + if (cpu_feature_enabled(X86_FEATURE_LA57) && + !cap_5lp_support(iommu->cap)) { + pr_err("%s SVM disabled, incompatible paging mode\n", + iommu->name); + return; + } + + iommu->flags |= VTD_FLAG_SVM_CAPABLE; +} + static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev, unsigned long address, unsigned long pages, int ih) { diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index ed11ef594378..7dcfa1c4a844 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -433,6 +433,7 @@ enum { #define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0) #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1) +#define VTD_FLAG_SVM_CAPABLE (1 << 2) extern int intel_iommu_sm; @@ -656,7 +657,7 @@ void iommu_flush_write_buffer(struct intel_iommu *iommu); int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev); #ifdef CONFIG_INTEL_IOMMU_SVM -int intel_svm_init(struct intel_iommu *iommu); +extern void intel_svm_check(struct intel_iommu *iommu); extern int intel_svm_enable_prq(struct intel_iommu *iommu); extern int intel_svm_finish_prq(struct intel_iommu *iommu); @@ -684,6 +685,8 @@ struct intel_svm { }; extern struct intel_iommu *intel_svm_device_to_iommu(struct device *dev); +#else +static inline void intel_svm_check(struct intel_iommu *iommu) {} #endif #ifdef CONFIG_INTEL_IOMMU_DEBUGFS -- 2.7.4