From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06C7BC433EF for ; Tue, 14 Jun 2022 03:00:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355317AbiFNDA3 (ORCPT ); Mon, 13 Jun 2022 23:00:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355529AbiFNC6x (ORCPT ); Mon, 13 Jun 2022 22:58:53 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21CFCE0C for ; Mon, 13 Jun 2022 19:55:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175338; x=1686711338; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0jGkwfXQqJ7dzQuNigUUeqPRhHr5dHCQjCVxl5UQzFw=; b=kcap8FPU9Bb27nCIAypOhzk4M6HVfX4CEkE3oqeVu2i5D6aPkafW+nNh PYWeqjVisym8ZSLwrVhlBnW5w3p8CsMyq3fagUWf9rGHbgFEnLe6A3ym3 roDEvsNtMM3RLNNtnJY9PqrOGuwmlpOqoQTiHdar3P7iCl2Fq4ksA1h+S a4i0n53sOgCAFgWBQRsCrIvUGgO5YDBeK8aCQOQRTfje9DfwSYHI9JmyH 0KqGyaV7+i5Tmwtq7AWO8kXs/4mNzTL0Qx4jrl4gNJUcn4D65d9SNH72q df8w7JonruorV5pn7hQAnlX62bjyuqAESc4pXPEA/U4f4T0ihCN8t1KLC A==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930247" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930247" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166412" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:35 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 01/12] iommu/vt-d: debugfs: Remove device_domain_lock usage Date: Tue, 14 Jun 2022 10:51:26 +0800 Message-Id: <20220614025137.1632762-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The domain_translation_struct debugfs node is used to dump the DMAR page tables for the PCI devices. It potentially races with setting domains to devices. The existing code uses a global spinlock device_domain_lock to avoid the races, but this is problematical as this lock is only used to protect the device tracking lists of each domain. This replaces device_domain_lock with group->mutex to protect page tables from setting a new domain. This also makes device_domain_lock static as it is now only used inside the file. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.h | 1 - drivers/iommu/intel/debugfs.c | 49 +++++++++++++++++++++++++---------- drivers/iommu/intel/iommu.c | 2 +- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index a22adfbdf870..8a6d64d726c0 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -480,7 +480,6 @@ enum { #define VTD_FLAG_SVM_CAPABLE (1 << 2) =20 extern int intel_iommu_sm; -extern spinlock_t device_domain_lock; =20 #define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap)) #define pasid_supported(iommu) (sm_supported(iommu) && \ diff --git a/drivers/iommu/intel/debugfs.c b/drivers/iommu/intel/debugfs.c index d927ef10641b..5ebfe32265d5 100644 --- a/drivers/iommu/intel/debugfs.c +++ b/drivers/iommu/intel/debugfs.c @@ -342,15 +342,23 @@ static void pgtable_walk_level(struct seq_file *m, st= ruct dma_pte *pde, } } =20 -static int show_device_domain_translation(struct device *dev, void *data) +struct show_domain_opaque { + struct device *dev; + struct seq_file *m; +}; + +static int __show_device_domain_translation(struct device *dev, void *data) { - struct device_domain_info *info =3D dev_iommu_priv_get(dev); - struct dmar_domain *domain =3D info->domain; - struct seq_file *m =3D data; + struct show_domain_opaque *opaque =3D data; + struct device_domain_info *info; + struct seq_file *m =3D opaque->m; + struct dmar_domain *domain; u64 path[6] =3D { 0 }; =20 - if (!domain) + if (dev !=3D opaque->dev) return 0; + info =3D dev_iommu_priv_get(dev); + domain =3D info->domain; =20 seq_printf(m, "Device %s @0x%llx\n", dev_name(dev), (u64)virt_to_phys(domain->pgd)); @@ -359,20 +367,33 @@ static int show_device_domain_translation(struct devi= ce *dev, void *data) pgtable_walk_level(m, domain->pgd, domain->agaw + 2, 0, path); seq_putc(m, '\n'); =20 - return 0; + return 1; } =20 -static int domain_translation_struct_show(struct seq_file *m, void *unused) +static int show_device_domain_translation(struct device *dev, void *data) { - unsigned long flags; - int ret; + struct show_domain_opaque opaque =3D {dev, data}; + struct iommu_group *group; =20 - spin_lock_irqsave(&device_domain_lock, flags); - ret =3D bus_for_each_dev(&pci_bus_type, NULL, m, - show_device_domain_translation); - spin_unlock_irqrestore(&device_domain_lock, flags); + group =3D iommu_group_get(dev); + if (group) { + /* + * The group->mutex is held across the callback, which will + * block calls to iommu_attach/detach_group/device. Hence, + * the domain of the device will not change during traversal. + */ + iommu_group_for_each_dev(group, &opaque, + __show_device_domain_translation); + iommu_group_put(group); + } =20 - return ret; + return 0; +} + +static int domain_translation_struct_show(struct seq_file *m, void *unused) +{ + return bus_for_each_dev(&pci_bus_type, NULL, m, + show_device_domain_translation); } DEFINE_SHOW_ATTRIBUTE(domain_translation_struct); =20 diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 19024dc52735..a39d72a9d1cf 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -314,7 +314,7 @@ static int iommu_skip_te_disable; #define IDENTMAP_GFX 2 #define IDENTMAP_AZALIA 4 =20 -DEFINE_SPINLOCK(device_domain_lock); +static DEFINE_SPINLOCK(device_domain_lock); static LIST_HEAD(device_domain_list); =20 /* --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5253C43334 for ; Tue, 14 Jun 2022 03:00:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355346AbiFNDAp (ORCPT ); Mon, 13 Jun 2022 23:00:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355530AbiFNC6x (ORCPT ); Mon, 13 Jun 2022 22:58:53 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3359110AB for ; Mon, 13 Jun 2022 19:55:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175341; x=1686711341; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XkrY1IFtBFukO48gqiQ0AuYcbFkThuu4cQHVHVcOWwQ=; b=dC6NEzesiMnGlNzJiQhg71SBwi2JFXjgiyj47+OR3oVyGCBBXmhtkTYE bfCralLiAt/UfZexTChIAJ58H9+eJyG5potwGQoKeh59xDqDsPVfh3a09 kY7JwgEF5T9BkxEtB0yQYcVu+n/DAbwsgenqLcM6yCgJWaYsQAds9hN7h SlNlb8HQKmcAP8NMGu3BQA9khWhjr0kNWYSe97IQ8anpFJMZSDotTd5QB VAgYGzKdRMzP7/JvMGd/YJZTioIgvWKn2Ph3JcZo4VUEEtGVCKaVglH+5 qO8YJHwhG9O/AZylJLtk+/zhd7KSEwAWfgQUQ/agY7CNeNVzuvNIy/jLi w==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930291" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930291" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166431" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:38 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 02/12] iommu/vt-d: Remove for_each_device_domain() Date: Tue, 14 Jun 2022 10:51:27 +0800 Message-Id: <20220614025137.1632762-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The per-device device_domain_info data could be retrieved from the device itself. There's no need to search a global list. Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.h | 2 -- drivers/iommu/intel/iommu.c | 25 ---------------------- drivers/iommu/intel/pasid.c | 41 +++++++++++-------------------------- 3 files changed, 12 insertions(+), 56 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 8a6d64d726c0..2f4a5b9509c0 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -727,8 +727,6 @@ extern int dmar_ir_support(void); void *alloc_pgtable_page(int node); void free_pgtable_page(void *vaddr); struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); -int for_each_device_domain(int (*fn)(struct device_domain_info *info, - void *data), void *data); void iommu_flush_write_buffer(struct intel_iommu *iommu); int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev= ); struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn= ); diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index a39d72a9d1cf..ff6018f746e0 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -316,31 +316,6 @@ static int iommu_skip_te_disable; =20 static DEFINE_SPINLOCK(device_domain_lock); static LIST_HEAD(device_domain_list); - -/* - * Iterate over elements in device_domain_list and call the specified - * callback @fn against each element. - */ -int for_each_device_domain(int (*fn)(struct device_domain_info *info, - void *data), void *data) -{ - int ret =3D 0; - unsigned long flags; - struct device_domain_info *info; - - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry(info, &device_domain_list, global) { - ret =3D fn(info, data); - if (ret) { - spin_unlock_irqrestore(&device_domain_lock, flags); - return ret; - } - } - spin_unlock_irqrestore(&device_domain_lock, flags); - - return 0; -} - const struct iommu_ops intel_iommu_ops; =20 static bool translation_pre_enabled(struct intel_iommu *iommu) diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index b2ac5869286f..641a4a6eb61e 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -103,36 +103,19 @@ device_detach_pasid_table(struct device_domain_info *= info, } =20 struct pasid_table_opaque { - struct pasid_table **pasid_table; - int segment; - int bus; - int devfn; + struct pasid_table *pasid_table; }; =20 -static int search_pasid_table(struct device_domain_info *info, void *opaqu= e) -{ - struct pasid_table_opaque *data =3D opaque; - - if (info->iommu->segment =3D=3D data->segment && - info->bus =3D=3D data->bus && - info->devfn =3D=3D data->devfn && - info->pasid_table) { - *data->pasid_table =3D info->pasid_table; - return 1; - } - - return 0; -} - static int get_alias_pasid_table(struct pci_dev *pdev, u16 alias, void *op= aque) { struct pasid_table_opaque *data =3D opaque; + struct device_domain_info *info; =20 - data->segment =3D pci_domain_nr(pdev->bus); - data->bus =3D PCI_BUS_NUM(alias); - data->devfn =3D alias & 0xff; + info =3D dev_iommu_priv_get(&pdev->dev); + if (info && info->pasid_table) + data->pasid_table =3D info->pasid_table; =20 - return for_each_device_domain(&search_pasid_table, data); + return data->pasid_table !=3D NULL; } =20 /* @@ -141,12 +124,12 @@ static int get_alias_pasid_table(struct pci_dev *pdev= , u16 alias, void *opaque) */ int intel_pasid_alloc_table(struct device *dev) { + struct pasid_table_opaque data =3D { NULL }; struct device_domain_info *info; struct pasid_table *pasid_table; - struct pasid_table_opaque data; struct page *pages; u32 max_pasid =3D 0; - int ret, order; + int order; int size; =20 might_sleep(); @@ -155,11 +138,11 @@ int intel_pasid_alloc_table(struct device *dev) return -EINVAL; =20 /* DMA alias device already has a pasid table, use it: */ - data.pasid_table =3D &pasid_table; - ret =3D pci_for_each_dma_alias(to_pci_dev(dev), - &get_alias_pasid_table, &data); - if (ret) + if (pci_for_each_dma_alias(to_pci_dev(dev), + get_alias_pasid_table, &data)) { + pasid_table =3D data.pasid_table; goto attach_out; + } =20 pasid_table =3D kzalloc(sizeof(*pasid_table), GFP_KERNEL); if (!pasid_table) --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7250AC433EF for ; Tue, 14 Jun 2022 02:59:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350370AbiFNC7Z (ORCPT ); Mon, 13 Jun 2022 22:59:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355539AbiFNC6x (ORCPT ); Mon, 13 Jun 2022 22:58:53 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 504E32725 for ; Mon, 13 Jun 2022 19:55:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175344; x=1686711344; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JgUJCM9giMMlxrrl4/MFeIqwQoPEmE59CZySUaxICSM=; b=TBisvL0qAE8ibKUgiigKFVdB0S29oOjaGyUF9NeJo2yWrfyLmPB6KKfT CiBBFFdvpx7WFAvUPUCuRgyusNgI8H9WGGe8T6BYalH7UyT9W4e4ty0bN 2ugwWxQHHXsq8hOaTAE1bPdMVKVX/9cCC1RIZ4QJOOHL8l8guxiLrTwhG YI9By6aQm8US5eTlbtvuWSInzUNPp/biJqW2KPr+LtwFbJ5Nq3sHM3uWv /bHgOAiVvS+JOtfOGtV89tKKLp21vEXRZKnugKDLF/b/FUtFcWIetrb9b hKYtIrK/Gldwd8oRBHV8BOiwMTd/TWIYy5z9aV05q3K9U6EF3BV/NI6ak Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930299" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930299" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166453" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:41 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 03/12] iommu/vt-d: Remove clearing translation data in disable_dmar_iommu() Date: Tue, 14 Jun 2022 10:51:28 +0800 Message-Id: <20220614025137.1632762-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The disable_dmar_iommu() is called when IOMMU initialization fails or the IOMMU is hot-removed from the system. In both cases, there is no need to clear the IOMMU translation data structures for devices. On the initialization path, the device probing only happens after the IOMMU is initialized successfully, hence there're no translation data structures. On the hot-remove path, there is no real use case where the IOMMU is hot-removed, but the devices that it manages are still alive in the system. The translation data structures were torn down during device release, hence there's no need to repeat it in IOMMU hot-remove path either. This removes the unnecessary code and only leaves a check. Signed-off-by: Lu Baolu --- drivers/iommu/intel/pasid.h | 1 + drivers/iommu/intel/iommu.c | 21 +++++++-------------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index 583ea67fc783..2afbb2afe8cc 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -39,6 +39,7 @@ * only and pass-through transfer modes. */ #define FLPT_DEFAULT_DID 1 +#define NUM_RESERVED_DID 2 =20 /* * The SUPERVISOR_MODE flag indicates a first level translation which diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index ff6018f746e0..695aed474e5d 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1715,23 +1715,16 @@ static int iommu_init_domains(struct intel_iommu *i= ommu) =20 static void disable_dmar_iommu(struct intel_iommu *iommu) { - struct device_domain_info *info, *tmp; - unsigned long flags; - if (!iommu->domain_ids) return; =20 - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry_safe(info, tmp, &device_domain_list, global) { - if (info->iommu !=3D iommu) - continue; - - if (!info->dev || !info->domain) - continue; - - __dmar_remove_one_dev_info(info); - } - spin_unlock_irqrestore(&device_domain_lock, flags); + /* + * All iommu domains must have been detached from the devices, + * hence there should be no domain IDs in use. + */ + if (WARN_ON(bitmap_weight(iommu->domain_ids, cap_ndoms(iommu->cap)) + !=3D NUM_RESERVED_DID)) + return; =20 if (iommu->gcmd & DMA_GCMD_TE) iommu_disable_translation(iommu); --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4820C433EF for ; Tue, 14 Jun 2022 03:00:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355144AbiFNDAE (ORCPT ); Mon, 13 Jun 2022 23:00:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355547AbiFNC6y (ORCPT ); Mon, 13 Jun 2022 22:58:54 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 87A5A5FEA for ; Mon, 13 Jun 2022 19:55:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175347; x=1686711347; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=29AHg92ykddBPrrPE1x24Akt3wGIsfhUFlU0p8Ba9Jg=; b=PCsBruZEhevjgmwsn4k7kF2b2IIPIl3jzUzyysZzvELd4tXoNFMZgQj2 B+1tdi14GplEYA4s4DSR0VuzW7UE3njSVjPb5FakP/XZC5kXu3tfvdHjo zhU1uF5KfrVzUOr6tYywxPPxz5/BZFb7UF9vTXVVsnHLJ4se9mNq6b0r4 NDq9MrCxXQxCNs/MtE9JVUd2aSc8pJ9GrZ+Gfd3OtIXlJG5+soItYhEEM IamZBMBjJ+ABIJC3zAd9akazJr5xSqe4InrBLlknDvc6IKv9p/pH97J3S uqNgEouHcjD6F68j6zJ9BALiuJisolMKHXYr7dZguthRK7dogp6QDxnye Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930311" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930311" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166481" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:44 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 04/12] iommu/vt-d: Use pci_get_domain_bus_and_slot() in pgtable_walk() Date: Tue, 14 Jun 2022 10:51:29 +0800 Message-Id: <20220614025137.1632762-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Use pci_get_domain_bus_and_slot() instead of searching the global list to retrieve the pci device pointer. This also removes the global device_domain_list as there isn't any consumer anymore. Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.h | 1 - drivers/iommu/intel/iommu.c | 33 ++++++--------------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 2f4a5b9509c0..6724703d573b 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -609,7 +609,6 @@ struct intel_iommu { /* PCI domain-device relationship */ struct device_domain_info { struct list_head link; /* link to domain siblings */ - struct list_head global; /* link to global list */ struct list_head table; /* link to pasid table */ u32 segment; /* PCI segment number */ u8 bus; /* PCI bus number */ diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 695aed474e5d..839bb5f3e000 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -131,8 +131,6 @@ static struct intel_iommu **g_iommus; =20 static void __init check_tylersburg_isoch(void); static int rwbf_quirk; -static inline struct device_domain_info * -dmar_search_domain_by_dev_info(int segment, int bus, int devfn); =20 /* * set to 1 to panic kernel if can't successfully enable VT-d @@ -315,7 +313,6 @@ static int iommu_skip_te_disable; #define IDENTMAP_AZALIA 4 =20 static DEFINE_SPINLOCK(device_domain_lock); -static LIST_HEAD(device_domain_list); const struct iommu_ops intel_iommu_ops; =20 static bool translation_pre_enabled(struct intel_iommu *iommu) @@ -845,9 +842,14 @@ static void pgtable_walk(struct intel_iommu *iommu, un= signed long pfn, u8 bus, u struct device_domain_info *info; struct dma_pte *parent, *pte; struct dmar_domain *domain; + struct pci_dev *pdev; int offset, level; =20 - info =3D dmar_search_domain_by_dev_info(iommu->segment, bus, devfn); + pdev =3D pci_get_domain_bus_and_slot(iommu->segment, bus, devfn); + if (!pdev) + return; + + info =3D dev_iommu_priv_get(&pdev->dev); if (!info || !info->domain) { pr_info("device [%02x:%02x.%d] not probed\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -2356,19 +2358,6 @@ static void domain_remove_dev_info(struct dmar_domai= n *domain) spin_unlock_irqrestore(&device_domain_lock, flags); } =20 -static inline struct device_domain_info * -dmar_search_domain_by_dev_info(int segment, int bus, int devfn) -{ - struct device_domain_info *info; - - list_for_each_entry(info, &device_domain_list, global) - if (info->segment =3D=3D segment && info->bus =3D=3D bus && - info->devfn =3D=3D devfn) - return info; - - return NULL; -} - static int domain_setup_first_level(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, @@ -4572,7 +4561,6 @@ static struct iommu_device *intel_iommu_probe_device(= struct device *dev) struct pci_dev *pdev =3D dev_is_pci(dev) ? to_pci_dev(dev) : NULL; struct device_domain_info *info; struct intel_iommu *iommu; - unsigned long flags; u8 bus, devfn; =20 iommu =3D device_to_iommu(dev, &bus, &devfn); @@ -4615,10 +4603,7 @@ static struct iommu_device *intel_iommu_probe_device= (struct device *dev) } } =20 - spin_lock_irqsave(&device_domain_lock, flags); - list_add(&info->global, &device_domain_list); dev_iommu_priv_set(dev, info); - spin_unlock_irqrestore(&device_domain_lock, flags); =20 return &iommu->iommu; } @@ -4626,15 +4611,9 @@ static struct iommu_device *intel_iommu_probe_device= (struct device *dev) static void intel_iommu_release_device(struct device *dev) { struct device_domain_info *info =3D dev_iommu_priv_get(dev); - unsigned long flags; =20 dmar_remove_one_dev_info(dev); - - spin_lock_irqsave(&device_domain_lock, flags); dev_iommu_priv_set(dev, NULL); - list_del(&info->global); - spin_unlock_irqrestore(&device_domain_lock, flags); - kfree(info); set_dma_ops(dev, NULL); } --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAC93C433EF for ; Tue, 14 Jun 2022 03:00:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237123AbiFNDA0 (ORCPT ); Mon, 13 Jun 2022 23:00:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355560AbiFNC6y (ORCPT ); Mon, 13 Jun 2022 22:58:54 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67155395 for ; Mon, 13 Jun 2022 19:55:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175350; x=1686711350; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MD6b7Jmra9xHiCqKLw4ESY2w0DMiMfiF6H7FjVcg6Y8=; b=EDSJ0ZQayth1nt9oA5qaIN+/lyxNqqLuMzxi4kpoL5k84en/cYVSwgFb +DEdgByy02C0mt+ClD0Z7e8CSqIhWUCdF8R6zdYVPQ1b98mVcQyUL0a6f UiXjuR9mlp0pjkNPJAqdECZAfZBrq5SvN4fdSIuGr2gsioHVunvHa7w9A lBp18ZpHD2ppZhBmKSG53Kt2ES4ch1CRS160Qlw9SbXixfsz3jNVFCsbX Iq9Q7kqsPtgcOj1fUoPSZhnXatEWdf3J1dKRrj+Y/8bg7zGBvZelguiqS QqMh3iLfq+Ij3Q4jb5xtPQi8FH/kcOtoIFZA0+O/8JEh2MP890/FcAbnR g==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930326" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930326" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166508" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:47 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 05/12] iommu/vt-d: Unnecessary spinlock for root table alloc and free Date: Tue, 14 Jun 2022 10:51:30 +0800 Message-Id: <20220614025137.1632762-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The IOMMU root table is allocated and freed in the IOMMU initialization code in static boot or hot-remove paths. There's no need for a spinlock. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 839bb5f3e000..b2ef8af0c3f3 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -809,14 +809,12 @@ static int device_context_mapped(struct intel_iommu *= iommu, u8 bus, u8 devfn) =20 static void free_context_table(struct intel_iommu *iommu) { - int i; - unsigned long flags; struct context_entry *context; + int i; + + if (!iommu->root_entry) + return; =20 - spin_lock_irqsave(&iommu->lock, flags); - if (!iommu->root_entry) { - goto out; - } for (i =3D 0; i < ROOT_ENTRY_NR; i++) { context =3D iommu_context_addr(iommu, i, 0, 0); if (context) @@ -828,12 +826,10 @@ static void free_context_table(struct intel_iommu *io= mmu) context =3D iommu_context_addr(iommu, i, 0x80, 0); if (context) free_pgtable_page(context); - } + free_pgtable_page(iommu->root_entry); iommu->root_entry =3D NULL; -out: - spin_unlock_irqrestore(&iommu->lock, flags); } =20 #ifdef CONFIG_DMAR_DEBUG @@ -1232,7 +1228,6 @@ static void domain_unmap(struct dmar_domain *domain, = unsigned long start_pfn, static int iommu_alloc_root_entry(struct intel_iommu *iommu) { struct root_entry *root; - unsigned long flags; =20 root =3D (struct root_entry *)alloc_pgtable_page(iommu->node); if (!root) { @@ -1242,10 +1237,7 @@ static int iommu_alloc_root_entry(struct intel_iommu= *iommu) } =20 __iommu_flush_cache(iommu, root, ROOT_SIZE); - - spin_lock_irqsave(&iommu->lock, flags); iommu->root_entry =3D root; - spin_unlock_irqrestore(&iommu->lock, flags); =20 return 0; } --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53213CCA47D for ; Tue, 14 Jun 2022 02:59:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237243AbiFNC7b (ORCPT ); Mon, 13 Jun 2022 22:59:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355562AbiFNC6y (ORCPT ); Mon, 13 Jun 2022 22:58:54 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C22F38F for ; Mon, 13 Jun 2022 19:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175353; x=1686711353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L3qriFSIL9Rs/CZrpXk8fQv7+QTkDASTys7GisGLWzc=; b=ENIpEzokfjnPp0HAjHc14AUBnZzrp+EK33BvFOCwAJSM/cbT/xTQoUMa ZVRgjDmYXz5PZG1WVMhhZOYa2YUbMJ2YRz4KJGSXrEkh135eo7IPon7rY Y/qnKZsQKRkKKe1RxVIYTjDx1vhP5WHh5oDqQIhX4q425RCFtaxdjXC5l jrYA6GQrp5k0vLpB3NnVorLpavG0uouZBqU3si11k7RFjmkYhd+afxRuc v2nuAQbZntdQZTuMSEGrI7s0JzpVshULAJczgQQO3z0jNBUu5cthRGwrS QgNmaYdnDbs4QUbhLezHGWhsOz0VoJdzCKgDILrNIB7p21GPoSQGaLNkU g==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930348" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930348" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166546" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:50 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 06/12] iommu/vt-d: Acquiring lock in domain ID allocation helpers Date: Tue, 14 Jun 2022 10:51:31 +0800 Message-Id: <20220614025137.1632762-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The iommu->lock is used to protect the per-IOMMU domain ID resource. Moving the lock into the ID alloc/free helpers makes the code more compact. At the same time, the device_domain_lock is irrelevant to the domain ID resource, remove its assertion as well. On the other hand, the iommu->lock is never used in interrupt context, there's no need to use the irqsave variant of the spinlock calls. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index b2ef8af0c3f3..8fdaa01ef10d 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1782,16 +1782,13 @@ static struct dmar_domain *alloc_domain(unsigned in= t type) return domain; } =20 -/* Must be called with iommu->lock */ static int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu) { unsigned long ndomains; - int num; - - assert_spin_locked(&device_domain_lock); - assert_spin_locked(&iommu->lock); + int num, ret =3D 0; =20 + spin_lock(&iommu->lock); domain->iommu_refcnt[iommu->seq_id] +=3D 1; if (domain->iommu_refcnt[iommu->seq_id] =3D=3D 1) { ndomains =3D cap_ndoms(iommu->cap); @@ -1800,7 +1797,8 @@ static int domain_attach_iommu(struct dmar_domain *do= main, if (num >=3D ndomains) { pr_err("%s: No free domain ids\n", iommu->name); domain->iommu_refcnt[iommu->seq_id] -=3D 1; - return -ENOSPC; + ret =3D -ENOSPC; + goto out_unlock; } =20 set_bit(num, iommu->domain_ids); @@ -1809,7 +1807,9 @@ static int domain_attach_iommu(struct dmar_domain *do= main, domain_update_iommu_cap(domain); } =20 - return 0; +out_unlock: + spin_unlock(&iommu->lock); + return ret; } =20 static void domain_detach_iommu(struct dmar_domain *domain, @@ -1817,9 +1817,7 @@ static void domain_detach_iommu(struct dmar_domain *d= omain, { int num; =20 - assert_spin_locked(&device_domain_lock); - assert_spin_locked(&iommu->lock); - + spin_lock(&iommu->lock); domain->iommu_refcnt[iommu->seq_id] -=3D 1; if (domain->iommu_refcnt[iommu->seq_id] =3D=3D 0) { num =3D domain->iommu_did[iommu->seq_id]; @@ -1827,6 +1825,7 @@ static void domain_detach_iommu(struct dmar_domain *d= omain, domain_update_iommu_cap(domain); domain->iommu_did[iommu->seq_id] =3D 0; } + spin_unlock(&iommu->lock); } =20 static inline int guestwidth_to_adjustwidth(int gaw) @@ -2479,9 +2478,7 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) =20 spin_lock_irqsave(&device_domain_lock, flags); info->domain =3D domain; - spin_lock(&iommu->lock); ret =3D domain_attach_iommu(domain, iommu); - spin_unlock(&iommu->lock); if (ret) { spin_unlock_irqrestore(&device_domain_lock, flags); return ret; @@ -4166,7 +4163,6 @@ static void __dmar_remove_one_dev_info(struct device_= domain_info *info) { struct dmar_domain *domain; struct intel_iommu *iommu; - unsigned long flags; =20 assert_spin_locked(&device_domain_lock); =20 @@ -4187,10 +4183,7 @@ static void __dmar_remove_one_dev_info(struct device= _domain_info *info) } =20 list_del(&info->link); - - spin_lock_irqsave(&iommu->lock, flags); domain_detach_iommu(domain, iommu); - spin_unlock_irqrestore(&iommu->lock, flags); } =20 static void dmar_remove_one_dev_info(struct device *dev) --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00544C433EF for ; Tue, 14 Jun 2022 02:59:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354946AbiFNC75 (ORCPT ); Mon, 13 Jun 2022 22:59:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355568AbiFNC6z (ORCPT ); Mon, 13 Jun 2022 22:58:55 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6BAAC54 for ; Mon, 13 Jun 2022 19:55:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175356; x=1686711356; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EAjIQYdFglf9BwBkf15G6oBYNR6+NPtkQlQ3XFT8w7Q=; b=bf87ZWUAuKo+Ql+ZpT84BTWj8MQnz49WPu8rYvoJrp78yFdt3oaDE4lt /LqlBo1V+menDcfeaSUCUHhY5SEFEt+2U/r88pCxRzRIvn1sifT0czu+r w1EZwlU8AnEEiTKBNeUwKbog6/a74Ru4/QmBLfjXU6YM+/gdzDOIKjl4f NmEKqMAKYLsPB4z7I0VwLtvv+8JWEuHH9Z4UcKQNGT9DDFzbXoUqSBLCT uCCRD3MV6A5Hk4pJtK46AMzwuNPUu22GEjOSZ9jsBX4Rv/e04lTs88ILs sVCtv6Baru3SFMSxCG3MI8c0x0nKuYW/ecRtRlNjWN9e64MgX/7gTMR82 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930391" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930391" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166570" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:53 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 07/12] iommu/vt-d: Acquiring lock in pasid manipulation helpers Date: Tue, 14 Jun 2022 10:51:32 +0800 Message-Id: <20220614025137.1632762-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The iommu->lock is used to protect the per-IOMMU pasid directory table and pasid table. Move the spinlock acquisition/release into the helpers to make the code self-contained. Again, the iommu->lock is never used in interrupt contexts, hence there's no need to disable the interrupts when holding the lock. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 2 - drivers/iommu/intel/pasid.c | 108 +++++++++++++++++++----------------- drivers/iommu/intel/svm.c | 5 +- 3 files changed, 57 insertions(+), 58 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 8fdaa01ef10d..12cd12fc86a4 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2496,7 +2496,6 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) } =20 /* Setup the PASID entry for requests without PASID: */ - spin_lock_irqsave(&iommu->lock, flags); if (hw_pass_through && domain_type_is_si(domain)) ret =3D intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); @@ -2506,7 +2505,6 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) else ret =3D intel_pasid_setup_second_level(iommu, domain, dev, PASID_RID2PASID); - spin_unlock_irqrestore(&iommu->lock, flags); if (ret) { dev_err(dev, "Setup RID2PASID failed\n"); dmar_remove_one_dev_info(dev); diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 641a4a6eb61e..3276895d7ba7 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -496,17 +496,17 @@ void intel_pasid_tear_down_entry(struct intel_iommu *= iommu, struct device *dev, struct pasid_entry *pte; u16 did, pgtt; =20 + spin_lock(&iommu->lock); pte =3D intel_pasid_get_entry(dev, pasid); - if (WARN_ON(!pte)) - return; - - if (!pasid_pte_is_present(pte)) + if (WARN_ON(!pte) || !pasid_pte_is_present(pte)) { + spin_unlock(&iommu->lock); return; + } =20 did =3D pasid_get_domain_id(pte); pgtt =3D pasid_pte_get_pgtt(pte); - intel_pasid_clear_entry(dev, pasid, fault_ignore); + spin_unlock(&iommu->lock); =20 if (!ecap_coherent(iommu->ecap)) clflush_cache_range(pte, sizeof(*pte)); @@ -542,21 +542,17 @@ static void pasid_flush_caches(struct intel_iommu *io= mmu, } } =20 -static inline int pasid_enable_wpe(struct pasid_entry *pte) +static struct pasid_entry *get_non_present_pasid_entry(struct device *dev, + u32 pasid) { -#ifdef CONFIG_X86 - unsigned long cr0 =3D read_cr0(); + struct pasid_entry *pte; =20 - /* CR0.WP is normally set but just to be sure */ - if (unlikely(!(cr0 & X86_CR0_WP))) { - pr_err_ratelimited("No CPU write protect!\n"); - return -EINVAL; - } -#endif - pasid_set_wpe(pte); + pte =3D intel_pasid_get_entry(dev, pasid); + if (!pte || pasid_pte_is_present(pte)) + return NULL; =20 - return 0; -}; + return pte; +} =20 /* * Set up the scalable mode pasid table entry for first only @@ -574,39 +570,47 @@ int intel_pasid_setup_first_level(struct intel_iommu = *iommu, return -EINVAL; } =20 - pte =3D intel_pasid_get_entry(dev, pasid); - if (WARN_ON(!pte)) + if ((flags & PASID_FLAG_SUPERVISOR_MODE)) { +#ifdef CONFIG_X86 + unsigned long cr0 =3D read_cr0(); + + /* CR0.WP is normally set but just to be sure */ + if (unlikely(!(cr0 & X86_CR0_WP))) { + pr_err("No CPU write protect!\n"); + return -EINVAL; + } +#endif + if (!ecap_srs(iommu->ecap)) { + pr_err("No supervisor request support on %s\n", + iommu->name); + return -EINVAL; + } + } + + if ((flags & PASID_FLAG_FL5LP) && !cap_5lp_support(iommu->cap)) { + pr_err("No 5-level paging support for first-level on %s\n", + iommu->name); return -EINVAL; + } =20 - /* Caller must ensure PASID entry is not in use. */ - if (pasid_pte_is_present(pte)) + spin_lock(&iommu->lock); + pte =3D get_non_present_pasid_entry(dev, pasid); + if (!pte) { + spin_unlock(&iommu->lock); return -EBUSY; + } =20 pasid_clear_entry(pte); =20 /* Setup the first level page table pointer: */ pasid_set_flptr(pte, (u64)__pa(pgd)); if (flags & PASID_FLAG_SUPERVISOR_MODE) { - if (!ecap_srs(iommu->ecap)) { - pr_err("No supervisor request support on %s\n", - iommu->name); - return -EINVAL; - } pasid_set_sre(pte); - if (pasid_enable_wpe(pte)) - return -EINVAL; - + pasid_set_wpe(pte); } =20 - if (flags & PASID_FLAG_FL5LP) { - if (cap_5lp_support(iommu->cap)) { - pasid_set_flpm(pte, 1); - } else { - pr_err("No 5-level paging support for first-level\n"); - pasid_clear_entry(pte); - return -EINVAL; - } - } + if (flags & PASID_FLAG_FL5LP) + pasid_set_flpm(pte, 1); =20 if (flags & PASID_FLAG_PAGE_SNOOP) pasid_set_pgsnp(pte); @@ -618,6 +622,8 @@ int intel_pasid_setup_first_level(struct intel_iommu *i= ommu, /* Setup Present and PASID Granular Transfer Type: */ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_FL_ONLY); pasid_set_present(pte); + spin_unlock(&iommu->lock); + pasid_flush_caches(iommu, pte, pasid, did); =20 return 0; @@ -675,15 +681,12 @@ int intel_pasid_setup_second_level(struct intel_iommu= *iommu, pgd_val =3D virt_to_phys(pgd); did =3D domain->iommu_did[iommu->seq_id]; =20 - pte =3D intel_pasid_get_entry(dev, pasid); + spin_lock(&iommu->lock); + pte =3D get_non_present_pasid_entry(dev, pasid); if (!pte) { - dev_err(dev, "Failed to get pasid entry of PASID %d\n", pasid); - return -ENODEV; - } - - /* Caller must ensure PASID entry is not in use. */ - if (pasid_pte_is_present(pte)) + spin_unlock(&iommu->lock); return -EBUSY; + } =20 pasid_clear_entry(pte); pasid_set_domain_id(pte, did); @@ -700,6 +703,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *= iommu, if (pasid !=3D PASID_RID2PASID) pasid_set_sre(pte); pasid_set_present(pte); + spin_unlock(&iommu->lock); + pasid_flush_caches(iommu, pte, pasid, did); =20 return 0; @@ -715,15 +720,12 @@ int intel_pasid_setup_pass_through(struct intel_iommu= *iommu, u16 did =3D FLPT_DEFAULT_DID; struct pasid_entry *pte; =20 - pte =3D intel_pasid_get_entry(dev, pasid); + spin_lock(&iommu->lock); + pte =3D get_non_present_pasid_entry(dev, pasid); if (!pte) { - dev_err(dev, "Failed to get pasid entry of PASID %d\n", pasid); - return -ENODEV; - } - - /* Caller must ensure PASID entry is not in use. */ - if (pasid_pte_is_present(pte)) + spin_unlock(&iommu->lock); return -EBUSY; + } =20 pasid_clear_entry(pte); pasid_set_domain_id(pte, did); @@ -738,6 +740,8 @@ int intel_pasid_setup_pass_through(struct intel_iommu *= iommu, */ pasid_set_sre(pte); pasid_set_present(pte); + spin_unlock(&iommu->lock); + pasid_flush_caches(iommu, pte, pasid, did); =20 return 0; diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index 580713aa9e07..64072e628bbd 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -328,9 +328,9 @@ static struct iommu_sva *intel_svm_bind_mm(struct intel= _iommu *iommu, unsigned int flags) { struct device_domain_info *info =3D dev_iommu_priv_get(dev); - unsigned long iflags, sflags; struct intel_svm_dev *sdev; struct intel_svm *svm; + unsigned long sflags; int ret =3D 0; =20 svm =3D pasid_private_find(mm->pasid); @@ -394,11 +394,8 @@ static struct iommu_sva *intel_svm_bind_mm(struct inte= l_iommu *iommu, sflags =3D (flags & SVM_FLAG_SUPERVISOR_MODE) ? PASID_FLAG_SUPERVISOR_MODE : 0; sflags |=3D cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0; - spin_lock_irqsave(&iommu->lock, iflags); ret =3D intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid, FLPT_DEFAULT_DID, sflags); - spin_unlock_irqrestore(&iommu->lock, iflags); - if (ret) goto free_sdev; =20 --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DEE0C43334 for ; Tue, 14 Jun 2022 02:59:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354882AbiFNC7s (ORCPT ); Mon, 13 Jun 2022 22:59:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344101AbiFNC64 (ORCPT ); Mon, 13 Jun 2022 22:58:56 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC2061161 for ; Mon, 13 Jun 2022 19:55:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175359; x=1686711359; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fgT3PdgsPjTnJV7XQS4uQIJjlx5l5+fnH5HeIY8TEvU=; b=SAbyF3xvw0Bkl2AOnsjeGA2c5pC06WC0uuKkTmVzGYfiXsEmJuLx1uiD KD8kbtkjIHxS8pK7aIR9Z+S5Ks1raQTEpXvyEZszbYsYZo51X8iFbpQ6X RXclwrxiQ9mEc7/l+5TYn/McokunV7FP3k7Epaums0mEwuUeixV/QSeUA 0mbS6ZcG1XVlbt9nBPS0DOC5heJ4qf9pWH04qmF5z9mMkUqECbCEIfIrq imZqGVazPyjCzM51HZc1zhfPAhqtbHDCKbHDdRCCMTIHCwUTHICLqm/6A 5ZRvF8KzSOMJezNR1gzf8mwWv9fKAZkgrRd3Ocsm085rwRL4GvKDwjonr g==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930423" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930423" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:55:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166586" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:56 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 08/12] iommu/vt-d: Replace spin_lock_irqsave() with spin_lock() Date: Tue, 14 Jun 2022 10:51:33 +0800 Message-Id: <20220614025137.1632762-9-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The iommu->lock is used to protect changes in root/context/pasid tables and domain ID allocation. There's no use case to change these resources in any interrupt context. Hence there's no need to disable interrupts when helding the spinlock. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/debugfs.c | 6 ++---- drivers/iommu/intel/iommu.c | 17 +++++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/intel/debugfs.c b/drivers/iommu/intel/debugfs.c index 5ebfe32265d5..104f9d77b3f0 100644 --- a/drivers/iommu/intel/debugfs.c +++ b/drivers/iommu/intel/debugfs.c @@ -263,10 +263,9 @@ static void ctx_tbl_walk(struct seq_file *m, struct in= tel_iommu *iommu, u16 bus) =20 static void root_tbl_walk(struct seq_file *m, struct intel_iommu *iommu) { - unsigned long flags; u16 bus; =20 - spin_lock_irqsave(&iommu->lock, flags); + spin_lock(&iommu->lock); seq_printf(m, "IOMMU %s: Root Table Address: 0x%llx\n", iommu->name, (u64)virt_to_phys(iommu->root_entry)); seq_puts(m, "B.D.F\tRoot_entry\t\t\t\tContext_entry\t\t\t\tPASID\tPASID_t= able_entry\n"); @@ -278,8 +277,7 @@ static void root_tbl_walk(struct seq_file *m, struct in= tel_iommu *iommu) */ for (bus =3D 0; bus < 256; bus++) ctx_tbl_walk(m, iommu, bus); - - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); } =20 static int dmar_translation_struct_show(struct seq_file *m, void *unused) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 12cd12fc86a4..aec33599c7f7 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -797,13 +797,12 @@ static int device_context_mapped(struct intel_iommu *= iommu, u8 bus, u8 devfn) { struct context_entry *context; int ret =3D 0; - unsigned long flags; =20 - spin_lock_irqsave(&iommu->lock, flags); + spin_lock(&iommu->lock); context =3D iommu_context_addr(iommu, bus, devfn, 0); if (context) ret =3D context_present(context); - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); return ret; } =20 @@ -2295,16 +2294,15 @@ static void domain_context_clear_one(struct device_= domain_info *info, u8 bus, u8 { struct intel_iommu *iommu =3D info->iommu; struct context_entry *context; - unsigned long flags; u16 did_old; =20 if (!iommu) return; =20 - spin_lock_irqsave(&iommu->lock, flags); + spin_lock(&iommu->lock); context =3D iommu_context_addr(iommu, bus, devfn, 0); if (!context) { - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); return; } =20 @@ -2319,7 +2317,7 @@ static void domain_context_clear_one(struct device_do= main_info *info, u8 bus, u8 =20 context_clear_entry(context); __iommu_flush_cache(iommu, context, sizeof(*context)); - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); iommu->flush.flush_context(iommu, did_old, (((u16)bus) << 8) | devfn, @@ -2772,7 +2770,6 @@ static int copy_translation_tables(struct intel_iommu= *iommu) struct root_entry *old_rt; phys_addr_t old_rt_phys; int ctxt_table_entries; - unsigned long flags; u64 rtaddr_reg; int bus, ret; bool new_ext, ext; @@ -2815,7 +2812,7 @@ static int copy_translation_tables(struct intel_iommu= *iommu) } } =20 - spin_lock_irqsave(&iommu->lock, flags); + spin_lock(&iommu->lock); =20 /* Context tables are copied, now write them to the root_entry table */ for (bus =3D 0; bus < 256; bus++) { @@ -2834,7 +2831,7 @@ static int copy_translation_tables(struct intel_iommu= *iommu) iommu->root_entry[bus].hi =3D val; } =20 - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); =20 kfree(ctxt_tbls); =20 --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79032C433EF for ; Tue, 14 Jun 2022 02:59:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354906AbiFNC7y (ORCPT ); Mon, 13 Jun 2022 22:59:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237358AbiFNC64 (ORCPT ); Mon, 13 Jun 2022 22:58:56 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C15F25C9 for ; Mon, 13 Jun 2022 19:56:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175362; x=1686711362; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UyypLQRZ2rwlwU4TmSKR8yEOyNaSyi6KIuXUtRWtZWA=; b=hLPENoNN/Y9UZq0wZyXv8hdvtON1kU1r6LouNvSPPpLOGmVYCnFth/vI AwJIIk7cHJh2pb63pAihWhYdRHcTKg+VYXnJxEnPizaBk1CAjfL7Du71W z+LhjfkSCYLJ2bF41lU9fZYWt2qPpnMf6wvLUykSC37D7MCg5YX541nHs UBqg310+d+CE0+u620PphXr1FaK85zrK25IXQhW5gKlnWbKyV+ezMUMi0 lUnvzpehIKi1BTe1BB0vvo2243lK0t17vKYajawJMan9CcfChXJD2QcWf lzDUsoII21aokFrM+ueroNjM4mblgwhGZscvJhFBEug3E8Tx7ojhG44lb Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930427" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930427" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:56:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166632" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:55:59 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 09/12] iommu/vt-d: Check device list of domain in domain free path Date: Tue, 14 Jun 2022 10:51:34 +0800 Message-Id: <20220614025137.1632762-10-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When the IOMMU domain is about to be freed, it should not be set on any device. Instead of silently dealing with some bug cases, it's better to trigger a warning to report and fix any potential bugs at the first time. Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index aec33599c7f7..af22690f44c8 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -294,7 +294,6 @@ static LIST_HEAD(dmar_satc_units); /* bitmap for indexing intel_iommus */ static int g_num_of_iommus; =20 -static void domain_remove_dev_info(struct dmar_domain *domain); static void dmar_remove_one_dev_info(struct device *dev); static void __dmar_remove_one_dev_info(struct device_domain_info *info); =20 @@ -1843,10 +1842,6 @@ static inline int guestwidth_to_adjustwidth(int gaw) =20 static void domain_exit(struct dmar_domain *domain) { - - /* Remove associated devices and clear attached or cached domains */ - domain_remove_dev_info(domain); - if (domain->pgd) { LIST_HEAD(freelist); =20 @@ -1854,6 +1849,9 @@ static void domain_exit(struct dmar_domain *domain) put_pages_list(&freelist); } =20 + if (WARN_ON(!list_empty(&domain->devices))) + return; + kfree(domain); } =20 @@ -2336,17 +2334,6 @@ static void domain_context_clear_one(struct device_d= omain_info *info, u8 bus, u8 __iommu_flush_dev_iotlb(info, 0, MAX_AGAW_PFN_WIDTH); } =20 -static void domain_remove_dev_info(struct dmar_domain *domain) -{ - struct device_domain_info *info, *tmp; - unsigned long flags; - - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry_safe(info, tmp, &domain->devices, link) - __dmar_remove_one_dev_info(info); - spin_unlock_irqrestore(&device_domain_lock, flags); -} - static int domain_setup_first_level(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD0B4C433EF for ; Tue, 14 Jun 2022 03:00:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237054AbiFNDAj (ORCPT ); Mon, 13 Jun 2022 23:00:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343582AbiFNC7K (ORCPT ); Mon, 13 Jun 2022 22:59:10 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D5D01BEA7 for ; Mon, 13 Jun 2022 19:56:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175369; x=1686711369; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2OradfonvTzvQIlP/JG0I5HnkCgZvFw+PYBG+YT/4/4=; b=i2e3PkpG9vO2hDjNBBFS3qg2P1G+nR3+90Mz9cIqniN5LTE7k3lHtHCF f7abaRQBYoGScBlQ3tqgTHmt2k6gMBY37miIgOOlPxXouuK1L1lhD8QZb ts+gRDdWQgEKuzYAnN3tW89EZJlAl9263yxPu3pvqbrQi8sIEw91FXDLc DfU3oF/nVGgQiSMyDJ0MqJXcCIWtuIx57XWUjnwhQdT9CtX+CFo6cE/W/ k2nGQlYeJeU/MqmgallQZTBJHuNz5u8szpB0FiOExDJbpksFRAHB5z3BR wYAY32djGeAkcy1YobGyXVdm2t0WH6Mkoh9QjCrVUZGYPr6iCvVHiaiCE w==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930433" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930433" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:56:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166694" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:56:02 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 10/12] iommu/vt-d: Fold __dmar_remove_one_dev_info() into its caller Date: Tue, 14 Jun 2022 10:51:35 +0800 Message-Id: <20220614025137.1632762-11-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Fold __dmar_remove_one_dev_info() into dmar_remove_one_dev_info() which is its only caller. Make the spin lock critical range only cover the device list change code and remove some unnecessary checks. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index af22690f44c8..8345e0c0824c 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -295,7 +295,6 @@ static LIST_HEAD(dmar_satc_units); static int g_num_of_iommus; =20 static void dmar_remove_one_dev_info(struct device *dev); -static void __dmar_remove_one_dev_info(struct device_domain_info *info); =20 int dmar_disabled =3D !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON); int intel_iommu_sm =3D IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT= _ON); @@ -4141,20 +4140,14 @@ static void domain_context_clear(struct device_doma= in_info *info) &domain_context_clear_one_cb, info); } =20 -static void __dmar_remove_one_dev_info(struct device_domain_info *info) +static void dmar_remove_one_dev_info(struct device *dev) { - struct dmar_domain *domain; - struct intel_iommu *iommu; - - assert_spin_locked(&device_domain_lock); - - if (WARN_ON(!info)) - return; - - iommu =3D info->iommu; - domain =3D info->domain; + struct device_domain_info *info =3D dev_iommu_priv_get(dev); + struct dmar_domain *domain =3D info->domain; + struct intel_iommu *iommu =3D info->iommu; + unsigned long flags; =20 - if (info->dev && !dev_is_real_dma_subdevice(info->dev)) { + if (!dev_is_real_dma_subdevice(info->dev)) { if (dev_is_pci(info->dev) && sm_supported(iommu)) intel_pasid_tear_down_entry(iommu, info->dev, PASID_RID2PASID, false); @@ -4164,20 +4157,11 @@ static void __dmar_remove_one_dev_info(struct devic= e_domain_info *info) intel_pasid_free_table(info->dev); } =20 - list_del(&info->link); - domain_detach_iommu(domain, iommu); -} - -static void dmar_remove_one_dev_info(struct device *dev) -{ - struct device_domain_info *info; - unsigned long flags; - spin_lock_irqsave(&device_domain_lock, flags); - info =3D dev_iommu_priv_get(dev); - if (info) - __dmar_remove_one_dev_info(info); + list_del(&info->link); spin_unlock_irqrestore(&device_domain_lock, flags); + + domain_detach_iommu(domain, iommu); } =20 static int md_domain_init(struct dmar_domain *domain, int guest_width) --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72642C43334 for ; Tue, 14 Jun 2022 03:00:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231284AbiFNDAM (ORCPT ); Mon, 13 Jun 2022 23:00:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349618AbiFNC7K (ORCPT ); Mon, 13 Jun 2022 22:59:10 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E6A763D0 for ; Mon, 13 Jun 2022 19:56:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175370; x=1686711370; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=X4v9Bmx8d9POOXLVdnulFn+5nL6EUfwlXyM8GuGzRxw=; b=l4NOlHQiwuorKnmkHXQvliEkfcTAclwAosQBYExDk7E215DTPfN44zoG YNh+WBpKbEaAOxoy7Wm8XW9DkpYQapf2d/y1CuKOWbVD00e8gDvd4kjSI qwTOmwmjvkouAws6qI5dSgXBPUe1/HWlrEPTYH1fR6PUXFFQWIGJyoh5/ oKE0N+oi2FPy9v5UeZxcDiiYp+aEqVBJc8g3tdc1EhXqziqajE7UeEFuf M1gs5m4dy09f/KsWH/MudzwxPp8L7kVtS6/jvBuRtn/9pbB0oQacb5So2 +5RVkWLs22U0q80nwa3ulyv2FoTIJb9sQv/4c4DmXDmR+46aAcK3cnVpn w==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930439" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930439" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:56:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166745" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:56:05 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 11/12] iommu/vt-d: Use device_domain_lock accurately Date: Tue, 14 Jun 2022 10:51:36 +0800 Message-Id: <20220614025137.1632762-12-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The device_domain_lock is used to protect the device tracking list of a domain. Remove unnecessary spin_lock/unlock()'s and move the necessary ones around the list access. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 68 +++++++++++++++---------------------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 8345e0c0824c..aa3dea1c9f13 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -534,16 +534,10 @@ static int domain_update_device_node(struct dmar_doma= in *domain) { struct device_domain_info *info; int nid =3D NUMA_NO_NODE; + unsigned long flags; =20 - assert_spin_locked(&device_domain_lock); - - if (list_empty(&domain->devices)) - return NUMA_NO_NODE; - + spin_lock_irqsave(&device_domain_lock, flags); list_for_each_entry(info, &domain->devices, link) { - if (!info->dev) - continue; - /* * There could possibly be multiple device numa nodes as devices * within the same domain may sit behind different IOMMUs. There @@ -554,6 +548,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) if (nid !=3D NUMA_NO_NODE) break; } + spin_unlock_irqrestore(&device_domain_lock, flags); =20 return nid; } @@ -1376,49 +1371,50 @@ static void __iommu_flush_iotlb(struct intel_iommu = *iommu, u16 did, } =20 static struct device_domain_info * -iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *i= ommu, - u8 bus, u8 devfn) +iommu_support_dev_iotlb(struct dmar_domain *domain, struct intel_iommu *io= mmu, + u8 bus, u8 devfn) { - struct device_domain_info *info; - - assert_spin_locked(&device_domain_lock); + struct device_domain_info *info =3D NULL, *tmp; + unsigned long flags; =20 if (!iommu->qi) return NULL; =20 - list_for_each_entry(info, &domain->devices, link) - if (info->iommu =3D=3D iommu && info->bus =3D=3D bus && - info->devfn =3D=3D devfn) { - if (info->ats_supported && info->dev) - return info; + spin_lock_irqsave(&device_domain_lock, flags); + list_for_each_entry(tmp, &domain->devices, link) { + if (tmp->iommu =3D=3D iommu && tmp->bus =3D=3D bus && + tmp->devfn =3D=3D devfn) { + if (tmp->ats_supported) + info =3D tmp; break; } + } + spin_unlock_irqrestore(&device_domain_lock, flags); =20 - return NULL; + return info; } =20 static void domain_update_iotlb(struct dmar_domain *domain) { struct device_domain_info *info; bool has_iotlb_device =3D false; + unsigned long flags; =20 - assert_spin_locked(&device_domain_lock); - - list_for_each_entry(info, &domain->devices, link) + spin_lock_irqsave(&device_domain_lock, flags); + list_for_each_entry(info, &domain->devices, link) { if (info->ats_enabled) { has_iotlb_device =3D true; break; } - + } domain->has_iotlb_device =3D has_iotlb_device; + spin_unlock_irqrestore(&device_domain_lock, flags); } =20 static void iommu_enable_dev_iotlb(struct device_domain_info *info) { struct pci_dev *pdev; =20 - assert_spin_locked(&device_domain_lock); - if (!info || !dev_is_pci(info->dev)) return; =20 @@ -1464,8 +1460,6 @@ static void iommu_disable_dev_iotlb(struct device_dom= ain_info *info) { struct pci_dev *pdev; =20 - assert_spin_locked(&device_domain_lock); - if (!dev_is_pci(info->dev)) return; =20 @@ -1908,11 +1902,11 @@ static int domain_context_mapping_one(struct dmar_d= omain *domain, struct pasid_table *table, u8 bus, u8 devfn) { + struct device_domain_info *info =3D + iommu_support_dev_iotlb(domain, iommu, bus, devfn); u16 did =3D domain->iommu_did[iommu->seq_id]; int translation =3D CONTEXT_TT_MULTI_LEVEL; - struct device_domain_info *info =3D NULL; struct context_entry *context; - unsigned long flags; int ret; =20 WARN_ON(did =3D=3D 0); @@ -1925,7 +1919,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, =20 BUG_ON(!domain->pgd); =20 - spin_lock_irqsave(&device_domain_lock, flags); spin_lock(&iommu->lock); =20 ret =3D -ENOMEM; @@ -1978,7 +1971,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, * Setup the Device-TLB enable bit and Page request * Enable bit: */ - info =3D iommu_support_dev_iotlb(domain, iommu, bus, devfn); if (info && info->ats_supported) context_set_sm_dte(context); if (info && info->pri_supported) @@ -2001,7 +1993,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, goto out_unlock; } =20 - info =3D iommu_support_dev_iotlb(domain, iommu, bus, devfn); if (info && info->ats_supported) translation =3D CONTEXT_TT_DEV_IOTLB; else @@ -2047,7 +2038,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, =20 out_unlock: spin_unlock(&iommu->lock); - spin_unlock_irqrestore(&device_domain_lock, flags); =20 return ret; } @@ -2460,15 +2450,14 @@ static int domain_add_dev_info(struct dmar_domain *= domain, struct device *dev) if (!iommu) return -ENODEV; =20 - spin_lock_irqsave(&device_domain_lock, flags); - info->domain =3D domain; ret =3D domain_attach_iommu(domain, iommu); - if (ret) { - spin_unlock_irqrestore(&device_domain_lock, flags); + if (ret) return ret; - } + + spin_lock_irqsave(&device_domain_lock, flags); list_add(&info->link, &domain->devices); spin_unlock_irqrestore(&device_domain_lock, flags); + info->domain =3D domain; =20 /* PASID table is mandatory for a PCI device in scalable mode. */ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { @@ -4637,7 +4626,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) struct device_domain_info *info =3D dev_iommu_priv_get(dev); struct context_entry *context; struct dmar_domain *domain; - unsigned long flags; u64 ctx_lo; int ret; =20 @@ -4645,7 +4633,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) if (!domain) return -EINVAL; =20 - spin_lock_irqsave(&device_domain_lock, flags); spin_lock(&iommu->lock); =20 ret =3D -EINVAL; @@ -4677,7 +4664,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) =20 out: spin_unlock(&iommu->lock); - spin_unlock_irqrestore(&device_domain_lock, flags); =20 return ret; } --=20 2.25.1 From nobody Mon Apr 27 11:49:27 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA305C433EF for ; Tue, 14 Jun 2022 02:59:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354084AbiFNC7p (ORCPT ); Mon, 13 Jun 2022 22:59:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353824AbiFNC7L (ORCPT ); Mon, 13 Jun 2022 22:59:11 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B39EC1C925 for ; Mon, 13 Jun 2022 19:56:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655175371; x=1686711371; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6v/TvD3cHFaKqMIzUzQPUP7REA0SWO/3xA9jf2Ll40w=; b=PwGh8jGahLnIX1EyLzC0z2Y2wodGG1BDFAZfRotHnhDXSdC/C7n10JT6 qn4MVM+81sCpToZMUiKI+7jbuB8XBYQdIHWG0jiJLc5tuAJsuuuqw03jG jEHE0PMggwsojc4rvDdutYyCe3IgYxykXK5gIUeB8zTMQfYVBDwuO30K1 r10ZVRRrwQYKqvJuPE3/38Di4IKpcfHZBk9WxoAVN3fwWaYAjxVcfkQZu PELCpc9f8RLLHKpMq1qBzjEu0Vm4oYAPQl/ZKbZL0pPF4Z7WFU/WCWQwS 7NEW+ymYfgL7RcPAnDFWuWhUrd9SWCDfNPMG9rJjae//x9EKYYmFRnF7r A==; X-IronPort-AV: E=McAfee;i="6400,9594,10377"; a="258930463" X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="258930463" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2022 19:56:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,298,1647327600"; d="scan'208";a="588166779" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga007.fm.intel.com with ESMTP; 13 Jun 2022 19:56:08 -0700 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Christoph Hellwig , Jason Gunthorpe Cc: Will Deacon , Robin Murphy , Liu Yi L , Jacob jun Pan , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 12/12] iommu/vt-d: Convert global spinlock into per domain ones Date: Tue, 14 Jun 2022 10:51:37 +0800 Message-Id: <20220614025137.1632762-13-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614025137.1632762-1-baolu.lu@linux.intel.com> References: <20220614025137.1632762-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Using a global device_domain_lock spinlock to protect per-domain device tracking lists is an inefficient way, especially considering this lock is also needed in the hot paths. This optimizes the locking mechanism by converting the global lock to per domain lock. On the other hand, as the device tracking lists are never accessed in any interrupt context, there is no need to disable interrupts while spinning. Replace irqsave variant with spinlock calls. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.h | 1 + drivers/iommu/intel/iommu.c | 45 +++++++++++++++---------------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 6724703d573b..cc304ff09a7b 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -541,6 +541,7 @@ struct dmar_domain { u8 force_snooping : 1; /* Create IOPTEs with snoop control */ u8 set_pte_snp:1; =20 + spinlock_t lock; /* Protect device tracking lists */ struct list_head devices; /* all devices' list */ =20 struct dma_pte *pgd; /* virtual address */ diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index aa3dea1c9f13..60e70682a190 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -310,7 +310,6 @@ static int iommu_skip_te_disable; #define IDENTMAP_GFX 2 #define IDENTMAP_AZALIA 4 =20 -static DEFINE_SPINLOCK(device_domain_lock); const struct iommu_ops intel_iommu_ops; =20 static bool translation_pre_enabled(struct intel_iommu *iommu) @@ -534,9 +533,8 @@ static int domain_update_device_node(struct dmar_domain= *domain) { struct device_domain_info *info; int nid =3D NUMA_NO_NODE; - unsigned long flags; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) { /* * There could possibly be multiple device numa nodes as devices @@ -548,7 +546,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) if (nid !=3D NUMA_NO_NODE) break; } - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); =20 return nid; } @@ -1375,12 +1373,11 @@ iommu_support_dev_iotlb(struct dmar_domain *domain,= struct intel_iommu *iommu, u8 bus, u8 devfn) { struct device_domain_info *info =3D NULL, *tmp; - unsigned long flags; =20 if (!iommu->qi) return NULL; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_for_each_entry(tmp, &domain->devices, link) { if (tmp->iommu =3D=3D iommu && tmp->bus =3D=3D bus && tmp->devfn =3D=3D devfn) { @@ -1389,7 +1386,7 @@ iommu_support_dev_iotlb(struct dmar_domain *domain, s= truct intel_iommu *iommu, break; } } - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); =20 return info; } @@ -1398,9 +1395,8 @@ static void domain_update_iotlb(struct dmar_domain *d= omain) { struct device_domain_info *info; bool has_iotlb_device =3D false; - unsigned long flags; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) { if (info->ats_enabled) { has_iotlb_device =3D true; @@ -1408,7 +1404,7 @@ static void domain_update_iotlb(struct dmar_domain *d= omain) } } domain->has_iotlb_device =3D has_iotlb_device; - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); } =20 static void iommu_enable_dev_iotlb(struct device_domain_info *info) @@ -1499,17 +1495,15 @@ static void __iommu_flush_dev_iotlb(struct device_d= omain_info *info, static void iommu_flush_dev_iotlb(struct dmar_domain *domain, u64 addr, unsigned mask) { - unsigned long flags; struct device_domain_info *info; =20 if (!domain->has_iotlb_device) return; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) __iommu_flush_dev_iotlb(info, addr, mask); - - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); } =20 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, @@ -1769,6 +1763,7 @@ static struct dmar_domain *alloc_domain(unsigned int = type) domain->flags |=3D DOMAIN_FLAG_USE_FIRST_LEVEL; domain->has_iotlb_device =3D false; INIT_LIST_HEAD(&domain->devices); + spin_lock_init(&domain->lock); =20 return domain; } @@ -2442,7 +2437,6 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) { struct device_domain_info *info =3D dev_iommu_priv_get(dev); struct intel_iommu *iommu; - unsigned long flags; u8 bus, devfn; int ret; =20 @@ -2454,9 +2448,9 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) if (ret) return ret; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_add(&info->link, &domain->devices); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); info->domain =3D domain; =20 /* PASID table is mandatory for a PCI device in scalable mode. */ @@ -4134,7 +4128,6 @@ static void dmar_remove_one_dev_info(struct device *d= ev) struct device_domain_info *info =3D dev_iommu_priv_get(dev); struct dmar_domain *domain =3D info->domain; struct intel_iommu *iommu =3D info->iommu; - unsigned long flags; =20 if (!dev_is_real_dma_subdevice(info->dev)) { if (dev_is_pci(info->dev) && sm_supported(iommu)) @@ -4146,9 +4139,9 @@ static void dmar_remove_one_dev_info(struct device *d= ev) intel_pasid_free_table(info->dev); } =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&domain->lock); list_del(&info->link); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&domain->lock); =20 domain_detach_iommu(domain, iommu); } @@ -4432,7 +4425,7 @@ static bool domain_support_force_snooping(struct dmar= _domain *domain) struct device_domain_info *info; bool support =3D true; =20 - assert_spin_locked(&device_domain_lock); + assert_spin_locked(&domain->lock); list_for_each_entry(info, &domain->devices, link) { if (!ecap_sc_support(info->iommu->ecap)) { support =3D false; @@ -4447,8 +4440,7 @@ static void domain_set_force_snooping(struct dmar_dom= ain *domain) { struct device_domain_info *info; =20 - assert_spin_locked(&device_domain_lock); - + assert_spin_locked(&domain->lock); /* * Second level page table supports per-PTE snoop control. The * iommu_map() interface will handle this by setting SNP bit. @@ -4466,20 +4458,19 @@ static void domain_set_force_snooping(struct dmar_d= omain *domain) static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domai= n) { struct dmar_domain *dmar_domain =3D to_dmar_domain(domain); - unsigned long flags; =20 if (dmar_domain->force_snooping) return true; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&dmar_domain->lock); if (!domain_support_force_snooping(dmar_domain)) { - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&dmar_domain->lock); return false; } =20 domain_set_force_snooping(dmar_domain); dmar_domain->force_snooping =3D true; - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&dmar_domain->lock); =20 return true; } --=20 2.25.1