From nobody Mon Jun 29 16:45:19 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 33692C3526E for ; Mon, 7 Feb 2022 07:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241253AbiBGG61 (ORCPT ); Mon, 7 Feb 2022 01:58:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357377AbiBGGoH (ORCPT ); Mon, 7 Feb 2022 01:44:07 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 383B7C043186 for ; Sun, 6 Feb 2022 22:44:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216245; x=1675752245; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ExNa4riMiRn3tJUUnGOWKKokWOZoF/At4lWu1NiLiTc=; b=PhcDjv2aEAAYF+T5obmGcqtyvXkhaziYzxZ0kQuo1YOiush3OBO8AI7F CXqP/AhF13VSGX43BhTI3YngGd4FacGIYSzlsxnHoYzKcPy3mHP4jQrAE zyYp5Nf7Q4eTP96iyNwKHmDxyuEbKioDIiSIzQs04+mipVFKJSSt6ouGL mLvh2vDrDXeoozQ75PxEDOXcYdndEyS4Glr/0b/d9teXUbuI8yrBs3Fog /afvDREhV35gyieuyjXOZaOoEVAprhzlmzOLkik4x/oPm5ZpsBBQO4iMo HvJltiHjJ+j7PyBhANkyn9CFBKAK2rrX6bzqLM6/IBxvpmxmYiUxD04T9 w==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171132" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171132" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020191" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:42:59 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 01/10] iommu/vt-d: Move DMAR specific helpers into dmar.c Date: Mon, 7 Feb 2022 14:41:33 +0800 Message-Id: <20220207064142.1092846-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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" Some ACPI/DMAR specific helpers are defined in iommu.c but used in dmar.c. Move those helpers to the place where they are used. No functional change. Signed-off-by: Lu Baolu --- include/linux/dmar.h | 43 +++++-- drivers/iommu/intel/dmar.c | 216 +++++++++++++++++++++++++++++++- drivers/iommu/intel/iommu.c | 241 +----------------------------------- 3 files changed, 246 insertions(+), 254 deletions(-) diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 45e903d84733..53746cc1efb2 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -52,6 +52,32 @@ struct dmar_drhd_unit { struct intel_iommu *iommu; }; =20 +struct dmar_rmrr_unit { + struct list_head list; /* list of rmrr units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + u64 base_address; /* reserved base address*/ + u64 end_address; /* reserved end address */ + struct dmar_dev_scope *devices; /* target devices */ + int devices_cnt; /* target device count */ +}; + +struct dmar_atsr_unit { + struct list_head list; /* list of ATSR units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + struct dmar_dev_scope *devices; /* target devices */ + int devices_cnt; /* target device count */ + u8 include_all:1; /* include all ports */ +}; + +struct dmar_satc_unit { + struct list_head list; /* list of SATC units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + struct dmar_dev_scope *devices; /* target devices */ + struct intel_iommu *iommu; /* the corresponding iommu */ + int devices_cnt; /* target device count */ + u8 atc_required:1; /* ATS is required */ +}; + struct dmar_pci_path { u8 bus; u8 device; @@ -69,6 +95,9 @@ struct dmar_pci_notify_info { =20 extern struct rw_semaphore dmar_global_lock; extern struct list_head dmar_drhd_units; +extern struct list_head dmar_rmrr_units; +extern struct list_head dmar_atsr_units; +extern struct list_head dmar_satc_units; =20 #define for_each_drhd_unit(drhd) \ list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ @@ -89,6 +118,9 @@ extern struct list_head dmar_drhd_units; dmar_rcu_check()) \ if (i=3Ddrhd->iommu, 0) {} else=20 =20 +#define for_each_rmrr_units(rmrr) \ + list_for_each_entry(rmrr, &dmar_rmrr_units, list) + static inline bool dmar_rcu_check(void) { return rwsem_is_locked(&dmar_global_lock) || @@ -143,23 +175,12 @@ static inline void dmar_fault_dump_ptes(struct intel_= iommu *iommu, u16 source_id extern int iommu_detected, no_iommu; extern int intel_iommu_init(void); extern void intel_iommu_shutdown(void); -extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg); -extern int dmar_parse_one_atsr(struct acpi_dmar_header *header, void *arg); -extern int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg); -extern int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg); -extern int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg); extern int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert); extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); #else /* !CONFIG_INTEL_IOMMU: */ static inline int intel_iommu_init(void) { return -ENODEV; } static inline void intel_iommu_shutdown(void) { } =20 -#define dmar_parse_one_rmrr dmar_res_noop -#define dmar_parse_one_atsr dmar_res_noop -#define dmar_check_one_atsr dmar_res_noop -#define dmar_release_one_atsr dmar_res_noop -#define dmar_parse_one_satc dmar_res_noop - static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info = *info) { return 0; diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index 915bff76fe96..c94decd052f6 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -58,6 +58,9 @@ struct dmar_res_callback { */ DECLARE_RWSEM(dmar_global_lock); LIST_HEAD(dmar_drhd_units); +LIST_HEAD(dmar_rmrr_units); +LIST_HEAD(dmar_atsr_units); +LIST_HEAD(dmar_satc_units); =20 struct acpi_table_header * __initdata dmar_tbl; static int dmar_dev_scope_status =3D 1; @@ -518,8 +521,214 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_heade= r *header, void *arg) #define dmar_parse_one_rhsa dmar_res_noop #endif =20 -static void -dmar_table_print_dmar_entry(struct acpi_dmar_header *header) +#ifdef CONFIG_INTEL_IOMMU +static inline int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) +{ + if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) || + !IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) || + rmrr->end_address <=3D rmrr->base_address || + arch_rmrr_sanity_check(rmrr)) + return -EINVAL; + + return 0; +} + +static int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, voi= d *arg) +{ + struct acpi_dmar_reserved_memory *rmrr; + struct dmar_rmrr_unit *rmrru; + + rmrr =3D (struct acpi_dmar_reserved_memory *)header; + if (rmrr_sanity_check(rmrr)) { + pr_warn(FW_BUG + "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + rmrr->base_address, rmrr->end_address, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + } + + rmrru =3D kzalloc(sizeof(*rmrru), GFP_KERNEL); + if (!rmrru) + goto out; + + rmrru->hdr =3D header; + rmrru->base_address =3D rmrr->base_address; + rmrru->end_address =3D rmrr->end_address; + rmrru->devices =3D dmar_alloc_dev_scope((void *)(rmrr + 1), + ((void *)rmrr) + rmrr->header.length, + &rmrru->devices_cnt); + + if (rmrru->devices_cnt && !rmrru->devices) + goto free_rmrru; + + list_add(&rmrru->list, &dmar_rmrr_units); + + return 0; +free_rmrru: + kfree(rmrru); +out: + return -ENOMEM; +} + +static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr) +{ + struct dmar_atsr_unit *atsru; + struct acpi_dmar_atsr *tmp; + + list_for_each_entry_rcu(atsru, &dmar_atsr_units, list, + dmar_rcu_check()) { + tmp =3D (struct acpi_dmar_atsr *)atsru->hdr; + if (atsr->segment !=3D tmp->segment) + continue; + if (atsr->header.length !=3D tmp->header.length) + continue; + if (memcmp(atsr, tmp, atsr->header.length) =3D=3D 0) + return atsru; + } + + return NULL; +} + +static int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg) +{ + struct acpi_dmar_atsr *atsr; + struct dmar_atsr_unit *atsru; + + if (system_state >=3D SYSTEM_RUNNING && !intel_iommu_enabled) + return 0; + + atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); + atsru =3D dmar_find_atsr(atsr); + if (atsru) + return 0; + + atsru =3D kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL); + if (!atsru) + return -ENOMEM; + + /* + * If memory is allocated from slab by ACPI _DSM method, we need to + * copy the memory content because the memory buffer will be freed + * on return. + */ + atsru->hdr =3D (void *)(atsru + 1); + memcpy(atsru->hdr, hdr, hdr->length); + atsru->include_all =3D atsr->flags & 0x1; + if (!atsru->include_all) { + atsru->devices =3D dmar_alloc_dev_scope((void *)(atsr + 1), + (void *)atsr + atsr->header.length, + &atsru->devices_cnt); + if (atsru->devices_cnt && !atsru->devices) { + kfree(atsru); + return -ENOMEM; + } + } + + list_add_rcu(&atsru->list, &dmar_atsr_units); + + return 0; +} + +static int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg) +{ + struct acpi_dmar_atsr *atsr; + struct dmar_atsr_unit *atsru; + + atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); + atsru =3D dmar_find_atsr(atsr); + if (atsru) { + list_del_rcu(&atsru->list); + synchronize_rcu(); + dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt); + kfree(atsru); + } + + return 0; +} + +static int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg) +{ + int i; + struct device *dev; + struct acpi_dmar_atsr *atsr; + struct dmar_atsr_unit *atsru; + + atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); + atsru =3D dmar_find_atsr(atsr); + if (!atsru) + return 0; + + if (!atsru->include_all && atsru->devices && atsru->devices_cnt) { + for_each_active_dev_scope(atsru->devices, atsru->devices_cnt, + i, dev) + return -EBUSY; + } + + return 0; +} + +static struct dmar_satc_unit *dmar_find_satc(struct acpi_dmar_satc *satc) +{ + struct dmar_satc_unit *satcu; + struct acpi_dmar_satc *tmp; + + list_for_each_entry_rcu(satcu, &dmar_satc_units, list, + dmar_rcu_check()) { + tmp =3D (struct acpi_dmar_satc *)satcu->hdr; + if (satc->segment !=3D tmp->segment) + continue; + if (satc->header.length !=3D tmp->header.length) + continue; + if (memcmp(satc, tmp, satc->header.length) =3D=3D 0) + return satcu; + } + + return NULL; +} + +static int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg) +{ + struct acpi_dmar_satc *satc; + struct dmar_satc_unit *satcu; + + if (system_state >=3D SYSTEM_RUNNING && !intel_iommu_enabled) + return 0; + + satc =3D container_of(hdr, struct acpi_dmar_satc, header); + satcu =3D dmar_find_satc(satc); + if (satcu) + return 0; + + satcu =3D kzalloc(sizeof(*satcu) + hdr->length, GFP_KERNEL); + if (!satcu) + return -ENOMEM; + + satcu->hdr =3D (void *)(satcu + 1); + memcpy(satcu->hdr, hdr, hdr->length); + satcu->atc_required =3D satc->flags & 0x1; + satcu->devices =3D dmar_alloc_dev_scope((void *)(satc + 1), + (void *)satc + satc->header.length, + &satcu->devices_cnt); + if (satcu->devices_cnt && !satcu->devices) { + kfree(satcu); + return -ENOMEM; + } + list_add_rcu(&satcu->list, &dmar_satc_units); + + return 0; +} +#else /* !CONFIG_INTEL_IOMMU: */ +#define dmar_parse_one_rmrr dmar_res_noop +#define dmar_parse_one_atsr dmar_res_noop +#define dmar_check_one_atsr dmar_res_noop +#define dmar_release_one_atsr dmar_res_noop +#define dmar_parse_one_satc dmar_res_noop +#endif + +static void dmar_table_print_dmar_entry(struct acpi_dmar_header *header) { struct acpi_dmar_hardware_unit *drhd; struct acpi_dmar_reserved_memory *rmrr; @@ -631,8 +840,7 @@ static inline int dmar_walk_dmar_table(struct acpi_tabl= e_dmar *dmar, /** * parse_dmar_table - parses the DMA reporting table */ -static int __init -parse_dmar_table(void) +static int __init parse_dmar_table(void) { struct acpi_table_dmar *dmar; int drhd_count =3D 0; diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index b549172e88ef..3eb914798c18 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -280,39 +280,6 @@ static int hw_pass_through =3D 1; for (idx =3D 0; idx < g_num_of_iommus; idx++) \ if (domain->iommu_refcnt[idx]) =20 -struct dmar_rmrr_unit { - struct list_head list; /* list of rmrr units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - u64 base_address; /* reserved base address*/ - u64 end_address; /* reserved end address */ - struct dmar_dev_scope *devices; /* target devices */ - int devices_cnt; /* target device count */ -}; - -struct dmar_atsr_unit { - struct list_head list; /* list of ATSR units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - struct dmar_dev_scope *devices; /* target devices */ - int devices_cnt; /* target device count */ - u8 include_all:1; /* include all ports */ -}; - -struct dmar_satc_unit { - struct list_head list; /* list of SATC units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - struct dmar_dev_scope *devices; /* target devices */ - struct intel_iommu *iommu; /* the corresponding iommu */ - int devices_cnt; /* target device count */ - u8 atc_required:1; /* ATS is required */ -}; - -static LIST_HEAD(dmar_atsr_units); -static LIST_HEAD(dmar_rmrr_units); -static LIST_HEAD(dmar_satc_units); - -#define for_each_rmrr_units(rmrr) \ - list_for_each_entry(rmrr, &dmar_rmrr_units, list) - /* bitmap for indexing intel_iommus */ static int g_num_of_iommus; =20 @@ -3657,211 +3624,6 @@ static void __init init_iommu_pm_ops(void) static inline void init_iommu_pm_ops(void) {} #endif /* CONFIG_PM */ =20 -static int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) -{ - if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) || - !IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) || - rmrr->end_address <=3D rmrr->base_address || - arch_rmrr_sanity_check(rmrr)) - return -EINVAL; - - return 0; -} - -int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) -{ - struct acpi_dmar_reserved_memory *rmrr; - struct dmar_rmrr_unit *rmrru; - - rmrr =3D (struct acpi_dmar_reserved_memory *)header; - if (rmrr_sanity_check(rmrr)) { - pr_warn(FW_BUG - "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - rmrr->base_address, rmrr->end_address, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); - add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); - } - - rmrru =3D kzalloc(sizeof(*rmrru), GFP_KERNEL); - if (!rmrru) - goto out; - - rmrru->hdr =3D header; - - rmrru->base_address =3D rmrr->base_address; - rmrru->end_address =3D rmrr->end_address; - - rmrru->devices =3D dmar_alloc_dev_scope((void *)(rmrr + 1), - ((void *)rmrr) + rmrr->header.length, - &rmrru->devices_cnt); - if (rmrru->devices_cnt && rmrru->devices =3D=3D NULL) - goto free_rmrru; - - list_add(&rmrru->list, &dmar_rmrr_units); - - return 0; -free_rmrru: - kfree(rmrru); -out: - return -ENOMEM; -} - -static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr) -{ - struct dmar_atsr_unit *atsru; - struct acpi_dmar_atsr *tmp; - - list_for_each_entry_rcu(atsru, &dmar_atsr_units, list, - dmar_rcu_check()) { - tmp =3D (struct acpi_dmar_atsr *)atsru->hdr; - if (atsr->segment !=3D tmp->segment) - continue; - if (atsr->header.length !=3D tmp->header.length) - continue; - if (memcmp(atsr, tmp, atsr->header.length) =3D=3D 0) - return atsru; - } - - return NULL; -} - -int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg) -{ - struct acpi_dmar_atsr *atsr; - struct dmar_atsr_unit *atsru; - - if (system_state >=3D SYSTEM_RUNNING && !intel_iommu_enabled) - return 0; - - atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); - atsru =3D dmar_find_atsr(atsr); - if (atsru) - return 0; - - atsru =3D kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL); - if (!atsru) - return -ENOMEM; - - /* - * If memory is allocated from slab by ACPI _DSM method, we need to - * copy the memory content because the memory buffer will be freed - * on return. - */ - atsru->hdr =3D (void *)(atsru + 1); - memcpy(atsru->hdr, hdr, hdr->length); - atsru->include_all =3D atsr->flags & 0x1; - if (!atsru->include_all) { - atsru->devices =3D dmar_alloc_dev_scope((void *)(atsr + 1), - (void *)atsr + atsr->header.length, - &atsru->devices_cnt); - if (atsru->devices_cnt && atsru->devices =3D=3D NULL) { - kfree(atsru); - return -ENOMEM; - } - } - - list_add_rcu(&atsru->list, &dmar_atsr_units); - - return 0; -} - -static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru) -{ - dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt); - kfree(atsru); -} - -int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg) -{ - struct acpi_dmar_atsr *atsr; - struct dmar_atsr_unit *atsru; - - atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); - atsru =3D dmar_find_atsr(atsr); - if (atsru) { - list_del_rcu(&atsru->list); - synchronize_rcu(); - intel_iommu_free_atsr(atsru); - } - - return 0; -} - -int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg) -{ - int i; - struct device *dev; - struct acpi_dmar_atsr *atsr; - struct dmar_atsr_unit *atsru; - - atsr =3D container_of(hdr, struct acpi_dmar_atsr, header); - atsru =3D dmar_find_atsr(atsr); - if (!atsru) - return 0; - - if (!atsru->include_all && atsru->devices && atsru->devices_cnt) { - for_each_active_dev_scope(atsru->devices, atsru->devices_cnt, - i, dev) - return -EBUSY; - } - - return 0; -} - -static struct dmar_satc_unit *dmar_find_satc(struct acpi_dmar_satc *satc) -{ - struct dmar_satc_unit *satcu; - struct acpi_dmar_satc *tmp; - - list_for_each_entry_rcu(satcu, &dmar_satc_units, list, - dmar_rcu_check()) { - tmp =3D (struct acpi_dmar_satc *)satcu->hdr; - if (satc->segment !=3D tmp->segment) - continue; - if (satc->header.length !=3D tmp->header.length) - continue; - if (memcmp(satc, tmp, satc->header.length) =3D=3D 0) - return satcu; - } - - return NULL; -} - -int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg) -{ - struct acpi_dmar_satc *satc; - struct dmar_satc_unit *satcu; - - if (system_state >=3D SYSTEM_RUNNING && !intel_iommu_enabled) - return 0; - - satc =3D container_of(hdr, struct acpi_dmar_satc, header); - satcu =3D dmar_find_satc(satc); - if (satcu) - return 0; - - satcu =3D kzalloc(sizeof(*satcu) + hdr->length, GFP_KERNEL); - if (!satcu) - return -ENOMEM; - - satcu->hdr =3D (void *)(satcu + 1); - memcpy(satcu->hdr, hdr, hdr->length); - satcu->atc_required =3D satc->flags & 0x1; - satcu->devices =3D dmar_alloc_dev_scope((void *)(satc + 1), - (void *)satc + satc->header.length, - &satcu->devices_cnt); - if (satcu->devices_cnt && !satcu->devices) { - kfree(satcu); - return -ENOMEM; - } - list_add_rcu(&satcu->list, &dmar_satc_units); - - return 0; -} - static int intel_iommu_add(struct dmar_drhd_unit *dmaru) { int sp, ret; @@ -3977,7 +3739,8 @@ static void intel_iommu_free_dmars(void) =20 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) { list_del(&atsru->list); - intel_iommu_free_atsr(atsru); + dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt); + kfree(atsru); } list_for_each_entry_safe(satcu, satc_n, &dmar_satc_units, list) { list_del(&satcu->list); --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 20D0FC433FE for ; Mon, 7 Feb 2022 07:02:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242317AbiBGG6u (ORCPT ); Mon, 7 Feb 2022 01:58:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357550AbiBGGoK (ORCPT ); Mon, 7 Feb 2022 01:44:10 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 246A9C043184 for ; Sun, 6 Feb 2022 22:44:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216248; x=1675752248; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gN3LPgLC7pbNU4whlKOywLY30HbjfL0dlgHdNEPYbiE=; b=WdzNyDVxvIcYeLG/AE8OISq3HBw4/XL6wyaskn7ibPNvuNOSWlxdCZJB ZFohdG5uKpSW79bo9xNaB2R2ri1niPfNeV30dA7kO21Cg4wGncaWM0fJu YQWngFac7HuJohF2o28VdhILX69FSOvzxcEZra4gpGOeotOszZ0hV0a88 n0/2PX8lG4yWsx8XsKmqF6MWyHs8+h9g8PE949zkNrpeWfk/QGanvSupd SAIFEj3QDbTdk2dTUSzNlLMnSeskpCiDwWVLur3ivfzb7NO0tBpKVGOzy TqdMupVMIO0T95DEMSxoQDRK2/Xh0aEdhkoiLYZKTg9C27gAE/xsscIpq Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171143" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171143" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020204" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:03 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 02/10] iommu/vt-d: Remove intel_iommu::domains Date: Mon, 7 Feb 2022 14:41:34 +0800 Message-Id: <20220207064142.1092846-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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 "domains" field of the intel_iommu structure keeps the mapping of domain_id to dmar_domain. This information is not used anywhere. Remove and cleanup it to avoid unnecessary memory consumption. Signed-off-by: Lu Baolu Reviewed-by: Christoph Hellwig --- include/linux/intel-iommu.h | 1 - drivers/iommu/intel/iommu.c | 68 ++----------------------------------- 2 files changed, 3 insertions(+), 66 deletions(-) diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 5cfda90b2cca..8c7591b5f3e2 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -578,7 +578,6 @@ struct intel_iommu { =20 #ifdef CONFIG_INTEL_IOMMU unsigned long *domain_ids; /* bitmap of domains */ - struct dmar_domain ***domains; /* ptr to domains */ spinlock_t lock; /* protect context, domain ids */ struct root_entry *root_entry; /* virtual address */ =20 diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 3eb914798c18..438da5da301d 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -422,36 +422,6 @@ __setup("intel_iommu=3D", intel_iommu_setup); static struct kmem_cache *iommu_domain_cache; static struct kmem_cache *iommu_devinfo_cache; =20 -static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16= did) -{ - struct dmar_domain **domains; - int idx =3D did >> 8; - - domains =3D iommu->domains[idx]; - if (!domains) - return NULL; - - return domains[did & 0xff]; -} - -static void set_iommu_domain(struct intel_iommu *iommu, u16 did, - struct dmar_domain *domain) -{ - struct dmar_domain **domains; - int idx =3D did >> 8; - - if (!iommu->domains[idx]) { - size_t size =3D 256 * sizeof(struct dmar_domain *); - iommu->domains[idx] =3D kzalloc(size, GFP_ATOMIC); - } - - domains =3D iommu->domains[idx]; - if (WARN_ON(!domains)) - return; - else - domains[did & 0xff] =3D domain; -} - void *alloc_pgtable_page(int node) { struct page *page; @@ -1718,8 +1688,7 @@ static void intel_flush_iotlb_all(struct iommu_domain= *domain) DMA_TLB_DSI_FLUSH); =20 if (!cap_caching_mode(iommu->cap)) - iommu_flush_dev_iotlb(get_iommu_domain(iommu, did), - 0, MAX_AGAW_PFN_WIDTH); + iommu_flush_dev_iotlb(dmar_domain, 0, MAX_AGAW_PFN_WIDTH); } } =20 @@ -1782,7 +1751,6 @@ static void iommu_disable_translation(struct intel_io= mmu *iommu) static int iommu_init_domains(struct intel_iommu *iommu) { u32 ndomains; - size_t size; =20 ndomains =3D cap_ndoms(iommu->cap); pr_debug("%s: Number of Domains supported <%d>\n", @@ -1794,24 +1762,6 @@ static int iommu_init_domains(struct intel_iommu *io= mmu) if (!iommu->domain_ids) return -ENOMEM; =20 - size =3D (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **); - iommu->domains =3D kzalloc(size, GFP_KERNEL); - - if (iommu->domains) { - size =3D 256 * sizeof(struct dmar_domain *); - iommu->domains[0] =3D kzalloc(size, GFP_KERNEL); - } - - if (!iommu->domains || !iommu->domains[0]) { - pr_err("%s: Allocating domain array failed\n", - iommu->name); - bitmap_free(iommu->domain_ids); - kfree(iommu->domains); - iommu->domain_ids =3D NULL; - iommu->domains =3D NULL; - return -ENOMEM; - } - /* * If Caching mode is set, then invalid translations are tagged * with domain-id 0, hence we need to pre-allocate it. We also @@ -1838,7 +1788,7 @@ static void disable_dmar_iommu(struct intel_iommu *io= mmu) struct device_domain_info *info, *tmp; unsigned long flags; =20 - if (!iommu->domains || !iommu->domain_ids) + if (!iommu->domain_ids) return; =20 spin_lock_irqsave(&device_domain_lock, flags); @@ -1859,15 +1809,8 @@ static void disable_dmar_iommu(struct intel_iommu *i= ommu) =20 static void free_dmar_iommu(struct intel_iommu *iommu) { - if ((iommu->domains) && (iommu->domain_ids)) { - int elems =3D ALIGN(cap_ndoms(iommu->cap), 256) >> 8; - int i; - - for (i =3D 0; i < elems; i++) - kfree(iommu->domains[i]); - kfree(iommu->domains); + if (iommu->domain_ids) { bitmap_free(iommu->domain_ids); - iommu->domains =3D NULL; iommu->domain_ids =3D NULL; } =20 @@ -1945,11 +1888,8 @@ static int domain_attach_iommu(struct dmar_domain *d= omain, } =20 set_bit(num, iommu->domain_ids); - set_iommu_domain(iommu, num, domain); - domain->iommu_did[iommu->seq_id] =3D num; domain->nid =3D iommu->node; - domain_update_iommu_cap(domain); } =20 @@ -1968,8 +1908,6 @@ static void domain_detach_iommu(struct dmar_domain *d= omain, if (domain->iommu_refcnt[iommu->seq_id] =3D=3D 0) { num =3D domain->iommu_did[iommu->seq_id]; clear_bit(num, iommu->domain_ids); - set_iommu_domain(iommu, num, NULL); - domain_update_iommu_cap(domain); domain->iommu_did[iommu->seq_id] =3D 0; } --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 BC5CCC4167B for ; Mon, 7 Feb 2022 07:00:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240306AbiBGG6D (ORCPT ); Mon, 7 Feb 2022 01:58:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357613AbiBGGoL (ORCPT ); Mon, 7 Feb 2022 01:44:11 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27545C043185 for ; Sun, 6 Feb 2022 22:44:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216251; x=1675752251; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OKL1r6Isxh5NwGJDUX9vHjv6BhHF7fJWfzI6cLdyIuo=; b=EC6qW772MgTnnPlVoXLbpJIERfhMdQfQRjnfH06CmdHPorWNffIuUPL7 qqV1PxSgqH42lbAXyQ7S61NtloynrudiBlp3tQO0EUSqPQDOQn5W4LXNd YaxSQH8BM5mU2CX2eAwzMP36h9yxdidJFNLOcYFoRX5SKuHu0ZJdlpyJH oXrahmAtjVWdAGqaNP2TsPgpCA6v1f7FhpqTqAgDeDprNo/kq1YMlyACB baIsvoaT816wq6cXKldNdqu7y4PDStNW/EmQtPbNM8sHEjmklMG7OD1In VsZxfcgvgDu7EJYMIPrGxDvwpwcD0/GVDweFijaDk0c09h2zIL66ZugQe w==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171153" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171153" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020221" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:06 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 03/10] iommu/vt-d: Remove finding domain in dmar_insert_one_dev_info() Date: Mon, 7 Feb 2022 14:41:35 +0800 Message-Id: <20220207064142.1092846-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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 Intel IOMMU driver has already converted to use default domain framework in iommu core. There's no need to find a domain for the device in the domain attaching path. Cleanup that code. Signed-off-by: Lu Baolu Reviewed-by: Christoph Hellwig --- drivers/iommu/intel/iommu.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 438da5da301d..583ec0fa4ac1 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2521,7 +2521,6 @@ static struct dmar_domain *dmar_insert_one_dev_info(s= truct intel_iommu *iommu, struct device *dev, struct dmar_domain *domain) { - struct dmar_domain *found =3D NULL; struct device_domain_info *info; unsigned long flags; int ret; @@ -2572,26 +2571,6 @@ static struct dmar_domain *dmar_insert_one_dev_info(= struct intel_iommu *iommu, } =20 spin_lock_irqsave(&device_domain_lock, flags); - if (dev) - found =3D find_domain(dev); - - if (!found) { - struct device_domain_info *info2; - info2 =3D dmar_search_domain_by_dev_info(info->segment, info->bus, - info->devfn); - if (info2) { - found =3D info2->domain; - info2->dev =3D dev; - } - } - - if (found) { - spin_unlock_irqrestore(&device_domain_lock, flags); - free_devinfo_mem(info); - /* Caller must free the original domain */ - return found; - } - spin_lock(&iommu->lock); ret =3D domain_attach_iommu(domain, iommu); spin_unlock(&iommu->lock); --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 9224EC43217 for ; Mon, 7 Feb 2022 07:00:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239806AbiBGG55 (ORCPT ); Mon, 7 Feb 2022 01:57:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357739AbiBGGoP (ORCPT ); Mon, 7 Feb 2022 01:44:15 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CF4CC043188 for ; Sun, 6 Feb 2022 22:44:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216254; x=1675752254; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fIEVBkJiUooXYrTSIvBLA7Ijyh2xdWSYljcHg0SF2/8=; b=CYMTGuSZAy7BPqeglBCqaG3fZeJVxe9erk+C/u72W3O7nWwswXy2JaDV 1NSEhXfU5WPBlVyN9icVaSTyqyvN/dTJkzwkLTCdlmN04T3f+gp6Vk81f ryHpz5cyEbKhMjB4aQLRit/upezwbgTgm4dMQGYgUnekFCrI2ZHRJl/6/ AdAhaUGkuLcwsacAOrtzRhlIou52U1aOohJ8AI4blhIuv754b5h9Ok1Wg axDTx5gx9WPAZzaBSw/GuPLdvGk0I6H1lx9cMoJhLzLKKRPZ/Vzn9ZQc/ 90HPmft4tsLcsVIVopIzwTRq5cPDheSJl2v70kWSUHbgT54S1EG7VLPZp Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171167" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171167" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020245" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:09 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 04/10] iommu/vt-d: Remove iova_cache_get/put() Date: Mon, 7 Feb 2022 14:41:36 +0800 Message-Id: <20220207064142.1092846-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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" These have been done in drivers/iommu/dma-iommu.c. Remove this duplicate code. Signed-off-by: Lu Baolu Reviewed-by: Christoph Hellwig --- drivers/iommu/intel/iommu.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 583ec0fa4ac1..e8d58654361c 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -3348,9 +3348,6 @@ static inline int iommu_devinfo_cache_init(void) static int __init iommu_init_mempool(void) { int ret; - ret =3D iova_cache_get(); - if (ret) - return ret; =20 ret =3D iommu_domain_cache_init(); if (ret) @@ -3362,7 +3359,6 @@ static int __init iommu_init_mempool(void) =20 kmem_cache_destroy(iommu_domain_cache); domain_error: - iova_cache_put(); =20 return -ENOMEM; } @@ -3371,7 +3367,6 @@ static void __init iommu_exit_mempool(void) { kmem_cache_destroy(iommu_devinfo_cache); kmem_cache_destroy(iommu_domain_cache); - iova_cache_put(); } =20 static void __init init_no_remapping_devices(void) --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 63D9CC43219 for ; Mon, 7 Feb 2022 07:02:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242953AbiBGG7E (ORCPT ); Mon, 7 Feb 2022 01:59:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357819AbiBGGoS (ORCPT ); Mon, 7 Feb 2022 01:44:18 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A163C043189 for ; Sun, 6 Feb 2022 22:44:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216257; x=1675752257; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UGmKiwSdYRMedpHT9dtqUe3n0EwJaj3PL5+dZ3oF/ac=; b=LZBZJwpcDc3l5PXJx2MLvgU5XPO6LCtrT1FO+cs6fNRixuJrVp8EEpeB wbGipXBL3nL9tnbRu6BLnDshFGapkJmGBEr7ghQxrKn6sNz6cKTqxPjah bhnsV3Qa4x+jywYoLtyn7TTGzJf2jjtxwbO2wHzl0isllmiYmKrAEprhk o5qBNXbu6jzNgR2BtjF9PdItXdCq0Q9Kw7q/151xcR2xDyPehJ6tSrq6Y +8BLX7Mxdo48P4rqx5c6Q7yLYjrhX3mb///7oDh4lcmSRj54CwwB14zcK vxsQ/Vl/htWvENnZOB/P84E79mNjCqwCX76ESlTTGmGj1KSuJXk4zKSR4 w==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171180" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171180" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020263" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:12 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 05/10] iommu/vt-d: Remove domain and devinfo mempool Date: Mon, 7 Feb 2022 14:41:37 +0800 Message-Id: <20220207064142.1092846-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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 and devinfo memory blocks are only allocated during device probe and released during remove. There's no hot-path context, hence no need for memory pools. Signed-off-by: Lu Baolu Reviewed-by: Christoph Hellwig --- drivers/iommu/intel/iommu.c | 104 ++---------------------------------- 1 file changed, 5 insertions(+), 99 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index e8d58654361c..185aa38df602 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -419,9 +419,6 @@ static int __init intel_iommu_setup(char *str) } __setup("intel_iommu=3D", intel_iommu_setup); =20 -static struct kmem_cache *iommu_domain_cache; -static struct kmem_cache *iommu_devinfo_cache; - void *alloc_pgtable_page(int node) { struct page *page; @@ -438,26 +435,6 @@ void free_pgtable_page(void *vaddr) free_page((unsigned long)vaddr); } =20 -static inline void *alloc_domain_mem(void) -{ - return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC); -} - -static void free_domain_mem(void *vaddr) -{ - kmem_cache_free(iommu_domain_cache, vaddr); -} - -static inline void * alloc_devinfo_mem(void) -{ - return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC); -} - -static inline void free_devinfo_mem(void *vaddr) -{ - kmem_cache_free(iommu_devinfo_cache, vaddr); -} - static inline int domain_type_is_si(struct dmar_domain *domain) { return domain->domain.type =3D=3D IOMMU_DOMAIN_IDENTITY; @@ -1852,11 +1829,10 @@ static struct dmar_domain *alloc_domain(unsigned in= t type) { struct dmar_domain *domain; =20 - domain =3D alloc_domain_mem(); + domain =3D kzalloc(sizeof(*domain), GFP_KERNEL); if (!domain) return NULL; =20 - memset(domain, 0, sizeof(*domain)); domain->nid =3D NUMA_NO_NODE; if (first_level_by_default(type)) domain->flags |=3D DOMAIN_FLAG_USE_FIRST_LEVEL; @@ -1940,7 +1916,7 @@ static void domain_exit(struct dmar_domain *domain) put_pages_list(&freelist); } =20 - free_domain_mem(domain); + kfree(domain); } =20 /* @@ -2525,7 +2501,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(s= truct intel_iommu *iommu, unsigned long flags; int ret; =20 - info =3D alloc_devinfo_mem(); + info =3D kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return NULL; =20 @@ -2541,13 +2517,9 @@ static struct dmar_domain *dmar_insert_one_dev_info(= struct intel_iommu *iommu, info->segment =3D pci_domain_nr(pdev->bus); } =20 - info->ats_supported =3D info->pasid_supported =3D info->pri_supported =3D= 0; - info->ats_enabled =3D info->pasid_enabled =3D info->pri_enabled =3D 0; - info->ats_qdep =3D 0; info->dev =3D dev; info->domain =3D domain; info->iommu =3D iommu; - info->pasid_table =3D NULL; =20 if (dev && dev_is_pci(dev)) { struct pci_dev *pdev =3D to_pci_dev(info->dev); @@ -2577,7 +2549,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(s= truct intel_iommu *iommu, =20 if (ret) { spin_unlock_irqrestore(&device_domain_lock, flags); - free_devinfo_mem(info); + kfree(info); return NULL; } =20 @@ -3310,65 +3282,6 @@ static int __init init_dmars(void) return ret; } =20 -static inline int iommu_domain_cache_init(void) -{ - int ret =3D 0; - - iommu_domain_cache =3D kmem_cache_create("iommu_domain", - sizeof(struct dmar_domain), - 0, - SLAB_HWCACHE_ALIGN, - - NULL); - if (!iommu_domain_cache) { - pr_err("Couldn't create iommu_domain cache\n"); - ret =3D -ENOMEM; - } - - return ret; -} - -static inline int iommu_devinfo_cache_init(void) -{ - int ret =3D 0; - - iommu_devinfo_cache =3D kmem_cache_create("iommu_devinfo", - sizeof(struct device_domain_info), - 0, - SLAB_HWCACHE_ALIGN, - NULL); - if (!iommu_devinfo_cache) { - pr_err("Couldn't create devinfo cache\n"); - ret =3D -ENOMEM; - } - - return ret; -} - -static int __init iommu_init_mempool(void) -{ - int ret; - - ret =3D iommu_domain_cache_init(); - if (ret) - goto domain_error; - - ret =3D iommu_devinfo_cache_init(); - if (!ret) - return ret; - - kmem_cache_destroy(iommu_domain_cache); -domain_error: - - return -ENOMEM; -} - -static void __init iommu_exit_mempool(void) -{ - kmem_cache_destroy(iommu_devinfo_cache); - kmem_cache_destroy(iommu_domain_cache); -} - static void __init init_no_remapping_devices(void) { struct dmar_drhd_unit *drhd; @@ -4016,12 +3929,6 @@ int __init intel_iommu_init(void) force_on =3D (!intel_iommu_tboot_noforce && tboot_force_iommu()) || platform_optin_force_iommu(); =20 - if (iommu_init_mempool()) { - if (force_on) - panic("tboot: Failed to initialize iommu memory\n"); - return -ENOMEM; - } - down_write(&dmar_global_lock); if (dmar_table_init()) { if (force_on) @@ -4142,7 +4049,6 @@ int __init intel_iommu_init(void) out_free_dmar: intel_iommu_free_dmars(); up_write(&dmar_global_lock); - iommu_exit_mempool(); return ret; } =20 @@ -4199,7 +4105,7 @@ static void __dmar_remove_one_dev_info(struct device_= domain_info *info) domain_detach_iommu(domain, iommu); spin_unlock_irqrestore(&iommu->lock, flags); =20 - free_devinfo_mem(info); + kfree(info); } =20 static void dmar_remove_one_dev_info(struct device *dev) --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 620DFC4332F for ; Mon, 7 Feb 2022 07:00:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239513AbiBGG5x (ORCPT ); Mon, 7 Feb 2022 01:57:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357835AbiBGGoU (ORCPT ); Mon, 7 Feb 2022 01:44:20 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 363C6C043187 for ; Sun, 6 Feb 2022 22:44:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216260; x=1675752260; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6WtSTQdjRD4wi8NPB/wH0EeILHtZl3dydvFj3GNNpHk=; b=NN1f/sPU7usXw7MPT8L/xf2ghf2katrlmVLV9jMGZA8jsLc/nZv3e6XS wm46sgJ+PQdCK1gTtNRtG9VUVDpML+NG3l0lM08d4Vh5XrplyWrkgwAdf 2DlqqH0LTjvuxIfD0HlO677bXEUNkuVOG6vP9AH0J0IeoZ0FFEGL/YVKP WdQ8wDHDHCjIM7BM2usf2NRGa89gZ2sNohWyx6i6LbMaovynBEgJQ1hjR CLU7Hxrv69BWoZtZ9KbCkeXc+Gj2ZFrrUvOVupy/RhKwnets5KtyWqL9M 37h9i8zfREJ7a67sOCQ2XIXEXXpmjDIRAeZWqqNq8sSTX/2jboFAd69NB w==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171187" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171187" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020280" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:15 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 06/10] iommu/vt-d: Remove DEFER_DEVICE_DOMAIN_INFO Date: Mon, 7 Feb 2022 14:41:38 +0800 Message-Id: <20220207064142.1092846-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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" Allocate and set the per-device iommu private data during iommu device probe. Add a flag to indicate whether default domain attachment is deferred. With this refactoring, the dummy DEFER_DEVICE_DOMAIN_INFO pointer is removed. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 122 +++++++++++++++--------------------- 1 file changed, 51 insertions(+), 71 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 185aa38df602..165c890b8304 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -309,19 +309,9 @@ static int iommu_skip_te_disable; int intel_iommu_gfx_mapped; EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); =20 -#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2)) struct device_domain_info *get_domain_info(struct device *dev) { - struct device_domain_info *info; - - if (!dev) - return NULL; - - info =3D dev_iommu_priv_get(dev); - if (unlikely(info =3D=3D DEFER_DEVICE_DOMAIN_INFO)) - return NULL; - - return info; + return dev_iommu_priv_get(dev); } =20 DEFINE_SPINLOCK(device_domain_lock); @@ -708,11 +698,6 @@ struct context_entry *iommu_context_addr(struct intel_= iommu *iommu, u8 bus, return &context[devfn]; } =20 -static bool attach_deferred(struct device *dev) -{ - return dev_iommu_priv_get(dev) =3D=3D DEFER_DEVICE_DOMAIN_INFO; -} - /** * is_downstream_to_pci_bridge - test if a device belongs to the PCI * sub-hierarchy of a candidate PCI-PCI bridge @@ -2426,9 +2411,6 @@ struct dmar_domain *find_domain(struct device *dev) if (unlikely(!dev || !dev->iommu)) return NULL; =20 - if (unlikely(attach_deferred(dev))) - return NULL; - /* No lock here, assumes no domain exit in normal case */ info =3D get_domain_info(dev); if (likely(info)) @@ -2497,66 +2479,20 @@ static struct dmar_domain *dmar_insert_one_dev_info= (struct intel_iommu *iommu, struct device *dev, struct dmar_domain *domain) { - struct device_domain_info *info; + struct device_domain_info *info =3D get_domain_info(dev); unsigned long flags; int ret; =20 - info =3D kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return NULL; - - if (!dev_is_real_dma_subdevice(dev)) { - info->bus =3D bus; - info->devfn =3D devfn; - info->segment =3D iommu->segment; - } else { - struct pci_dev *pdev =3D to_pci_dev(dev); - - info->bus =3D pdev->bus->number; - info->devfn =3D pdev->devfn; - info->segment =3D pci_domain_nr(pdev->bus); - } - - info->dev =3D dev; - info->domain =3D domain; - info->iommu =3D iommu; - - if (dev && dev_is_pci(dev)) { - struct pci_dev *pdev =3D to_pci_dev(info->dev); - - if (ecap_dev_iotlb_support(iommu->ecap) && - pci_ats_supported(pdev) && - dmar_find_matched_atsr_unit(pdev)) - info->ats_supported =3D 1; - - if (sm_supported(iommu)) { - if (pasid_supported(iommu)) { - int features =3D pci_pasid_features(pdev); - if (features >=3D 0) - info->pasid_supported =3D features | 1; - } - - if (info->ats_supported && ecap_prs(iommu->ecap) && - pci_pri_supported(pdev)) - info->pri_supported =3D 1; - } - } - 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); - kfree(info); return NULL; } - list_add(&info->link, &domain->devices); - list_add(&info->global, &device_domain_list); - if (dev) - dev_iommu_priv_set(dev, info); spin_unlock_irqrestore(&device_domain_lock, flags); =20 /* PASID table is mandatory for a PCI device in scalable mode. */ @@ -4405,14 +4341,56 @@ static bool intel_iommu_capable(enum iommu_cap cap) =20 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, NULL, NULL); + iommu =3D device_to_iommu(dev, &bus, &devfn); if (!iommu) return ERR_PTR(-ENODEV); =20 - if (translation_pre_enabled(iommu)) - dev_iommu_priv_set(dev, DEFER_DEVICE_DOMAIN_INFO); + info =3D kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + if (dev_is_real_dma_subdevice(dev)) { + info->bus =3D pdev->bus->number; + info->devfn =3D pdev->devfn; + info->segment =3D pci_domain_nr(pdev->bus); + } else { + info->bus =3D bus; + info->devfn =3D devfn; + info->segment =3D iommu->segment; + } + + info->dev =3D dev; + info->iommu =3D iommu; + if (dev_is_pci(dev)) { + if (ecap_dev_iotlb_support(iommu->ecap) && + pci_ats_supported(pdev) && + dmar_find_matched_atsr_unit(pdev)) + info->ats_supported =3D 1; + + if (sm_supported(iommu)) { + if (pasid_supported(iommu)) { + int features =3D pci_pasid_features(pdev); + + if (features >=3D 0) + info->pasid_supported =3D features | 1; + } + + if (info->ats_supported && ecap_prs(iommu->ecap) && + pci_pri_supported(pdev)) + info->pri_supported =3D 1; + } + } + + 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; } @@ -4635,7 +4613,9 @@ intel_iommu_dev_disable_feat(struct device *dev, enum= iommu_dev_features feat) =20 static bool intel_iommu_is_attach_deferred(struct device *dev) { - return attach_deferred(dev); + struct device_domain_info *info =3D get_domain_info(dev); + + return translation_pre_enabled(info->iommu) && !info->domain; } =20 /* --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 46F48C433EF for ; Mon, 7 Feb 2022 06:58:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231701AbiBGG4a (ORCPT ); Mon, 7 Feb 2022 01:56:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357841AbiBGGoY (ORCPT ); Mon, 7 Feb 2022 01:44:24 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E8FFC0401C0 for ; Sun, 6 Feb 2022 22:44:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216263; x=1675752263; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/1FAEc7MxY57hsQjIIjJSXw/pIhYqbkltVpu9dLzdic=; b=HDfnjt06/QciKFur9FsKIlBPtvK6xneIGcA3ZhJ2jAbCInRRxDexiWCN sVOYubzcwrpy9GOUbiBbdK/TjGnuWpu7lqF+fd2XRd3r2vMEkH7yWt1Cn 6s6pZYw4dq04AWRttQj+lbBqKmt6QmI52278yIWjgpHLbY1/KcuXM1QD7 oP/J3dOmhB3blxt8XdnxfL4lZzAhkZGPdZxy7zRQhn0CoeK8IzMlxXKe9 3FSvt39TN67oxQ19mjpfwEY9LX9tdhSxNSM/MIUqzxuSRlgP8/ybBW/+k /9As8IXXKO63R1gRKfOsqAW1HWX2SwT40GA3VqJIse8rlyjeU/FJKUcB9 g==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171192" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171192" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:21 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020303" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:18 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 07/10] iommu/vt-d: Use an xarray for global device_domain_info Date: Mon, 7 Feb 2022 14:41:39 +0800 Message-Id: <20220207064142.1092846-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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" Replace the existing global device_domain_list with an array so that it could be easily searched. The index of the array is composed by the PCI segment, bus and devfn. And use RCU lock for protection. Signed-off-by: Lu Baolu --- include/linux/intel-iommu.h | 1 - drivers/iommu/intel/iommu.c | 68 ++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 8c7591b5f3e2..1ccba739a062 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -610,7 +610,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 165c890b8304..d7eba86c7f72 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -151,8 +151,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,30 +313,30 @@ struct device_domain_info *get_domain_info(struct dev= ice *dev) } =20 DEFINE_SPINLOCK(device_domain_lock); -static LIST_HEAD(device_domain_list); +static DEFINE_XARRAY_ALLOC(device_domain_array); + +#define DEVI_IDX(seg, bus, devfn) ((((u16)(seg)) << 16) | PCI_DEVID(bus, d= evfn)) =20 /* - * Iterate over elements in device_domain_list and call the specified + * Iterate over elements in device_domain_array 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; + unsigned long index; + int ret =3D 0; =20 - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry(info, &device_domain_list, global) { + rcu_read_lock(); + xa_for_each(&device_domain_array, index, info) { ret =3D fn(info, data); - if (ret) { - spin_unlock_irqrestore(&device_domain_lock, flags); - return ret; - } + if (ret) + break; } - spin_unlock_irqrestore(&device_domain_lock, flags); + rcu_read_unlock(); =20 - return 0; + return ret; } =20 const struct iommu_ops intel_iommu_ops; @@ -900,7 +898,8 @@ static void pgtable_walk(struct intel_iommu *iommu, uns= igned long pfn, u8 bus, u struct dmar_domain *domain; int offset, level; =20 - info =3D dmar_search_domain_by_dev_info(iommu->segment, bus, devfn); + info =3D xa_load(&device_domain_array, + DEVI_IDX(iommu->segment, bus, devfn)); if (!info || !info->domain) { pr_info("device [%02x:%02x.%d] not probed\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -1747,14 +1746,14 @@ 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; + struct device_domain_info *info; + unsigned long index; =20 if (!iommu->domain_ids) return; =20 - spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry_safe(info, tmp, &device_domain_list, global) { + rcu_read_lock(); + xa_for_each(&device_domain_array, index, info) { if (info->iommu !=3D iommu) continue; =20 @@ -1763,7 +1762,7 @@ static void disable_dmar_iommu(struct intel_iommu *io= mmu) =20 __dmar_remove_one_dev_info(info); } - spin_unlock_irqrestore(&device_domain_lock, flags); + rcu_read_unlock(); =20 if (iommu->gcmd & DMA_GCMD_TE) iommu_disable_translation(iommu); @@ -2388,7 +2387,8 @@ static inline void unlink_domain_info(struct device_d= omain_info *info) { assert_spin_locked(&device_domain_lock); list_del(&info->link); - list_del(&info->global); + xa_erase(&device_domain_array, + DEVI_IDX(info->segment, info->bus, info->devfn)); if (info->dev) dev_iommu_priv_set(info->dev, NULL); } @@ -2419,19 +2419,6 @@ struct dmar_domain *find_domain(struct device *dev) return NULL; } =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, @@ -4344,8 +4331,8 @@ 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; + void *curr; =20 iommu =3D device_to_iommu(dev, &bus, &devfn); if (!iommu) @@ -4387,10 +4374,15 @@ static struct iommu_device *intel_iommu_probe_devic= e(struct device *dev) } } =20 - spin_lock_irqsave(&device_domain_lock, flags); - list_add(&info->global, &device_domain_list); + curr =3D xa_store(&device_domain_array, + DEVI_IDX(info->segment, info->bus, info->devfn), + info, GFP_KERNEL); + if (xa_err(curr) || WARN_ON(curr)) { + kfree(info); + return ERR_PTR(-ENOSPC); + } + dev_iommu_priv_set(dev, info); - spin_unlock_irqrestore(&device_domain_lock, flags); =20 return &iommu->iommu; } --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 9727DC433EF for ; Mon, 7 Feb 2022 07:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241383AbiBGG6b (ORCPT ); Mon, 7 Feb 2022 01:58:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357913AbiBGGo3 (ORCPT ); Mon, 7 Feb 2022 01:44:29 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43B93C043185 for ; Sun, 6 Feb 2022 22:44:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216268; x=1675752268; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lJxwiEIQSk9dgfIPGnEA9tRvOUzFf2hlDhpa/mB/TOA=; b=ZpiaXSxRty3tHBuOfqUcCEFhRp/R2FkC5ZWj3PNvI9Z8oOTqrOzVTX7y 4hz2Kz2nKm2Fxp6t2PcfVaCslLAe7Vl68bAspMCJWirl08hUCmkFwvhDU zSvyDAM/1YoTXRFXh/dv2IB8WHisb0xt/8cCwhceDxSPuUTmjVxteZ9ye hEGdtGcvS7ISc0OgjpYuNptpXqqeSL8pEG4CoWJflvOF0Y70A+sKlu47r TwDIyzVjfnBp5/3Fc0u0emGkOTNr9NGyNX4i2g7We13CNtrkNXwPWLU0i 9KvtyZe8ZXEmEFtZw0Fb/3YgR1gfLXn+x/A/ieyXDAPJNdnmpYi04UDH7 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171198" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171198" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020319" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:21 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 08/10] iommu/vt-d: Use rculist for dmar_domain::devices Date: Mon, 7 Feb 2022 14:41:40 +0800 Message-Id: <20220207064142.1092846-9-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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 rculist for list of devices attached by a domain. And use the RCU lock for read/write protection. As both the global device_domain array and per-domain device_domain list are protected by RCU lock now, there is no need to use the spinlock anymore. Cleanup device_domain_lock. Signed-off-by: Lu Baolu --- include/linux/intel-iommu.h | 1 - drivers/iommu/intel/debugfs.c | 3 - drivers/iommu/intel/iommu.c | 118 ++++++++++++++-------------------- 3 files changed, 47 insertions(+), 75 deletions(-) diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 1ccba739a062..2091576b5989 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/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 db7a0ca73626..43137704f187 100644 --- a/drivers/iommu/intel/debugfs.c +++ b/drivers/iommu/intel/debugfs.c @@ -363,13 +363,10 @@ static int show_device_domain_translation(struct devi= ce *dev, void *data) =20 static int domain_translation_struct_show(struct seq_file *m, void *unused) { - unsigned long flags; int ret; =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); =20 return ret; } diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index d7eba86c7f72..7d2fec3041e4 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -282,7 +282,6 @@ static int hw_pass_through =3D 1; static int g_num_of_iommus; =20 static void domain_exit(struct dmar_domain *domain); -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); static int intel_iommu_attach_device(struct iommu_domain *domain, @@ -312,7 +311,6 @@ struct device_domain_info *get_domain_info(struct devic= e *dev) return dev_iommu_priv_get(dev); } =20 -DEFINE_SPINLOCK(device_domain_lock); static DEFINE_XARRAY_ALLOC(device_domain_array); =20 #define DEVI_IDX(seg, bus, devfn) ((((u16)(seg)) << 16) | PCI_DEVID(bus, d= evfn)) @@ -590,12 +588,11 @@ static int domain_update_device_node(struct dmar_doma= in *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; =20 - list_for_each_entry(info, &domain->devices, link) { + rcu_read_lock(); + list_for_each_entry_rcu(info, &domain->devices, link) { if (!info->dev) continue; =20 @@ -609,6 +606,7 @@ static int domain_update_device_node(struct dmar_domain= *domain) if (nid !=3D NUMA_NO_NODE) break; } + rcu_read_unlock(); =20 return nid; } @@ -1437,25 +1435,26 @@ 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 *tmp, *info =3D NULL; =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; + rcu_read_lock(); + list_for_each_entry_rcu(tmp, &domain->devices, link) { + if (tmp->iommu =3D=3D iommu && tmp->bus =3D=3D bus && + tmp->devfn =3D=3D devfn) { + if (tmp->ats_supported && tmp->dev) + info =3D tmp; break; } + } + rcu_read_unlock(); =20 - return NULL; + return info; } =20 static void domain_update_iotlb(struct dmar_domain *domain) @@ -1463,13 +1462,14 @@ 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) + rcu_read_lock(); + list_for_each_entry_rcu(info, &domain->devices, link) { if (info->ats_enabled) { has_iotlb_device =3D true; break; } + } + rcu_read_unlock(); =20 domain->has_iotlb_device =3D has_iotlb_device; } @@ -1478,8 +1478,6 @@ static void iommu_enable_dev_iotlb(struct device_doma= in_info *info) { struct pci_dev *pdev; =20 - assert_spin_locked(&device_domain_lock); - if (!info || !dev_is_pci(info->dev)) return; =20 @@ -1525,8 +1523,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 @@ -1566,17 +1562,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); - list_for_each_entry(info, &domain->devices, link) + rcu_read_lock(); + list_for_each_entry_rcu(info, &domain->devices, link) __iommu_flush_dev_iotlb(info, addr, mask); - - spin_unlock_irqrestore(&device_domain_lock, flags); + rcu_read_unlock(); } =20 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, @@ -1821,7 +1815,7 @@ static struct dmar_domain *alloc_domain(unsigned int = type) if (first_level_by_default(type)) domain->flags |=3D DOMAIN_FLAG_USE_FIRST_LEVEL; domain->has_iotlb_device =3D false; - INIT_LIST_HEAD(&domain->devices); + INIT_LIST_HEAD_RCU(&domain->devices); =20 return domain; } @@ -1833,7 +1827,6 @@ static int domain_attach_iommu(struct dmar_domain *do= main, unsigned long ndomains; int num; =20 - assert_spin_locked(&device_domain_lock); assert_spin_locked(&iommu->lock); =20 domain->iommu_refcnt[iommu->seq_id] +=3D 1; @@ -1861,7 +1854,6 @@ static void domain_detach_iommu(struct dmar_domain *d= omain, { int num; =20 - assert_spin_locked(&device_domain_lock); assert_spin_locked(&iommu->lock); =20 domain->iommu_refcnt[iommu->seq_id] -=3D 1; @@ -1890,8 +1882,15 @@ static inline int guestwidth_to_adjustwidth(int gaw) static void domain_exit(struct dmar_domain *domain) { =20 - /* Remove associated devices and clear attached or cached domains */ - domain_remove_dev_info(domain); + struct device_domain_info *info, *tmp; + + /* + * Remove associated devices and clear attached or cached domains. + * No worries about new devices insertion or removal. Hence no need + * for a lock here. + */ + list_for_each_entry_safe(info, tmp, &domain->devices, link) + __dmar_remove_one_dev_info(info); =20 if (domain->pgd) { LIST_HEAD(freelist); @@ -1974,9 +1973,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(&iommu->lock); - + spin_lock_irqsave(&iommu->lock, flags); ret =3D -ENOMEM; context =3D iommu_context_addr(iommu, bus, devfn, 1); if (!context) @@ -2095,8 +2092,7 @@ static int domain_context_mapping_one(struct dmar_dom= ain *domain, ret =3D 0; =20 out_unlock: - spin_unlock(&iommu->lock); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock_irqrestore(&iommu->lock, flags); =20 return ret; } @@ -2385,25 +2381,13 @@ static void domain_context_clear_one(struct device_= domain_info *info, u8 bus, u8 =20 static inline void unlink_domain_info(struct device_domain_info *info) { - assert_spin_locked(&device_domain_lock); - list_del(&info->link); + list_del_rcu(&info->link); xa_erase(&device_domain_array, DEVI_IDX(info->segment, info->bus, info->devfn)); if (info->dev) dev_iommu_priv_set(info->dev, NULL); } =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); -} - struct dmar_domain *find_domain(struct device *dev) { struct device_domain_info *info; @@ -2470,17 +2454,14 @@ static struct dmar_domain *dmar_insert_one_dev_info= (struct intel_iommu *iommu, unsigned long flags; int ret; =20 - spin_lock_irqsave(&device_domain_lock, flags); - info->domain =3D domain; - spin_lock(&iommu->lock); + spin_lock_irqsave(&iommu->lock, flags); ret =3D domain_attach_iommu(domain, iommu); - spin_unlock(&iommu->lock); - if (ret) { - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock_irqrestore(&iommu->lock, flags); + if (ret) return NULL; - } - list_add(&info->link, &domain->devices); - spin_unlock_irqrestore(&device_domain_lock, flags); + + info->domain =3D domain; + list_add_rcu(&info->link, &domain->devices); =20 /* PASID table is mandatory for a PCI device in scalable mode. */ if (dev && dev_is_pci(dev) && sm_supported(iommu)) { @@ -4004,8 +3985,6 @@ static void __dmar_remove_one_dev_info(struct device_= domain_info *info) struct intel_iommu *iommu; unsigned long flags; =20 - assert_spin_locked(&device_domain_lock); - if (WARN_ON(!info)) return; =20 @@ -4013,9 +3992,12 @@ static void __dmar_remove_one_dev_info(struct device= _domain_info *info) domain =3D info->domain; =20 if (info->dev && !dev_is_real_dma_subdevice(info->dev)) { - if (dev_is_pci(info->dev) && sm_supported(iommu)) + if (dev_is_pci(info->dev) && sm_supported(iommu)) { + spin_lock_irqsave(&iommu->lock, flags); intel_pasid_tear_down_entry(iommu, info->dev, PASID_RID2PASID, false); + spin_unlock_irqrestore(&iommu->lock, flags); + } =20 iommu_disable_dev_iotlb(info); domain_context_clear(info); @@ -4034,13 +4016,10 @@ static void __dmar_remove_one_dev_info(struct devic= e_domain_info *info) 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); info =3D get_domain_info(dev); if (info) __dmar_remove_one_dev_info(info); - spin_unlock_irqrestore(&device_domain_lock, flags); } =20 static int md_domain_init(struct dmar_domain *domain, int guest_width) @@ -4476,9 +4455,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(&iommu->lock); - + spin_lock_irqsave(&iommu->lock, flags); ret =3D -EINVAL; info =3D get_domain_info(dev); if (!info || !info->pasid_supported) @@ -4508,8 +4485,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iomm= u, struct device *dev) ret =3D 0; =20 out: - spin_unlock(&iommu->lock); - spin_unlock_irqrestore(&device_domain_lock, flags); + spin_unlock_irqrestore(&iommu->lock, flags); =20 return ret; } --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 A88E7C3526C for ; Mon, 7 Feb 2022 07:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241519AbiBGG6e (ORCPT ); Mon, 7 Feb 2022 01:58:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357924AbiBGGob (ORCPT ); Mon, 7 Feb 2022 01:44:31 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 30B8FC043181 for ; Sun, 6 Feb 2022 22:44:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216270; x=1675752270; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mT+9PcyYDHIgmL0UWJZy2RHRNEpPZBOFnxSL7FkSYzI=; b=ZNBfAYClDcNdCXDBv2I5sga4ZFQxfQBkTSG6lUmSLRciZ4uLgeS2z7xe CuBBY7mPo3mIkuFI/vc0WloZWyZLqQrvmnzApqyZFLHCh+vAl26bap5jv ze/PbLuR+Hm7fFZ0/HeDQHyBK8aZKZVsi6AUyPw34eleMjSob+4RAfoRw zPQx59h0K3lLLr9QOQSel4Y1Rqp4V2ri9GZQAYrMeBP281fMOm99LiJr0 0OdUi7MZcL1ufE4gyGebLpsNfE7GtlMFx6qhFMXHWcgLaEc0r7Trzqmba U1fHNBU01v4Qo25vuzr5MZaY+JniU4eo+iXtKvxCfRFdx0qDVrbj5JcUC w==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171205" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171205" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020334" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:25 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 09/10] iommu/vt-d: Refactor dmar_insert_one_dev_info() Date: Mon, 7 Feb 2022 14:41:41 +0800 Message-Id: <20220207064142.1092846-10-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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 existing dmar_insert_one_dev_info() implementation looks messy. This refactors it by moving pasid table allocation to device probe function, changing the return type to integer, adding the error rewinding paths. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 117 +++++++++++++++++------------------- 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 7d2fec3041e4..9a9f21fd268a 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2379,15 +2379,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 inline void unlink_domain_info(struct device_domain_info *info) -{ - list_del_rcu(&info->link); - xa_erase(&device_domain_array, - DEVI_IDX(info->segment, info->bus, info->devfn)); - if (info->dev) - dev_iommu_priv_set(info->dev, NULL); -} - struct dmar_domain *find_domain(struct device *dev) { struct device_domain_info *info; @@ -2445,35 +2436,22 @@ static bool dev_is_real_dma_subdevice(struct device= *dev) pci_real_dma_dev(to_pci_dev(dev)) !=3D to_pci_dev(dev); } =20 -static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *io= mmu, - int bus, int devfn, - struct device *dev, - struct dmar_domain *domain) +static int dmar_insert_one_dev_info(struct intel_iommu *iommu, int bus, + int devfn, struct device *dev, + struct dmar_domain *domain) { struct device_domain_info *info =3D get_domain_info(dev); unsigned long flags; int ret; =20 spin_lock_irqsave(&iommu->lock, flags); + /* Link to iommu and get a domain id: */ ret =3D domain_attach_iommu(domain, iommu); - spin_unlock_irqrestore(&iommu->lock, flags); if (ret) - return NULL; - - info->domain =3D domain; - list_add_rcu(&info->link, &domain->devices); - - /* PASID table is mandatory for a PCI device in scalable mode. */ - if (dev && dev_is_pci(dev) && sm_supported(iommu)) { - ret =3D intel_pasid_alloc_table(dev); - if (ret) { - dev_err(dev, "PASID table allocation failed\n"); - dmar_remove_one_dev_info(dev); - return NULL; - } + goto attach_iommu_err; =20 - /* Setup the PASID entry for requests without PASID: */ - spin_lock_irqsave(&iommu->lock, flags); + /* Setup the PASID entry for requests without PASID: */ + if (dev_is_pci(dev) && sm_supported(iommu)) { if (hw_pass_through && domain_type_is_si(domain)) ret =3D intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); @@ -2483,21 +2461,31 @@ static struct dmar_domain *dmar_insert_one_dev_info= (struct intel_iommu *iommu, 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); - return NULL; - } + if (ret) + goto pasid_setup_err; } + spin_unlock_irqrestore(&iommu->lock, flags); =20 - if (dev && domain_context_mapping(domain, dev)) { - dev_err(dev, "Domain context map failed\n"); - dmar_remove_one_dev_info(dev); - return NULL; - } + /* Setup the context entry for device: */ + ret =3D domain_context_mapping(domain, dev); + if (ret) + goto setup_context_err; =20 - return domain; + info->domain =3D domain; + list_add_rcu(&info->link, &domain->devices); + + return 0; + +setup_context_err: + spin_lock_irqsave(&iommu->lock, flags); + if (dev_is_pci(dev) && sm_supported(iommu)) + intel_pasid_tear_down_entry(iommu, dev, PASID_RID2PASID, false); +pasid_setup_err: + domain_detach_iommu(domain, iommu); +attach_iommu_err: + spin_unlock_irqrestore(&iommu->lock, flags); + + return ret; } =20 static int iommu_domain_identity_map(struct dmar_domain *domain, @@ -2575,7 +2563,6 @@ static int __init si_domain_init(int hw) =20 static int domain_add_dev_info(struct dmar_domain *domain, struct device *= dev) { - struct dmar_domain *ndomain; struct intel_iommu *iommu; u8 bus, devfn; =20 @@ -2583,11 +2570,7 @@ static int domain_add_dev_info(struct dmar_domain *d= omain, struct device *dev) if (!iommu) return -ENODEV; =20 - ndomain =3D dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain); - if (ndomain !=3D domain) - return -EBUSY; - - return 0; + return dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain); } =20 static bool device_has_rmrr(struct device *dev) @@ -4001,16 +3984,13 @@ static void __dmar_remove_one_dev_info(struct devic= e_domain_info *info) =20 iommu_disable_dev_iotlb(info); domain_context_clear(info); - intel_pasid_free_table(info->dev); } =20 - unlink_domain_info(info); + list_del_rcu(&info->link); =20 spin_lock_irqsave(&iommu->lock, flags); domain_detach_iommu(domain, iommu); spin_unlock_irqrestore(&iommu->lock, flags); - - kfree(info); } =20 static void dmar_remove_one_dev_info(struct device *dev) @@ -4310,8 +4290,10 @@ 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 index; u8 bus, devfn; void *curr; + int ret; =20 iommu =3D device_to_iommu(dev, &bus, &devfn); if (!iommu) @@ -4353,30 +4335,39 @@ static struct iommu_device *intel_iommu_probe_devic= e(struct device *dev) } } =20 - curr =3D xa_store(&device_domain_array, - DEVI_IDX(info->segment, info->bus, info->devfn), - info, GFP_KERNEL); + index =3D DEVI_IDX(info->segment, info->bus, info->devfn); + curr =3D xa_store(&device_domain_array, index, info, GFP_KERNEL); if (xa_err(curr) || WARN_ON(curr)) { - kfree(info); - return ERR_PTR(-ENOSPC); + ret =3D -ENOSPC; + goto free_out; } =20 dev_iommu_priv_set(dev, info); + if (sm_supported(iommu)) { + ret =3D intel_pasid_alloc_table(dev); + if (ret) + goto cleanup_out; + } =20 return &iommu->iommu; + +cleanup_out: + dev_iommu_priv_set(dev, NULL); + xa_erase(&device_domain_array, index); +free_out: + kfree(info); + return ERR_PTR(ret); } =20 static void intel_iommu_release_device(struct device *dev) { - struct intel_iommu *iommu; - - iommu =3D device_to_iommu(dev, NULL, NULL); - if (!iommu) - return; - - dmar_remove_one_dev_info(dev); + struct device_domain_info *info =3D get_domain_info(dev); + unsigned long index =3D DEVI_IDX(info->segment, info->bus, info->devfn); =20 + xa_erase(&device_domain_array, index); + dev_iommu_priv_set(info->dev, NULL); set_dma_ops(dev, NULL); + kfree(info); } =20 static void intel_iommu_probe_finalize(struct device *dev) --=20 2.25.1 From nobody Mon Jun 29 16:45:19 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 3080DC43217 for ; Mon, 7 Feb 2022 07:02:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242422AbiBGG6y (ORCPT ); Mon, 7 Feb 2022 01:58:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42404 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357935AbiBGGoh (ORCPT ); Mon, 7 Feb 2022 01:44:37 -0500 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40C89C043181 for ; Sun, 6 Feb 2022 22:44:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1644216276; x=1675752276; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pi6PX6+nntRtFkpNMkBJo/Y18uMshhZleGI117X8MhA=; b=O5/o6UUZ1rQTZptl81zHq2TH+bHrXRIVenAWbqQegf8I3XMhalv1ZvQ5 rGWSnPDJHxfiYreIII8qYHFKr1P6hy4yb1XMbzGcz3TU1CmC6MRYXhKRh CiqHdoLxw3KUt/0VJrbTDH7weFOiS5T7/MH5IxIPIs/Y6flqFsqcJhDLi unyXZ3M9D28jBPmyGkz3nSu6F+928GlTxbJZ2iWl/oxlQOboLZzzkyYev ezMPXjbqzAHg/ZibrtmsvnF0LF9e/yHWm+YuoZ14FKKQb/KBOs9XK5KkU mBQEXCW0TyMXID1Wiy5Hd6NoPJOFAH2VuCenxJc1bVWaYxJjS5CEFKBFz g==; X-IronPort-AV: E=McAfee;i="6200,9189,10250"; a="273171217" X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="273171217" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2022 22:43:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,349,1635231600"; d="scan'208";a="525020346" Received: from allen-box.sh.intel.com ([10.239.159.118]) by orsmga007.jf.intel.com with ESMTP; 06 Feb 2022 22:43:28 -0800 From: Lu Baolu To: Joerg Roedel , Kevin Tian , Ashok Raj , Liu Yi L , Jacob Pan Cc: Robin Murphy , Jason Gunthorpe , Christoph Hellwig , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v1 10/10] iommu/vt-d: Some cleanups in iommu.c Date: Mon, 7 Feb 2022 14:41:42 +0800 Message-Id: <20220207064142.1092846-11-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220207064142.1092846-1-baolu.lu@linux.intel.com> References: <20220207064142.1092846-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" Remove unnecessary include files. Move macros and inline helpers to the header file. Remove commented out code. Remove spaces before jump lables. No intentional functionality changes. Signed-off-by: Lu Baolu --- include/linux/intel-iommu.h | 217 +++++++++++++++++++++++++++ drivers/iommu/intel/iommu.c | 283 ++---------------------------------- 2 files changed, 233 insertions(+), 267 deletions(-) diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 2091576b5989..9de98fafd958 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -55,6 +55,101 @@ #define CONTEXT_TT_PASS_THROUGH 2 #define CONTEXT_PASIDE BIT_ULL(3) =20 +#define ROOT_SIZE VTD_PAGE_SIZE +#define CONTEXT_SIZE VTD_PAGE_SIZE + +#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) =3D=3D PCI_BASE_CLASS_DIS= PLAY) +#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) =3D=3D PCI_CLASS_SERIAL_US= B) +#define IS_AZALIA(pdev) ((pdev)->vendor =3D=3D 0x8086 && (pdev)->device = =3D=3D 0x3a3e) + +#define IOAPIC_RANGE_START (0xfee00000) +#define IOAPIC_RANGE_END (0xfeefffff) + +#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57 + +#define MAX_AGAW_WIDTH 64 +#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT) + +#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << ((gaw) - VTD_PAGE_SHIFT)= ) - 1) +#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << (gaw)) - 1) + +/* + * We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR + * to match. That way, we can use 'unsigned long' for PFNs with impunity. + */ +#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \ + __DOMAIN_MAX_PFN(gaw), (unsigned long)-1)) + +#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) + +/* page table handling */ +#define LEVEL_STRIDE (9) +#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) + +static inline int agaw_to_level(int agaw) +{ + return agaw + 2; +} + +static inline int agaw_to_width(int agaw) +{ + return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH); +} + +static inline int width_to_agaw(int width) +{ + return DIV_ROUND_UP(width - 30, LEVEL_STRIDE); +} + +static inline unsigned int level_to_offset_bits(int level) +{ + return (level - 1) * LEVEL_STRIDE; +} + +static inline int pfn_level_offset(u64 pfn, int level) +{ + return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; +} + +static inline u64 level_mask(int level) +{ + return -1ULL << level_to_offset_bits(level); +} + +static inline u64 level_size(int level) +{ + return 1ULL << level_to_offset_bits(level); +} + +static inline u64 align_to_level(u64 pfn, int level) +{ + return (pfn + level_size(level) - 1) & level_mask(level); +} + +static inline unsigned long lvl_to_nr_pages(unsigned int lvl) +{ + return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH); +} + +/* + * VT-d pages must always be _smaller_ than MM pages. Otherwise things + * are never going to work. + */ +static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn) +{ + return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT); +} + +static inline unsigned long page_to_dma_pfn(struct page *pg) +{ + return mm_to_dma_pfn(page_to_pfn(pg)); +} + +static inline unsigned long virt_to_dma_pfn(void *p) +{ + return page_to_dma_pfn(virt_to_page(p)); +} + /* * Intel IOMMU register specification per version 1.0 public spec. */ @@ -516,6 +611,110 @@ struct context_entry { u64 hi; }; =20 +static inline void context_clear_pasid_enable(struct context_entry *contex= t) +{ + context->lo &=3D ~(1ULL << 11); +} + +static inline bool context_pasid_enabled(struct context_entry *context) +{ + return !!(context->lo & (1ULL << 11)); +} + +static inline void context_set_copied(struct context_entry *context) +{ + context->hi |=3D (1ull << 3); +} + +static inline bool context_copied(struct context_entry *context) +{ + return !!(context->hi & (1ULL << 3)); +} + +static inline bool __context_present(struct context_entry *context) +{ + return (context->lo & 1); +} + +static inline void context_set_present(struct context_entry *context) +{ + context->lo |=3D 1; +} + +static inline void context_set_fault_enable(struct context_entry *context) +{ + context->lo &=3D (((u64)-1) << 2) | 1; +} + +static inline void context_set_translation_type(struct context_entry *cont= ext, + unsigned long value) +{ + context->lo &=3D (((u64)-1) << 4) | 3; + context->lo |=3D (value & 3) << 2; +} + +static inline void context_set_address_root(struct context_entry *context, + unsigned long value) +{ + context->lo &=3D ~VTD_PAGE_MASK; + context->lo |=3D value & VTD_PAGE_MASK; +} + +static inline void context_set_address_width(struct context_entry *context, + unsigned long value) +{ + context->hi |=3D value & 7; +} + +static inline void context_set_domain_id(struct context_entry *context, + unsigned long value) +{ + context->hi |=3D (value & ((1 << 16) - 1)) << 8; +} + +static inline int context_domain_id(struct context_entry *c) +{ + return((c->hi >> 8) & 0xffff); +} + +static inline void context_clear_entry(struct context_entry *context) +{ + context->lo =3D 0; + context->hi =3D 0; +} + +/* + * Set the RID_PASID field of a scalable mode context entry. The + * IOMMU hardware will use the PASID value set in this field for + * DMA translations of DMA requests without PASID. + */ +static inline void +context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasi= d) +{ + context->hi |=3D pasid & ((1 << 20) - 1); +} + +/* + * Set the DTE(Device-TLB Enable) field of a scalable mode context + * entry. + */ +static inline void context_set_sm_dte(struct context_entry *context) +{ + context->lo |=3D (1 << 2); +} + +/* + * Set the PRE(Page Request Enable) field of a scalable mode context + * entry. + */ +static inline void context_set_sm_pre(struct context_entry *context) +{ + context->lo |=3D (1 << 4); +} + +/* Convert value to context PASID directory size field coding. */ +#define context_pdts(pds) (((pds) & 0x7) << 9) + /* * When VT-d works in the scalable mode, it allows DMA translation to * happen through either first level or second level page table. This @@ -640,6 +839,24 @@ static inline struct dmar_domain *to_dmar_domain(struc= t iommu_domain *dom) return container_of(dom, struct dmar_domain, domain); } =20 +static inline int domain_type_is_si(struct dmar_domain *domain) +{ + return domain->domain.type =3D=3D IOMMU_DOMAIN_IDENTITY; +} + +static inline bool domain_use_first_level(struct dmar_domain *domain) +{ + return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL; +} + +static inline int domain_pfn_supported(struct dmar_domain *domain, + unsigned long pfn) +{ + int addr_width =3D agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; + + return !(addr_width < BITS_PER_LONG && pfn >> addr_width); +} + /* * 0: readable * 1: writable diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 9a9f21fd268a..a5244be69c44 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -13,24 +13,9 @@ #define pr_fmt(fmt) "DMAR: " fmt #define dev_fmt(fmt) pr_fmt(fmt) =20 -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include #include @@ -38,114 +23,14 @@ #include #include #include -#include #include #include -#include -#include -#include -#include =20 #include "../irq_remapping.h" #include "../iommu-sva-lib.h" #include "pasid.h" #include "cap_audit.h" =20 -#define ROOT_SIZE VTD_PAGE_SIZE -#define CONTEXT_SIZE VTD_PAGE_SIZE - -#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) =3D=3D PCI_BASE_CLASS_DIS= PLAY) -#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) =3D=3D PCI_CLASS_SERIAL_US= B) -#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) =3D=3D PCI_CLASS_BRIDGE_IS= A) -#define IS_AZALIA(pdev) ((pdev)->vendor =3D=3D 0x8086 && (pdev)->device = =3D=3D 0x3a3e) - -#define IOAPIC_RANGE_START (0xfee00000) -#define IOAPIC_RANGE_END (0xfeefffff) -#define IOVA_START_ADDR (0x1000) - -#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57 - -#define MAX_AGAW_WIDTH 64 -#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT) - -#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << ((gaw) - VTD_PAGE_SHIFT)= ) - 1) -#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << (gaw)) - 1) - -/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR - to match. That way, we can use 'unsigned long' for PFNs with impunity. = */ -#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \ - __DOMAIN_MAX_PFN(gaw), (unsigned long)-1)) -#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAG= E_SHIFT) - -/* IO virtual address start page frame number */ -#define IOVA_START_PFN (1) - -#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) - -/* page table handling */ -#define LEVEL_STRIDE (9) -#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) - -static inline int agaw_to_level(int agaw) -{ - return agaw + 2; -} - -static inline int agaw_to_width(int agaw) -{ - return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH); -} - -static inline int width_to_agaw(int width) -{ - return DIV_ROUND_UP(width - 30, LEVEL_STRIDE); -} - -static inline unsigned int level_to_offset_bits(int level) -{ - return (level - 1) * LEVEL_STRIDE; -} - -static inline int pfn_level_offset(u64 pfn, int level) -{ - return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; -} - -static inline u64 level_mask(int level) -{ - return -1ULL << level_to_offset_bits(level); -} - -static inline u64 level_size(int level) -{ - return 1ULL << level_to_offset_bits(level); -} - -static inline u64 align_to_level(u64 pfn, int level) -{ - return (pfn + level_size(level) - 1) & level_mask(level); -} - -static inline unsigned long lvl_to_nr_pages(unsigned int lvl) -{ - return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH); -} - -/* VT-d pages must always be _smaller_ than MM pages. Otherwise things - are never going to work. */ -static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn) -{ - return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT); -} -static inline unsigned long page_to_dma_pfn(struct page *pg) -{ - return mm_to_dma_pfn(page_to_pfn(pg)); -} -static inline unsigned long virt_to_dma_pfn(void *p) -{ - return page_to_dma_pfn(virt_to_page(p)); -} - /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; =20 @@ -186,31 +71,6 @@ static phys_addr_t root_entry_uctp(struct root_entry *r= e) return re->hi & VTD_PAGE_MASK; } =20 -static inline void context_clear_pasid_enable(struct context_entry *contex= t) -{ - context->lo &=3D ~(1ULL << 11); -} - -static inline bool context_pasid_enabled(struct context_entry *context) -{ - return !!(context->lo & (1ULL << 11)); -} - -static inline void context_set_copied(struct context_entry *context) -{ - context->hi |=3D (1ull << 3); -} - -static inline bool context_copied(struct context_entry *context) -{ - return !!(context->hi & (1ULL << 3)); -} - -static inline bool __context_present(struct context_entry *context) -{ - return (context->lo & 1); -} - bool context_present(struct context_entry *context) { return context_pasid_enabled(context) ? @@ -218,53 +78,6 @@ bool context_present(struct context_entry *context) __context_present(context) && !context_copied(context); } =20 -static inline void context_set_present(struct context_entry *context) -{ - context->lo |=3D 1; -} - -static inline void context_set_fault_enable(struct context_entry *context) -{ - context->lo &=3D (((u64)-1) << 2) | 1; -} - -static inline void context_set_translation_type(struct context_entry *cont= ext, - unsigned long value) -{ - context->lo &=3D (((u64)-1) << 4) | 3; - context->lo |=3D (value & 3) << 2; -} - -static inline void context_set_address_root(struct context_entry *context, - unsigned long value) -{ - context->lo &=3D ~VTD_PAGE_MASK; - context->lo |=3D value & VTD_PAGE_MASK; -} - -static inline void context_set_address_width(struct context_entry *context, - unsigned long value) -{ - context->hi |=3D value & 7; -} - -static inline void context_set_domain_id(struct context_entry *context, - unsigned long value) -{ - context->hi |=3D (value & ((1 << 16) - 1)) << 8; -} - -static inline int context_domain_id(struct context_entry *c) -{ - return((c->hi >> 8) & 0xffff); -} - -static inline void context_clear_entry(struct context_entry *context) -{ - context->lo =3D 0; - context->hi =3D 0; -} - /* * This domain is a statically identity mapping domain. * 1. This domain creats a static 1:1 mapping to all usable memory. @@ -281,13 +94,8 @@ static int hw_pass_through =3D 1; /* bitmap for indexing intel_iommus */ static int g_num_of_iommus; =20 -static void domain_exit(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); -static int intel_iommu_attach_device(struct iommu_domain *domain, - struct device *dev); -static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova); =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); @@ -421,24 +229,6 @@ void free_pgtable_page(void *vaddr) free_page((unsigned long)vaddr); } =20 -static inline int domain_type_is_si(struct dmar_domain *domain) -{ - return domain->domain.type =3D=3D IOMMU_DOMAIN_IDENTITY; -} - -static inline bool domain_use_first_level(struct dmar_domain *domain) -{ - return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL; -} - -static inline int domain_pfn_supported(struct dmar_domain *domain, - unsigned long pfn) -{ - int addr_width =3D agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - - return !(addr_width < BITS_PER_LONG && pfn >> addr_width); -} - static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) { unsigned long sagaw; @@ -490,7 +280,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain= *domain) return g_iommus[iommu_id]; } =20 -static inline bool iommu_paging_structure_coherency(struct intel_iommu *io= mmu) +static bool iommu_paging_structure_coherency(struct intel_iommu *iommu) { return sm_supported(iommu) ? ecap_smpwc(iommu->ecap) : ecap_coherent(iommu->ecap); @@ -820,7 +610,7 @@ struct intel_iommu *device_to_iommu(struct device *dev,= u8 *bus, u8 *devfn) } =20 if (pdev && drhd->include_all) { - got_pdev: +got_pdev: if (bus && devfn) { *bus =3D pdev->bus->number; *devfn =3D pdev->devfn; @@ -829,7 +619,7 @@ struct intel_iommu *device_to_iommu(struct device *dev,= u8 *bus, u8 *devfn) } } iommu =3D NULL; - out: +out: if (iommu_is_dummy(iommu, dev)) iommu =3D NULL; =20 @@ -1401,15 +1191,7 @@ static void __iommu_flush_iotlb(struct intel_iommu *= iommu, u16 did, default: BUG(); } - /* Note: set drain read/write */ -#if 0 - /* - * This is probably to be super secure.. Looks like we can - * ignore it without any impact. - */ - if (cap_read_drain(iommu->cap)) - val |=3D DMA_TLB_READ_DRAIN; -#endif + if (cap_write_drain(iommu->cap)) val |=3D DMA_TLB_WRITE_DRAIN; =20 @@ -1613,9 +1395,9 @@ static void iommu_flush_iotlb_psi(struct intel_iommu = *iommu, } =20 /* Notification for newly created mappings */ -static inline void __mapping_notify_one(struct intel_iommu *iommu, - struct dmar_domain *domain, - unsigned long pfn, unsigned int pages) +static void __mapping_notify_one(struct intel_iommu *iommu, + struct dmar_domain *domain, + unsigned long pfn, unsigned int pages) { /* * It's a non-present to present mapping. Only flush if caching mode @@ -1865,7 +1647,7 @@ static void domain_detach_iommu(struct dmar_domain *d= omain, } } =20 -static inline int guestwidth_to_adjustwidth(int gaw) +static int guestwidth_to_adjustwidth(int gaw) { int agaw; int r =3D (gaw - 12) % 9; @@ -1907,7 +1689,7 @@ static void domain_exit(struct dmar_domain *domain) * Value of X in the PDTS field of a scalable mode context entry * indicates PASID directory with 2^(X + 7) entries. */ -static inline unsigned long context_get_sm_pds(struct pasid_table *table) +static unsigned long context_get_sm_pds(struct pasid_table *table) { unsigned long pds, max_pde; =20 @@ -1919,38 +1701,6 @@ static inline unsigned long context_get_sm_pds(struc= t pasid_table *table) return pds - 7; } =20 -/* - * Set the RID_PASID field of a scalable mode context entry. The - * IOMMU hardware will use the PASID value set in this field for - * DMA translations of DMA requests without PASID. - */ -static inline void -context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasi= d) -{ - context->hi |=3D pasid & ((1 << 20) - 1); -} - -/* - * Set the DTE(Device-TLB Enable) field of a scalable mode context - * entry. - */ -static inline void context_set_sm_dte(struct context_entry *context) -{ - context->lo |=3D (1 << 2); -} - -/* - * Set the PRE(Page Request Enable) field of a scalable mode context - * entry. - */ -static inline void context_set_sm_pre(struct context_entry *context) -{ - context->lo |=3D (1 << 4); -} - -/* Convert value to context PASID directory size field coding. */ -#define context_pdts(pds) (((pds) & 0x7) << 9) - static int domain_context_mapping_one(struct dmar_domain *domain, struct intel_iommu *iommu, struct pasid_table *table, @@ -2164,18 +1914,17 @@ static int domain_context_mapped(struct device *dev) } =20 /* Returns a number of VTD pages, but aligned to MM page size */ -static inline unsigned long aligned_nrpages(unsigned long host_addr, - size_t size) +static unsigned long aligned_nrpages(unsigned long host_addr, size_t size) { host_addr &=3D ~PAGE_MASK; return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; } =20 /* Return largest possible superpage level for a given mapping */ -static inline int hardware_largepage_caps(struct dmar_domain *domain, - unsigned long iov_pfn, - unsigned long phy_pfn, - unsigned long pages) +static int hardware_largepage_caps(struct dmar_domain *domain, + unsigned long iov_pfn, + unsigned long phy_pfn, + unsigned long pages) { int support, level =3D 1; unsigned long pfnmerge; @@ -3650,7 +3399,7 @@ void intel_iommu_shutdown(void) up_write(&dmar_global_lock); } =20 -static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev) +static struct intel_iommu *dev_to_intel_iommu(struct device *dev) { struct iommu_device *iommu_dev =3D dev_to_iommu_device(dev); =20 @@ -3728,7 +3477,7 @@ const struct attribute_group *intel_iommu_groups[] = =3D { NULL, }; =20 -static inline bool has_external_pci(void) +static bool has_external_pci(void) { struct pci_dev *pdev =3D NULL; =20 --=20 2.25.1