Received: by 2002:a89:d88:0:b0:1fa:5c73:8e2d with SMTP id eb8csp1831202lqb; Sun, 26 May 2024 21:08:10 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXrgGkHaoZRLNX5FdE0GzBu7vXV8X6Ud4Jjk5oaKq8z9e40KYyMde4ak49YcL1W63O9oxIgqVtVpsUY/jR/JKig26AN4hVEls81eNX86A== X-Google-Smtp-Source: AGHT+IGsgUvEcNBAeiIV0U32iwdw85pyMpy4/PZ9LSDbKv5/6z6iJ7cbjrssNKlTLCRg5o4rB6i7 X-Received: by 2002:a05:6a21:3398:b0:1af:a9ad:fbbe with SMTP id adf61e73a8af0-1b205cf89b4mr17090739637.27.1716782890272; Sun, 26 May 2024 21:08:10 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716782890; cv=pass; d=google.com; s=arc-20160816; b=tscyBNYUd4lFctQFrZpCLrG9JqYn8Oyq3w+zExyR0GIGxX99oubbm5ZGzl4hQ+j+4n EQ8ZZIMO2DpBhSNX1ywpUlmbXLaObmtPrFgpEbWxbszyUt/zYRsGg9jR0bIp35P89/NR TLZ6znT9gWAbZyQx4aRc0jsvq4a78jWoErJl53TUSUnOc+4IheiFna4dh2cDZgDFA15o LTiRD9+FFDrvN6EkCx+S4WS5O8hnDo/+zPWZE+JylXlFf9a9VzPosMhClUNowHHdx12G DguZF4U3C/45Ow52v5Ps6/VaslvYgs60cN3HB8J8pM5wrYUcZtnD6zVcqGGkxnCds+Uy 7TSA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=ohmi6mtDyA0iCV2nSabdZJRBRx+NW5GVBQ92hBkKA58=; fh=Zz3Qlvy2f7oQ41R2RRkjKy0BoKdSPWcMKkG2HiVB0aY=; b=ZMLn90/MkYb5VlfB0kJLRzH7OxMtW50rRRG2nWnO6w2Eg8SR9U+WHgYpWBfnxexBVT uM3IuDRgPkj3HjkWHG0h88f26JRPkGgXecnNKHWKAMYu8415L6Fo1ekSOfVUIZlw88UI 5kZW7zjE1bt1M32FPx3Lmz/8icwp31XzakDskpp5qoTsIDOOApLbldrKDtmf4bgAzsSN lHqimsQcHI5Xc7HvNFmJrsTxuHXB2274f9gP2tV/DS9syZ2LrPEgdiY6dmvHFmwBl6KT xGQJyBzNwTcvkkx5CC5cLx6AEfK8ywLY30X3i6zVmZiA8+xkQsXWGg8ylhpmwT/RJrJ6 KbJg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=GyteMkrp; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-190001-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-190001-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id 41be03b00d2f7-6822ae56f5fsi5430573a12.772.2024.05.26.21.08.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 May 2024 21:08:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-190001-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=GyteMkrp; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-190001-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-190001-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id BD7A0281761 for ; Mon, 27 May 2024 04:08:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4D752D53F; Mon, 27 May 2024 04:07:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="GyteMkrp" Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38B42D517 for ; Mon, 27 May 2024 04:07:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716782870; cv=none; b=kZ1+KK9jGs+2klXCfAH2THwDgp6F4CpQtDB5c0DSn8is91r4TW63k3iKdsh3+hlOJWvWsaElLBkmD3Q/ao8nnlo1h95DQBq0Vjrg4/WpXYX4kU8IVGwtSbx7wAh6cJR9WB6e+F8jTAwcniox67+NkFvM2QIOuaQfYKYmIkVSKs8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716782870; c=relaxed/simple; bh=J9wCRtxD0gbdHyIEhv/YJB4bZC0qR/j8eeGR5NVu5qM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SphnAnTLwNrysHirVFWxMXYEoMbe3HJEwLonJoGBKpU8mMogBxGGVmzNbgTC6a2bzdTfFy7I2tjxhA2kT+8ZH+STHVpWxuLW8RnvNQkVhITfLLV0VZ2RxAPHgk6HB71Go0FDd2yyqWNwaOyXXPi9pXk6Kw7qZZp9WvhTjLKDeVw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=GyteMkrp; arc=none smtp.client-ip=198.175.65.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1716782868; x=1748318868; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=J9wCRtxD0gbdHyIEhv/YJB4bZC0qR/j8eeGR5NVu5qM=; b=GyteMkrpFX4ZDTkR5caKqqHLPsYY++w6784ocA5ztCwgchPX48groMY1 zsr60uuTtc1xWSZkFwQgj6l7KnQ9w87W57GnanNlovtp7ZAxOYhYG3D/H ohJuXuBhKIvlbG/y0V3RwmyrUm9LmS5dK1Catm9CoHBdgsY1uYd66JnAu ffkr+L0fpNl8r5VP4p8l7FKU3SsBYrssRYC3uWMoYjfmF13+vo80qiBhW 1yNIuI0AjtrXN533mqJ5RZ3DEcusu2NibAa/XkDB71wH23oNAprfvy2cm /tukXB+XGu1C4pG7vUjichumHlrTrH7AGsfoBfLtL+6MQ/70Rm0Q0VvkC w==; X-CSE-ConnectionGUID: 5ncr6yApSOanoz3HwZE+/A== X-CSE-MsgGUID: JdJ4EXF3QvGqbI2BUBv11A== X-IronPort-AV: E=McAfee;i="6600,9927,11084"; a="13022662" X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="13022662" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 May 2024 21:07:29 -0700 X-CSE-ConnectionGUID: KFSkJIPGShaByYscKSv2uw== X-CSE-MsgGUID: AmXwEEv/S3+dzE7OfZJ60Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,191,1712646000"; d="scan'208";a="39399874" Received: from unknown (HELO allen-box.sh.intel.com) ([10.239.159.127]) by orviesa003.jf.intel.com with ESMTP; 26 May 2024 21:07:25 -0700 From: Lu Baolu To: Jason Gunthorpe , Kevin Tian , Joerg Roedel , Will Deacon , Robin Murphy , Jean-Philippe Brucker , Nicolin Chen , Yi Liu , Jacob Pan , Joel Granados Cc: iommu@lists.linux.dev, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu , Jason Gunthorpe Subject: [PATCH v6 01/10] iommu: Introduce domain attachment handle Date: Mon, 27 May 2024 12:05:08 +0800 Message-Id: <20240527040517.38561-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240527040517.38561-1-baolu.lu@linux.intel.com> References: <20240527040517.38561-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Currently, when attaching a domain to a device or its PASID, domain is stored within the iommu group. It could be retrieved for use during the window between attachment and detachment. With new features introduced, there's a need to store more information than just a domain pointer. This information essentially represents the association between a domain and a device. For example, the SVA code already has a custom struct iommu_sva which represents a bond between sva domain and a PASID of a device. Looking forward, the IOMMUFD needs a place to store the iommufd_device pointer in the core, so that the device object ID could be quickly retrieved in the critical fault handling path. Introduce domain attachment handle that explicitly represents the attachment relationship between a domain and a device or its PASID. Co-developed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe Signed-off-by: Lu Baolu --- include/linux/iommu.h | 18 +++++++++++++++--- drivers/dma/idxd/init.c | 2 +- drivers/iommu/iommu-sva.c | 13 ++++++++----- drivers/iommu/iommu.c | 23 +++++++++++++---------- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7bc8dff7cf6d..b89404acacd6 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -989,12 +989,22 @@ struct iommu_fwspec { /* ATS is supported */ #define IOMMU_FWSPEC_PCI_RC_ATS (1 << 0) +/* + * An iommu attach handle represents a relationship between an iommu domain + * and a PASID or RID of a device. It is allocated and managed by the component + * that manages the domain and is stored in the iommu group during the time the + * domain is attached. + */ +struct iommu_attach_handle { + struct iommu_domain *domain; +}; + /** * struct iommu_sva - handle to a device-mm bond */ struct iommu_sva { + struct iommu_attach_handle handle; struct device *dev; - struct iommu_domain *domain; struct list_head handle_item; refcount_t users; }; @@ -1052,7 +1062,8 @@ int iommu_device_claim_dma_owner(struct device *dev, void *owner); void iommu_device_release_dma_owner(struct device *dev); int iommu_attach_device_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid); + struct device *dev, ioasid_t pasid, + struct iommu_attach_handle *handle); void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev, ioasid_t pasid); struct iommu_domain * @@ -1388,7 +1399,8 @@ static inline int iommu_device_claim_dma_owner(struct device *dev, void *owner) } static inline int iommu_attach_device_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid) + struct device *dev, ioasid_t pasid, + struct iommu_attach_handle *handle) { return -ENODEV; } diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index a7295943fa22..385c488c9cd1 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -584,7 +584,7 @@ static int idxd_enable_system_pasid(struct idxd_device *idxd) * DMA domain is owned by the driver, it should support all valid * types such as DMA-FQ, identity, etc. */ - ret = iommu_attach_device_pasid(domain, dev, pasid); + ret = iommu_attach_device_pasid(domain, dev, pasid, NULL); if (ret) { dev_err(dev, "failed to attach device pasid %d, domain type %d", pasid, domain->type); diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c index 18a35e798b72..0fb923254062 100644 --- a/drivers/iommu/iommu-sva.c +++ b/drivers/iommu/iommu-sva.c @@ -99,7 +99,9 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm /* Search for an existing domain. */ list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) { - ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid); + handle->handle.domain = domain; + ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid, + &handle->handle); if (!ret) { domain->users++; goto out; @@ -113,7 +115,9 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm goto out_free_handle; } - ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid); + handle->handle.domain = domain; + ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid, + &handle->handle); if (ret) goto out_free_domain; domain->users = 1; @@ -124,7 +128,6 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm list_add(&handle->handle_item, &mm->iommu_mm->sva_handles); mutex_unlock(&iommu_sva_lock); handle->dev = dev; - handle->domain = domain; return handle; out_free_domain: @@ -147,7 +150,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_bind_device); */ void iommu_sva_unbind_device(struct iommu_sva *handle) { - struct iommu_domain *domain = handle->domain; + struct iommu_domain *domain = handle->handle.domain; struct iommu_mm_data *iommu_mm = domain->mm->iommu_mm; struct device *dev = handle->dev; @@ -170,7 +173,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_unbind_device); u32 iommu_sva_get_pasid(struct iommu_sva *handle) { - struct iommu_domain *domain = handle->domain; + struct iommu_domain *domain = handle->handle.domain; return mm_get_enqcmd_pasid(domain->mm); } diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 9df7cc75c1bc..efd281ddfa63 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3352,16 +3352,17 @@ static void __iommu_remove_group_pasid(struct iommu_group *group, * @domain: the iommu domain. * @dev: the attached device. * @pasid: the pasid of the device. + * @handle: the attach handle. * * Return: 0 on success, or an error. */ int iommu_attach_device_pasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid) + struct device *dev, ioasid_t pasid, + struct iommu_attach_handle *handle) { /* Caller must be a probed driver on dev */ struct iommu_group *group = dev->iommu_group; struct group_device *device; - void *curr; int ret; if (!domain->ops->set_dev_pasid) @@ -3382,11 +3383,9 @@ int iommu_attach_device_pasid(struct iommu_domain *domain, } } - curr = xa_cmpxchg(&group->pasid_array, pasid, NULL, domain, GFP_KERNEL); - if (curr) { - ret = xa_err(curr) ? : -EBUSY; + ret = xa_insert(&group->pasid_array, pasid, handle, GFP_KERNEL); + if (ret) goto out_unlock; - } ret = __iommu_set_group_pasid(domain, group, pasid); if (ret) @@ -3414,7 +3413,7 @@ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev, mutex_lock(&group->mutex); __iommu_remove_group_pasid(group, pasid, domain); - WARN_ON(xa_erase(&group->pasid_array, pasid) != domain); + xa_erase(&group->pasid_array, pasid); mutex_unlock(&group->mutex); } EXPORT_SYMBOL_GPL(iommu_detach_device_pasid); @@ -3439,15 +3438,19 @@ struct iommu_domain *iommu_get_domain_for_dev_pasid(struct device *dev, { /* Caller must be a probed driver on dev */ struct iommu_group *group = dev->iommu_group; - struct iommu_domain *domain; + struct iommu_attach_handle *handle; + struct iommu_domain *domain = NULL; if (!group) return NULL; xa_lock(&group->pasid_array); - domain = xa_load(&group->pasid_array, pasid); + handle = xa_load(&group->pasid_array, pasid); + if (handle) + domain = handle->domain; + if (type && domain && domain->type != type) - domain = ERR_PTR(-EBUSY); + domain = NULL; xa_unlock(&group->pasid_array); return domain; -- 2.34.1