From nobody Sun Apr 19 05:31:39 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 09B1FCCA47B for ; Wed, 6 Jul 2022 02:59:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231368AbiGFC75 (ORCPT ); Tue, 5 Jul 2022 22:59:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229645AbiGFC7y (ORCPT ); Tue, 5 Jul 2022 22:59:54 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E05C1A83C for ; Tue, 5 Jul 2022 19:59:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076394; x=1688612394; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RglkaDn/jOyxV3iDLdnwbZrQLmp90jV1b+cWCbFzid4=; b=FVx1bso/bIZqsJtratcjZqTTeTBgxJOZ/xm4bPZWeZ8B/VVf0rDzLCzP PjdAJy1ObNc4cImWaU8WMoniOw26hWVRwrcgFMIshayPwx2UCyDcqvCUw /VZv75+dFvJ68qL+LYFu7fzOBaA+xGHalPTX/PdenPcGiG4PMmzLhlCkn 1rHdG2XJ3FTsYDehyXVpLtG9+gjAIEWI8E+icED1Oxgu2v1BqudW/+dRq eJBcFZYh2QGO0wCB0y+Gfq5iDtfnQoQt67cLDKNNLB2xe7yu8lB9C2cpe h1wo52/Z/v34Wgg0SXAycvxUIJj+defD4K66j51FJXVomitCbOeV5hlaF A==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409526" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409526" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 19:59:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567874761" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 19:59:51 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 01/11] iommu/vt-d: debugfs: Remove device_domain_lock usage Date: Wed, 6 Jul 2022 10:55:14 +0800 Message-Id: <20220706025524.2904370-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 the global spinlock device_domain_lock to avoid the races. This removes the use of device_domain_lock outside of iommu.c by replacing it with the group mutex lock. Using the group mutex lock is cleaner and more compatible to following cleanups. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.h | 1 - drivers/iommu/intel/debugfs.c | 43 +++++++++++++++++++++++++---------- drivers/iommu/intel/iommu.c | 2 +- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 8285fcfa5fea..8deb745d8b36 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..6e1a3f88abc8 100644 --- a/drivers/iommu/intel/debugfs.c +++ b/drivers/iommu/intel/debugfs.c @@ -342,13 +342,13 @@ 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) +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 dmar_domain *domain; struct seq_file *m =3D data; u64 path[6] =3D { 0 }; =20 + domain =3D to_dmar_domain(iommu_get_domain_for_dev(dev)); if (!domain) return 0; =20 @@ -359,20 +359,39 @@ 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; + /* Don't iterate */ + 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 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. + * + * All devices in an iommu group share a single domain, hence + * we only dump the domain of the first device. Even though, + * this code still possibly races with the iommu_unmap() + * interface. This could be solved by RCU-freeing the page + * table pages in the iommu_unmap() path. + */ + iommu_group_for_each_dev(group, data, + __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 10bda4bec8fe..3b6571681bdd 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 const struct iommu_ops intel_iommu_ops; --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 0B6F1C433EF for ; Wed, 6 Jul 2022 03:00:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231415AbiGFDAA (ORCPT ); Tue, 5 Jul 2022 23:00:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231386AbiGFC75 (ORCPT ); Tue, 5 Jul 2022 22:59:57 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 849511ADA8 for ; Tue, 5 Jul 2022 19:59: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=1657076396; x=1688612396; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hkGm7YDPu5xil+VGf8bn6+rNMEI6Bw40A3ib6a6DFDY=; b=WiK35u5weMHc1cTY1s6U9peoIsqMY1oNvwRd6eu7bwMR8CiHn0McM8K8 0QiHJW2hKwQbtoOJ46hdVKwyzeYZXHEicLQ/Tuxk49ZEuGqLcilDQaQuY sZ/okp3CmDd9dsp0HBbcSwT3ejwCPsPLEXMUfpgdbJ21n5ceiZ0Y4ZKAK fr3AfNG6T1FzJHrctLKs2/3aYHpimt50DXoNw+u4qDT8S/0rLX+GkK3iq t3p3iDnVEQ6/S2hGV57YY7HRyh0nyuDeJo5qX24VjEVhxF3hWehpHnx/6 3huoxA7sU5syVkSH/045cpCr4kL24TWMgGA3KM6UfnnZyNr1VKG+oPiqQ g==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409532" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409532" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 19:59:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567874772" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 19:59:54 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 02/11] iommu/vt-d: Remove clearing translation data in disable_dmar_iommu() Date: Wed, 6 Jul 2022 10:55:15 +0800 Message-Id: <20220706025524.2904370-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 Reviewed-by: Kevin Tian --- 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 bf5b937848b4..20c54e50f533 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 3b6571681bdd..43aaec5bdd84 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1716,23 +1716,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)) + > NUM_RESERVED_DID)) + return; =20 if (iommu->gcmd & DMA_GCMD_TE) iommu_disable_translation(iommu); --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 43454C433EF for ; Wed, 6 Jul 2022 03:00:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231441AbiGFDAK (ORCPT ); Tue, 5 Jul 2022 23:00:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231372AbiGFDAA (ORCPT ); Tue, 5 Jul 2022 23:00:00 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 638711AF0D for ; Tue, 5 Jul 2022 19:59: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=1657076399; x=1688612399; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=d3apr3bU9mf+okAIPMYSp8s/p9GHpJYjT6FHqDZj33g=; b=M40o6sqj4EcvM4RwQw4FrPgCiJoDPemCUn9XJPWmMe+8FEmgaB/XhiRP opBjn/F3SRSyW4ufL/O5RVW2qAOoNMtH8cX/r9zfQPEykvk5RpewIeesu NF9D/pZWKf7sD/j7vGfnY3kJTjKGs+RYiq1PHiDHWU4RX/tLXF9uCRafe xl7s20LJgLX4R0HS5ibtcBpTmHVcg94ZcP+mSve09BW4wHYNSuWA2A5Lb tTQscNilt1Xpi3J/nko6lRGeChvkTG7TVdIQG3Tk9uy6XFdm/+8BPluQg IcrlHr6xf1VxGMqT945tZZ/KHbkh7ctp2qyjKN/24jndi5aCDn/cawNy+ A==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409540" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409540" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 19:59:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567874783" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 19:59:56 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu , Jason Gunthorpe Subject: [PATCH v4 03/11] iommu/vt-d: Use pci_get_domain_bus_and_slot() in pgtable_walk() Date: Wed, 6 Jul 2022 10:55:16 +0800 Message-Id: <20220706025524.2904370-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 | 34 ++++++---------------------------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 8deb745d8b36..198c6c822ef4 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 */ u32 segment; /* PCI segment number */ u8 bus; /* PCI bus number */ u8 devfn; /* PCI devfn number */ diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 43aaec5bdd84..77915d61f7ec 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,8 +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) @@ -846,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)); @@ -2357,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, @@ -4573,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); @@ -4616,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; } @@ -4627,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 Sun Apr 19 05:31:39 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 1E5EFC433EF for ; Wed, 6 Jul 2022 03:00:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231483AbiGFDAP (ORCPT ); Tue, 5 Jul 2022 23:00:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231447AbiGFDAH (ORCPT ); Tue, 5 Jul 2022 23:00:07 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4FA51B79B for ; Tue, 5 Jul 2022 20:00:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076401; x=1688612401; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1CTKfefQ/h6z94Nvf/sEonitLTLnAFkKkQpkqf1GosQ=; b=YWRLO7kQdathmhc2izWRqwbhzyg/++X/DyUM0F99dsOG4YBUG9edQi4+ E9Lrz2DCkOM5RykRbS0o15vSSpYJdqbGRrU+FfMkHIPcD8KGQ4eAFUjL7 1AxtxlzokzABYEyireQ9HKKQ0BTtuWl3VIVhO8TdD0SDg4Zz9ggOrinbL mKBX9BJwOam7jhr+ybGNJ0W/c31PxZKKHJXoQSNm3HBRRoM8mV/LqSkjN gTcdVIzqFStf+uFLhw3F9ICCEs9VvI1zb5gaHV0qZEduweGllAhv87MZ6 E25zIjriG+wEqyc2//sLo358c2cZ3UQle7vcWrytGOc9hrXuxpbNpPFUZ g==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409543" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409543" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567874816" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 19:59:59 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 04/11] iommu/vt-d: Unnecessary spinlock for root table alloc and free Date: Wed, 6 Jul 2022 10:55:17 +0800 Message-Id: <20220706025524.2904370-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 77915d61f7ec..ff49c9460ede 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 Sun Apr 19 05:31:39 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 B6AB7C433EF for ; Wed, 6 Jul 2022 03:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231435AbiGFDAV (ORCPT ); Tue, 5 Jul 2022 23:00:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231425AbiGFDAI (ORCPT ); Tue, 5 Jul 2022 23:00:08 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 900041B7B2 for ; Tue, 5 Jul 2022 20:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076404; x=1688612404; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TS5p2rw3PsIM1CYsCu2DJHLpkbTSVEYtGFFxg0dwPhQ=; b=KHEBcKDPFrG4Z+uECUiitoAckPfsSx+9Z9SCFa6xwyxRLT/2AZ9xvGir GBp5xnqDbS+AeL7DK7Pib1jci8Ax2cqlxly1lq1spBtYo7OXEnsjLFS9v 1JMcSuvmvrjGOCyA9E10dJtiL62hJLcb7slJs8D5lD6q0YC79umfk2xe6 Okd+1DHzSq8qfo6IrMoos/zYyqMurh5ua4nO8HGng3aCw8fMIxiVdeEv6 OJr6q8gWXoN25gfPl/Oj+yzuWHiITVhuGfBVw0RV1crMuC9DiVV3gWoEc RClEeTtq6K3ajrKMoIMzN+46q7o3+/Hu3fEqlaHIXx1bgzpVHFi4nhx22 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409553" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409553" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567874928" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:01 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 05/11] iommu/vt-d: Replace spin_lock_irqsave() with spin_lock() Date: Wed, 6 Jul 2022 10:55:18 +0800 Message-Id: <20220706025524.2904370-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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. Therefore, it is unnecessary to disable the interrupts when the spinlock is held. The same thing happens on the device_domain_lock side, which protects the device domain attachment information. This replaces spin_lock/unlock_irqsave/irqrestore() calls with the normal spin_lock/unlock(). Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/debugfs.c | 6 ++-- drivers/iommu/intel/iommu.c | 66 ++++++++++++++--------------------- drivers/iommu/intel/svm.c | 6 ++-- 3 files changed, 32 insertions(+), 46 deletions(-) diff --git a/drivers/iommu/intel/debugfs.c b/drivers/iommu/intel/debugfs.c index 6e1a3f88abc8..1f925285104e 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 ff49c9460ede..93f01082dce1 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 @@ -1508,17 +1507,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(&device_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(&device_domain_lock); } =20 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, @@ -1917,7 +1914,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, 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); @@ -1930,7 +1926,7 @@ 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(&device_domain_lock); spin_lock(&iommu->lock); =20 ret =3D -ENOMEM; @@ -2052,7 +2048,7 @@ 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); + spin_unlock(&device_domain_lock); =20 return ret; } @@ -2296,16 +2292,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 @@ -2320,7 +2315,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, @@ -2342,12 +2337,11 @@ static void domain_context_clear_one(struct device_= domain_info *info, u8 bus, u8 static void domain_remove_dev_info(struct dmar_domain *domain) { struct device_domain_info *info, *tmp; - unsigned long flags; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&device_domain_lock); list_for_each_entry_safe(info, tmp, &domain->devices, link) __dmar_remove_one_dev_info(info); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&device_domain_lock); } =20 static int domain_setup_first_level(struct intel_iommu *iommu, @@ -2469,7 +2463,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 @@ -2477,17 +2470,17 @@ 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); + spin_lock(&device_domain_lock); 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); + spin_unlock(&device_domain_lock); return ret; } list_add(&info->link, &domain->devices); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&device_domain_lock); =20 /* PASID table is mandatory for a PCI device in scalable mode. */ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { @@ -2499,7 +2492,7 @@ 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); + spin_lock(&iommu->lock); if (hw_pass_through && domain_type_is_si(domain)) ret =3D intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); @@ -2509,7 +2502,7 @@ 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); + spin_unlock(&iommu->lock); if (ret) { dev_err(dev, "Setup RID2PASID failed\n"); dmar_remove_one_dev_info(dev); @@ -2777,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; @@ -2820,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++) { @@ -2839,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 @@ -4166,7 +4158,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 @@ -4188,21 +4179,20 @@ static void __dmar_remove_one_dev_info(struct devic= e_domain_info *info) =20 list_del(&info->link); =20 - spin_lock_irqsave(&iommu->lock, flags); + spin_lock(&iommu->lock); domain_detach_iommu(domain, iommu); - spin_unlock_irqrestore(&iommu->lock, flags); + spin_unlock(&iommu->lock); } =20 static void dmar_remove_one_dev_info(struct device *dev) { struct device_domain_info *info; - unsigned long flags; =20 - spin_lock_irqsave(&device_domain_lock, flags); + spin_lock(&device_domain_lock); info =3D dev_iommu_priv_get(dev); if (info) __dmar_remove_one_dev_info(info); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&device_domain_lock); } =20 static int md_domain_init(struct dmar_domain *domain, int guest_width) @@ -4518,20 +4508,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(&device_domain_lock); if (!domain_support_force_snooping(dmar_domain)) { - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock(&device_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(&device_domain_lock); =20 return true; } @@ -4678,7 +4667,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 @@ -4686,7 +4674,7 @@ 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(&device_domain_lock); spin_lock(&iommu->lock); =20 ret =3D -EINVAL; @@ -4718,7 +4706,7 @@ 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); + spin_unlock(&device_domain_lock); =20 return ret; } diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index 580713aa9e07..82288a50660d 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,10 +394,10 @@ static struct iommu_sva *intel_svm_bind_mm(struct int= el_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); + spin_lock(&iommu->lock); ret =3D intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid, FLPT_DEFAULT_DID, sflags); - spin_unlock_irqrestore(&iommu->lock, iflags); + spin_unlock(&iommu->lock); =20 if (ret) goto free_sdev; --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 A6741C43334 for ; Wed, 6 Jul 2022 03:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231561AbiGFDA3 (ORCPT ); Tue, 5 Jul 2022 23:00:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231436AbiGFDAJ (ORCPT ); Tue, 5 Jul 2022 23:00:09 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21E191BE85 for ; Tue, 5 Jul 2022 20:00:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076407; x=1688612407; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yJXUA+NuM0V10Ayu1Uk2puf2SUIVOwGMq3d3tn/fE84=; b=GrGdeQ07LZqKRULEzmb/QK2Uu+MYdfVjWallutsgZPfQEbsolnZuQ/aQ Q/KpIKYdlc86W2q+vEjGxr0P7GszAFV6VfZ0bhomUKmCUHoFuT1ExsQjX SPU2DDPs7ThRFwia3LtXMR9ZWHlbEzLDc4nMTlwyMD2fuPlwk7eMY3LkU V823PK0Khs/pCQBSLAybUkPX9BZDUw7WFd4gK4JPub7H3e7tipIpxezOQ rDAYbeSLShVgn4GJyK7ZoEJD/0giTkEaU8jav6T6ADU41wlH1MYooqFV0 nZEec7534egixYlAZpCCcGfdwknoZBH67YefRGl8pGybDaTaetqN+2wmd w==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409573" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409573" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875034" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:04 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 06/11] iommu/vt-d: Acquiring lock in domain ID allocation helpers Date: Wed, 6 Jul 2022 10:55:19 +0800 Message-Id: <20220706025524.2904370-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 93f01082dce1..7f03576e72d7 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1779,16 +1779,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); @@ -1797,7 +1794,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); @@ -1806,7 +1804,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, @@ -1814,9 +1814,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]; @@ -1824,6 +1822,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) @@ -2472,9 +2471,7 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) =20 spin_lock(&device_domain_lock); info->domain =3D domain; - spin_lock(&iommu->lock); ret =3D domain_attach_iommu(domain, iommu); - spin_unlock(&iommu->lock); if (ret) { spin_unlock(&device_domain_lock); return ret; @@ -4178,10 +4175,7 @@ static void __dmar_remove_one_dev_info(struct device= _domain_info *info) } =20 list_del(&info->link); - - spin_lock(&iommu->lock); domain_detach_iommu(domain, iommu); - spin_unlock(&iommu->lock); } =20 static void dmar_remove_one_dev_info(struct device *dev) --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 7F22CC43334 for ; Wed, 6 Jul 2022 03:00:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231492AbiGFDAe (ORCPT ); Tue, 5 Jul 2022 23:00:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231452AbiGFDAL (ORCPT ); Tue, 5 Jul 2022 23:00:11 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0059A1B789 for ; Tue, 5 Jul 2022 20:00: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=1657076410; x=1688612410; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=C3JcqkNtyIa/3XeEvp8QehQA1FW7d0yOZTzbsfqpcAY=; b=UnK7QUmCwvFS8lcbNNZnTpWwrQYF8XZzLjshDVuUcCbOddnrMXEP3ctx 3KHq4RBsnVdZH/LT4VGmneyUoOVdW72+qvdX/Y5htv4HXICfV9ktSw9+h zbvx6qHnU89iNB+d3rx7qyht5RqANETyzQlkjQ8o4h9YL1Rw4Huqe/fgh XuK+nCvUb+jt0Mpuoa5jHjyDhDdrEoczRsOXS8HKOpp934re1HQxsm69x LB1LEa7tTlWopEE+5SnDbRfnCqodMYUrom3ml+NGJJ7bVM5FsdIQD2lse rC8eJLkDtlMNoVnR1wV3FKgJV3bFw9vDawmPyXni/GgxFAywy5cuYz+N1 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409579" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409579" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875151" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:07 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 07/11] iommu/vt-d: Acquiring lock in pasid manipulation helpers Date: Wed, 6 Jul 2022 10:55:20 +0800 Message-Id: <20220706025524.2904370-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 2 - drivers/iommu/intel/pasid.c | 103 +++++++++++++++++++----------------- drivers/iommu/intel/svm.c | 3 -- 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 7f03576e72d7..3d53de8c7634 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2489,7 +2489,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(&iommu->lock); if (hw_pass_through && domain_type_is_si(domain)) ret =3D intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); @@ -2499,7 +2498,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(&iommu->lock); 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 43f090381ec7..7792a1b2ebc4 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -450,17 +450,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)); @@ -496,22 +496,6 @@ static void pasid_flush_caches(struct intel_iommu *iom= mu, } } =20 -static inline int pasid_enable_wpe(struct pasid_entry *pte) -{ -#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_ratelimited("No CPU write protect!\n"); - return -EINVAL; - } -#endif - pasid_set_wpe(pte); - - return 0; -}; - /* * Set up the scalable mode pasid table entry for first only * translation type. @@ -528,39 +512,52 @@ 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 intel_pasid_get_entry(dev, pasid); + if (!pte) { + spin_unlock(&iommu->lock); + return -ENODEV; + } + + if (pasid_pte_is_present(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); @@ -572,6 +569,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; @@ -629,15 +628,17 @@ 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 + spin_lock(&iommu->lock); pte =3D intel_pasid_get_entry(dev, pasid); if (!pte) { - dev_err(dev, "Failed to get pasid entry of PASID %d\n", pasid); + spin_unlock(&iommu->lock); return -ENODEV; } =20 - /* Caller must ensure PASID entry is not in use. */ - if (pasid_pte_is_present(pte)) + if (pasid_pte_is_present(pte)) { + spin_unlock(&iommu->lock); return -EBUSY; + } =20 pasid_clear_entry(pte); pasid_set_domain_id(pte, did); @@ -654,6 +655,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; @@ -669,15 +672,17 @@ int intel_pasid_setup_pass_through(struct intel_iommu= *iommu, u16 did =3D FLPT_DEFAULT_DID; struct pasid_entry *pte; =20 + spin_lock(&iommu->lock); pte =3D intel_pasid_get_entry(dev, pasid); if (!pte) { - dev_err(dev, "Failed to get pasid entry of PASID %d\n", pasid); + spin_unlock(&iommu->lock); return -ENODEV; } =20 - /* Caller must ensure PASID entry is not in use. */ - if (pasid_pte_is_present(pte)) + if (pasid_pte_is_present(pte)) { + spin_unlock(&iommu->lock); return -EBUSY; + } =20 pasid_clear_entry(pte); pasid_set_domain_id(pte, did); @@ -692,6 +697,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 82288a50660d..64072e628bbd 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -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(&iommu->lock); ret =3D intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid, FLPT_DEFAULT_DID, sflags); - spin_unlock(&iommu->lock); - if (ret) goto free_sdev; =20 --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 8D372C433EF for ; Wed, 6 Jul 2022 03:00:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231508AbiGFDAh (ORCPT ); Tue, 5 Jul 2022 23:00:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231433AbiGFDAP (ORCPT ); Tue, 5 Jul 2022 23:00:15 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92E711AF2C for ; Tue, 5 Jul 2022 20:00:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076412; x=1688612412; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LImdZq86xx+dG7JHLesZkhPMUf7odOMmhfDwO8VtyYY=; b=fIwUF1VLDDfC7OjTeq0dQ0v9ld63AsKgDMalAuwmd4cQ91D3I2Xiu49/ mc0gY3P24fp21rp2uY2MA1awXwGCPR0EtRGayNjG8yiU+vqWlIFZlBV8q hwD97jJI4ej0ik8BILIZiX9uIGqwybVcj+tqMcG8nPGWE1ClkchAZu6DH Ujt164PeOef/MvfiPdC3AAyn8RMyxqKRm73+CCY59ocrKeuQwXS9t0M24 yiWOxjjOQvXVInNbWknV3WyIWNvilJ7FjpG18HNzDFflbgHDKJkhaVZWw vbMN2bfzRasBhkFsWiTExea7sdNjcM3oUHDydR8AUyq+yTiJx2ePULgT7 A==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409587" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409587" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875225" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:10 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu , Jason Gunthorpe Subject: [PATCH v4 08/11] iommu/vt-d: Check device list of domain in domain free path Date: Wed, 6 Jul 2022 10:55:21 +0800 Message-Id: <20220706025524.2904370-9-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 3d53de8c7634..a94fb69e1f9a 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 @@ -1841,10 +1840,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 @@ -1852,6 +1847,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 @@ -2333,16 +2331,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; - - spin_lock(&device_domain_lock); - list_for_each_entry_safe(info, tmp, &domain->devices, link) - __dmar_remove_one_dev_info(info); - spin_unlock(&device_domain_lock); -} - static int domain_setup_first_level(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 D241FC433EF for ; Wed, 6 Jul 2022 03:00:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231665AbiGFDAl (ORCPT ); Tue, 5 Jul 2022 23:00:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231512AbiGFDAS (ORCPT ); Tue, 5 Jul 2022 23:00:18 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 466F01B79D for ; Tue, 5 Jul 2022 20:00:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076415; x=1688612415; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2CBt8W0Jz4MB0nE32RyXPoX0OFG6DCbHzWMHPgH8Fwg=; b=Q8zbsCKwoTeBbj3IpmaAADYRofVu9aJj6zldhvDD0O9g3iSQAm0LTDDZ dQUCLAW6+ZrRvSzQ8D1oCYgpR2tQFlvqv1pTtOHTImi6hLdCk6fTL2agV xown1kxXzGZ3BE1HH4XAMWJohPd3eVN9LqFDdOQr20NhUqk01M1MmAf7q 5oMKkt1A8u+9gbr9gf/hJRcjlzWCtud6dMoBWniPcfnMPDMeD+rAOdeBV j8Xc7H+8LeXb4ibkiv/SsSBjaw855+b4juFG8fWa2urLQr/ZUV4WnAFry UAw/vfyUPWDP8jdjVsV+IrEdwwrm15R7enK3IxNTOl89r2YdCSOBabCoZ Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409594" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409594" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875268" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:12 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 09/11] iommu/vt-d: Fold __dmar_remove_one_dev_info() into its caller Date: Wed, 6 Jul 2022 10:55:22 +0800 Message-Id: <20220706025524.2904370-10-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index a94fb69e1f9a..899ae63e1ddf 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); @@ -4137,20 +4136,12 @@ 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 intel_iommu *iommu =3D info->iommu; =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); @@ -4160,19 +4151,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; - spin_lock(&device_domain_lock); - info =3D dev_iommu_priv_get(dev); - if (info) - __dmar_remove_one_dev_info(info); + list_del(&info->link); spin_unlock(&device_domain_lock); + + domain_detach_iommu(info->domain, iommu); } =20 static int md_domain_init(struct dmar_domain *domain, int guest_width) --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 A2FBAC43334 for ; Wed, 6 Jul 2022 03:00:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231684AbiGFDAo (ORCPT ); Tue, 5 Jul 2022 23:00:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231520AbiGFDAT (ORCPT ); Tue, 5 Jul 2022 23:00:19 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10ED51BE8E for ; Tue, 5 Jul 2022 20:00:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076418; x=1688612418; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hEpBYdeZhQy0F5FFGq2HaM1gLEXbenT6fwpuBylUe7A=; b=ZsmJPx/v2Rv1B0fNRNJzIBU5AsBjFTrvvBhTjAuRMOuCdBFnw1/jGsHM DJCbvFeYQQ+PlaIFDdvIX4sUA+ug99aEE6aarf1EgBadVwfs3m9jwEtjp IcNskI7xSF8OHmyA0zv8dsHtrsab5mFWqcVqu5G4bYeBpA6LgAYyMN56y h91BwvBdQO+LcQmhoPFwg5dhdYqgjR1v4CEn9RAbdP7DYS6N5ca8f5oSo w3ZJggsLpt6Bcj0JUw7pedICrLxgaFXMVvdxb3tkLz46QTRzIeKzB6esX tYdYGz0SrmkaUgOWpVI9xKaqrY/T8QDHSl9xiBl6v5Cbg90c2SxPBB1Du w==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409601" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409601" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875316" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:15 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 10/11] iommu/vt-d: Use device_domain_lock accurately Date: Wed, 6 Jul 2022 10:55:23 +0800 Message-Id: <20220706025524.2904370-11-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.c | 57 +++++++++++++------------------------ 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 899ae63e1ddf..46991e313bf3 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -535,15 +535,8 @@ static int domain_update_device_node(struct dmar_domai= n *domain) struct device_domain_info *info; int nid =3D NUMA_NO_NODE; =20 - assert_spin_locked(&device_domain_lock); - - if (list_empty(&domain->devices)) - return NUMA_NO_NODE; - + spin_lock(&device_domain_lock); 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 +547,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) if (nid !=3D NUMA_NO_NODE) break; } + spin_unlock(&device_domain_lock); =20 return nid; } @@ -1376,23 +1370,23 @@ 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; =20 - assert_spin_locked(&device_domain_lock); - if (!iommu->qi) return NULL; =20 - list_for_each_entry(info, &domain->devices, link) + spin_lock(&device_domain_lock); + 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; - break; + spin_unlock(&device_domain_lock); + return info->ats_supported ? info : NULL; } + } + spin_unlock(&device_domain_lock); =20 return NULL; } @@ -1402,23 +1396,21 @@ static void domain_update_iotlb(struct dmar_domain = *domain) struct device_domain_info *info; bool has_iotlb_device =3D false; =20 - assert_spin_locked(&device_domain_lock); - - list_for_each_entry(info, &domain->devices, link) + spin_lock(&device_domain_lock); + 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(&device_domain_lock); } =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 +1456,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 @@ -1906,9 +1896,10 @@ static int domain_context_mapping_one(struct dmar_do= main *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; int ret; =20 @@ -1922,9 +1913,7 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, =20 BUG_ON(!domain->pgd); =20 - spin_lock(&device_domain_lock); spin_lock(&iommu->lock); - ret =3D -ENOMEM; context =3D iommu_context_addr(iommu, bus, devfn, 1); if (!context) @@ -1975,7 +1964,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) @@ -1998,7 +1986,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 @@ -2044,7 +2031,6 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, =20 out_unlock: spin_unlock(&iommu->lock); - spin_unlock(&device_domain_lock); =20 return ret; } @@ -2456,13 +2442,11 @@ static int domain_add_dev_info(struct dmar_domain *= domain, struct device *dev) if (!iommu) return -ENODEV; =20 - spin_lock(&device_domain_lock); - info->domain =3D domain; ret =3D domain_attach_iommu(domain, iommu); - if (ret) { - spin_unlock(&device_domain_lock); + if (ret) return ret; - } + info->domain =3D domain; + spin_lock(&device_domain_lock); list_add(&info->link, &domain->devices); spin_unlock(&device_domain_lock); =20 @@ -4637,9 +4621,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) if (!domain) return -EINVAL; =20 - spin_lock(&device_domain_lock); spin_lock(&iommu->lock); - ret =3D -EINVAL; if (!info->pasid_supported) goto out; @@ -4669,7 +4651,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) =20 out: spin_unlock(&iommu->lock); - spin_unlock(&device_domain_lock); =20 return ret; } --=20 2.25.1 From nobody Sun Apr 19 05:31:39 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 0D5F3C433EF for ; Wed, 6 Jul 2022 03:01:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231433AbiGFDA5 (ORCPT ); Tue, 5 Jul 2022 23:00:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231620AbiGFDAf (ORCPT ); Tue, 5 Jul 2022 23:00:35 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B87B01C139 for ; Tue, 5 Jul 2022 20:00:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657076422; x=1688612422; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=A7RBb24g7uZ3YBXaYjY6jWSesk0/66f3mKiYAyMbNb8=; b=jwb6Ga3/6P8h8kT44af3YyO0jatwNgnWJV8YpZuwKaU0UBup6BxMNISB H+Iygtjnw+HGFKpddoZimyI4fy7eWy+0gRM1kADbTxWFtaPsDLBcFoIRf CWGOz4tlm+9JXgwol2mQc8srd3cDz6AkMaWn37yn6Tt8G+/HrU80ZJhsu 4BXE0mt7Ld4ELbII+ibOjhDqmFqZrvqvrwTxasGvEtA4CSrLRg8E1gZ+1 YHzqpOvYZ/8quj8FFfVEFTNBA6/jJu0zBJ0syv6Fc1fr+yOgZeT9h7Tv3 DlEpUSkBgjXPD4SW5eVj/gna0hiJ2YcHK8vX4UfaVHLf5HXfvKQL/12or w==; X-IronPort-AV: E=McAfee;i="6400,9594,10399"; a="272409622" X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="272409622" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2022 20:00:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,248,1650956400"; d="scan'208";a="567875365" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 05 Jul 2022 20:00:17 -0700 From: Lu Baolu To: iommu@lists.linux-foundation.org, iommu@lists.linux.dev Cc: Kevin Tian , Ashok Raj , Liu Yi L , Jacob jun Pan , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 11/11] iommu/vt-d: Convert global spinlock into per domain lock Date: Wed, 6 Jul 2022 10:55:24 +0800 Message-Id: <20220706025524.2904370-12-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706025524.2904370-1-baolu.lu@linux.intel.com> References: <20220706025524.2904370-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 Reviewed-by: Kevin Tian --- drivers/iommu/intel/iommu.h | 1 + drivers/iommu/intel/iommu.c | 42 ++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 198c6c822ef4..df64d3d9c49a 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 46991e313bf3..e007049eb9ff 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) @@ -535,7 +534,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) struct device_domain_info *info; int nid =3D NUMA_NO_NODE; =20 - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) { /* * There could possibly be multiple device numa nodes as devices @@ -547,7 +546,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) if (nid !=3D NUMA_NO_NODE) break; } - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); =20 return nid; } @@ -1378,15 +1377,15 @@ iommu_support_dev_iotlb(struct dmar_domain *domain,= struct intel_iommu *iommu, if (!iommu->qi) return NULL; =20 - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) { if (info->iommu =3D=3D iommu && info->bus =3D=3D bus && info->devfn =3D=3D devfn) { - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); return info->ats_supported ? info : NULL; } } - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); =20 return NULL; } @@ -1396,7 +1395,7 @@ static void domain_update_iotlb(struct dmar_domain *d= omain) struct device_domain_info *info; bool has_iotlb_device =3D false; =20 - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) { if (info->ats_enabled) { has_iotlb_device =3D true; @@ -1404,7 +1403,7 @@ static void domain_update_iotlb(struct dmar_domain *d= omain) } } domain->has_iotlb_device =3D has_iotlb_device; - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); } =20 static void iommu_enable_dev_iotlb(struct device_domain_info *info) @@ -1500,10 +1499,10 @@ static void iommu_flush_dev_iotlb(struct dmar_domai= n *domain, if (!domain->has_iotlb_device) return; =20 - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_for_each_entry(info, &domain->devices, link) __iommu_flush_dev_iotlb(info, addr, mask); - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); } =20 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, @@ -1763,6 +1762,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; } @@ -2446,9 +2446,9 @@ static int domain_add_dev_info(struct dmar_domain *do= main, struct device *dev) if (ret) return ret; info->domain =3D domain; - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_add(&info->link, &domain->devices); - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); =20 /* PASID table is mandatory for a PCI device in scalable mode. */ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { @@ -4123,6 +4123,7 @@ static void domain_context_clear(struct device_domain= _info *info) static void dmar_remove_one_dev_info(struct device *dev) { 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; =20 if (!dev_is_real_dma_subdevice(info->dev)) { @@ -4135,11 +4136,11 @@ static void dmar_remove_one_dev_info(struct device = *dev) intel_pasid_free_table(info->dev); } =20 - spin_lock(&device_domain_lock); + spin_lock(&domain->lock); list_del(&info->link); - spin_unlock(&device_domain_lock); + spin_unlock(&domain->lock); =20 - domain_detach_iommu(info->domain, iommu); + domain_detach_iommu(domain, iommu); } =20 static int md_domain_init(struct dmar_domain *domain, int guest_width) @@ -4421,7 +4422,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; @@ -4436,8 +4437,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. @@ -4459,15 +4459,15 @@ static bool intel_iommu_enforce_cache_coherency(str= uct iommu_domain *domain) if (dmar_domain->force_snooping) return true; =20 - spin_lock(&device_domain_lock); + spin_lock(&dmar_domain->lock); if (!domain_support_force_snooping(dmar_domain)) { - spin_unlock(&device_domain_lock); + spin_unlock(&dmar_domain->lock); return false; } =20 domain_set_force_snooping(dmar_domain); dmar_domain->force_snooping =3D true; - spin_unlock(&device_domain_lock); + spin_unlock(&dmar_domain->lock); =20 return true; } --=20 2.25.1