From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AB40C28EBD for ; Sun, 9 Jun 2019 13:42:58 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5AA9120868 for ; Sun, 9 Jun 2019 13:42:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5AA9120868 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=iommu-bounces@lists.linux-foundation.org Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8F611CC7; Sun, 9 Jun 2019 13:41:27 +0000 (UTC) Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 9413EC51 for ; Sun, 9 Jun 2019 13:41:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1769D76F for ; Sun, 9 Jun 2019 13:41:21 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jun 2019 06:41:18 -0700 X-ExtLoop1: 1 Received: from jacob-builder.jf.intel.com ([10.7.199.155]) by orsmga003.jf.intel.com with ESMTP; 09 Jun 2019 06:41:18 -0700 From: Jacob Pan To: iommu@lists.linux-foundation.org, LKML , Joerg Roedel , David Woodhouse , Eric Auger , Alex Williamson , Jean-Philippe Brucker Subject: [PATCH v4 14/22] iommu/vt-d: Add custom allocator for IOASID Date: Sun, 9 Jun 2019 06:44:14 -0700 Message-Id: <1560087862-57608-15-git-send-email-jacob.jun.pan@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1560087862-57608-1-git-send-email-jacob.jun.pan@linux.intel.com> References: <1560087862-57608-1-git-send-email-jacob.jun.pan@linux.intel.com> Cc: "Tian, Kevin" , Raj Ashok , Liu@mail.linuxfoundation.org, Andriy Shevchenko X-BeenThere: iommu@lists.linux-foundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Development issues for Linux IOMMU support List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: iommu-bounces@lists.linux-foundation.org Errors-To: iommu-bounces@lists.linux-foundation.org When VT-d driver runs in the guest, PASID allocation must be performed via virtual command interface. This patch registers a custom IOASID allocator which takes precedence over the default XArray based allocator. The resulting IOASID allocation will always come from the host. This ensures that PASID namespace is system- wide. Signed-off-by: Lu Baolu Signed-off-by: Liu, Yi L Signed-off-by: Jacob Pan --- drivers/iommu/Kconfig | 1 + drivers/iommu/intel-iommu.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/intel-iommu.h | 2 ++ 3 files changed, 63 insertions(+) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index c40c4b5..5d1bc2a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -213,6 +213,7 @@ config INTEL_IOMMU_SVM bool "Support for Shared Virtual Memory with Intel IOMMU" depends on INTEL_IOMMU && X86 select PCI_PASID + select IOASID select MMU_NOTIFIER select IOASID help diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 09b8ff0..5b84994 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1711,6 +1711,8 @@ static void free_dmar_iommu(struct intel_iommu *iommu) if (ecap_prs(iommu->ecap)) intel_svm_finish_prq(iommu); } + ioasid_unregister_allocator(&iommu->pasid_allocator); + #endif } @@ -4820,6 +4822,46 @@ static int __init platform_optin_force_iommu(void) return 1; } +#ifdef CONFIG_INTEL_IOMMU_SVM +static ioasid_t intel_ioasid_alloc(ioasid_t min, ioasid_t max, void *data) +{ + struct intel_iommu *iommu = data; + ioasid_t ioasid; + + /* + * VT-d virtual command interface always uses the full 20 bit + * PASID range. Host can partition guest PASID range based on + * policies but it is out of guest's control. + */ + if (min < PASID_MIN || max > PASID_MAX) + return -EINVAL; + + if (vcmd_alloc_pasid(iommu, &ioasid)) + return INVALID_IOASID; + + return ioasid; +} + +static void intel_ioasid_free(ioasid_t ioasid, void *data) +{ + struct iommu_pasid_alloc_info *svm; + struct intel_iommu *iommu = data; + + if (!iommu) + return; + /* + * Sanity check the ioasid owner is done at upper layer, e.g. VFIO + * We can only free the PASID when all the devices are unbond. + */ + svm = ioasid_find(NULL, ioasid, NULL); + if (!svm) { + pr_warn("Freeing unbond IOASID %d\n", ioasid); + return; + } + vcmd_free_pasid(iommu, ioasid); +} +#endif + int __init intel_iommu_init(void) { int ret = -ENODEV; @@ -4924,6 +4966,24 @@ int __init intel_iommu_init(void) "%s", iommu->name); iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); iommu_device_register(&iommu->iommu); +#ifdef CONFIG_INTEL_IOMMU_SVM + if (cap_caching_mode(iommu->cap) && sm_supported(iommu)) { + /* + * Register a custom ASID allocator if we are running + * in a guest, the purpose is to have a system wide PASID + * namespace among all PASID users. + * There can be multiple vIOMMUs in each guest but only + * one allocator is active. All vIOMMU allocators will + * eventually be calling the same host allocator. + */ + iommu->pasid_allocator.alloc = intel_ioasid_alloc; + iommu->pasid_allocator.free = intel_ioasid_free; + iommu->pasid_allocator.pdata = (void *)iommu; + ret = ioasid_register_allocator(&iommu->pasid_allocator); + if (ret) + pr_warn("Custom PASID allocator registeration failed\n"); + } +#endif } bus_set_iommu(&pci_bus_type, &intel_iommu_ops); diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index bff907b..8605c74 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -549,6 +550,7 @@ struct intel_iommu { #ifdef CONFIG_INTEL_IOMMU_SVM struct page_req_dsc *prq; unsigned char prq_name[16]; /* Name for PRQ interrupt */ + struct ioasid_allocator_ops pasid_allocator; /* Custom allocator for PASIDs */ #endif struct q_inval *qi; /* Queued invalidation info */ u32 *iommu_state; /* Store iommu states between suspend and resume.*/ -- 2.7.4 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu