lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20240628-jag-revisit_cache_tag_assign-v1-3-a0c19063c983@samsung.com>
Date: Fri, 28 Jun 2024 14:27:41 +0200
From: Joel Granados via B4 Relay <devnull+j.granados.samsung.com@...nel.org>
To: David Woodhouse <dwmw2@...radead.org>, 
 Lu Baolu <baolu.lu@...ux.intel.com>, Joerg Roedel <joro@...tes.org>, 
 Will Deacon <will@...nel.org>, Robin Murphy <robin.murphy@....com>
Cc: iommu@...ts.linux.dev, linux-kernel@...r.kernel.org, 
 Joel Granados <j.granados@...sung.com>
Subject: [PATCH RFC 3/5] iommu/vt-d: Pass cache_tag_id to {un}assignment
 functions

From: Joel Granados <j.granados@...sung.com>

Replace passing 4 arguments (domain id, pasid, cache type and device)
with just one cache_tag_id.

Signed-off-by: Joel Granados <j.granados@...sung.com>
---
 drivers/iommu/intel/cache.c | 120 ++++++++++++++++++++------------------------
 1 file changed, 54 insertions(+), 66 deletions(-)

diff --git a/drivers/iommu/intel/cache.c b/drivers/iommu/intel/cache.c
index b50ec5520871..eb409a296e43 100644
--- a/drivers/iommu/intel/cache.c
+++ b/drivers/iommu/intel/cache.c
@@ -38,40 +38,26 @@ static bool cache_tag_cmp(const struct cache_tag_id *left,
 }
 
 /* Assign a cache tag with specified type to domain. */
-static int cache_tag_assign(struct dmar_domain *domain, u16 did,
-			    struct device *dev, ioasid_t pasid,
-			    enum cache_tag_type type)
+static int cache_tag_assign_type(struct dmar_domain *domain,
+				 struct cache_tag_id const *tag_id,
+				 enum cache_tag_type tag_type)
 {
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-	struct intel_iommu *iommu = info->iommu;
 	struct cache_tag *tag, *temp;
 	unsigned long flags;
-	struct cache_tag_id cmp_tag = {
-		.type = type,
-		.pasid = pasid,
-		.iommu = info->iommu,
-		.dev = dev,
-		.domain_id = did
-	};
 
 	tag = kzalloc(sizeof(*tag), GFP_KERNEL);
 	if (!tag)
 		return -ENOMEM;
 
-	tag->id.type = type;
-	tag->id.iommu = iommu;
-	tag->id.domain_id = did;
-	tag->id.pasid = pasid;
+	tag->id = *tag_id;
+	tag->id.type = tag_type;
+	if (tag_id->type != CACHE_TAG_DEVTLB && tag_id->type != CACHE_TAG_NESTING_DEVTLB)
+		tag->id.dev = tag_id->iommu->iommu.dev;
 	tag->users = 1;
 
-	if (type == CACHE_TAG_DEVTLB || type == CACHE_TAG_NESTING_DEVTLB)
-		tag->id.dev = dev;
-	else
-		tag->id.dev = iommu->iommu.dev;
-
 	spin_lock_irqsave(&domain->cache_lock, flags);
 	list_for_each_entry(temp, &domain->cache_tags, node) {
-		if (cache_tag_cmp(&temp->id, &cmp_tag)) {
+		if (cache_tag_cmp(&temp->id, tag_id)) {
 			temp->users++;
 			spin_unlock_irqrestore(&domain->cache_lock, flags);
 			kfree(tag);
@@ -87,25 +73,17 @@ static int cache_tag_assign(struct dmar_domain *domain, u16 did,
 }
 
 /* Unassign a cache tag with specified type from domain. */
-static void cache_tag_unassign(struct dmar_domain *domain, u16 did,
-			       struct device *dev, ioasid_t pasid,
-			       enum cache_tag_type type)
+static void cache_tag_unassign_type(struct dmar_domain *domain,
+				    struct cache_tag_id *tag_id,
+				    enum cache_tag_type tag_type)
 {
 	struct cache_tag *tag;
 	unsigned long flags;
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-	struct cache_tag_id cmp_tag = {
-		.type = type,
-		.pasid = pasid,
-		.iommu = info->iommu,
-		.dev = dev,
-		.domain_id = did
-	};
-
 
+	tag_id->type = tag_type;
 	spin_lock_irqsave(&domain->cache_lock, flags);
 	list_for_each_entry(tag, &domain->cache_tags, node) {
-		if (cache_tag_cmp(&tag->id, &cmp_tag)) {
+		if (cache_tag_cmp(&tag->id, tag_id)) {
 			trace_cache_tag_unassign(tag);
 			if (--tag->users == 0) {
 				list_del(&tag->node);
@@ -117,60 +95,58 @@ static void cache_tag_unassign(struct dmar_domain *domain, u16 did,
 	spin_unlock_irqrestore(&domain->cache_lock, flags);
 }
 
-static int __cache_tag_assign_domain(struct dmar_domain *domain, u16 did,
-				     struct device *dev, ioasid_t pasid)
+static int __cache_tag_assign_domain(struct dmar_domain *domain,
+				     struct cache_tag_id *new_tag_id)
 {
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct device_domain_info *info = dev_iommu_priv_get(new_tag_id->dev);
 	int ret;
 
-	ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
+	ret = cache_tag_assign_type(domain, new_tag_id, CACHE_TAG_IOTLB);
 	if (ret || !info->ats_enabled)
 		return ret;
 
-	ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_DEVTLB);
+	ret = cache_tag_assign_type(domain, new_tag_id, CACHE_TAG_DEVTLB);
 	if (ret)
-		cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
+		cache_tag_unassign_type(domain, new_tag_id, CACHE_TAG_IOTLB);
 
 	return ret;
 }
 
-static void __cache_tag_unassign_domain(struct dmar_domain *domain, u16 did,
-					struct device *dev, ioasid_t pasid)
+static void __cache_tag_unassign_domain(struct dmar_domain *domain,
+					struct cache_tag_id *tag_id)
 {
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-
-	cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
+	struct device_domain_info *info = dev_iommu_priv_get(tag_id->dev);
 
+	cache_tag_unassign_type(domain, tag_id, CACHE_TAG_IOTLB);
 	if (info->ats_enabled)
-		cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_DEVTLB);
+		cache_tag_unassign_type(domain, tag_id, CACHE_TAG_DEVTLB);
 }
 
-static int __cache_tag_assign_parent_domain(struct dmar_domain *domain, u16 did,
-					    struct device *dev, ioasid_t pasid)
+static int __cache_tag_assign_parent_domain(struct dmar_domain *domain,
+					    struct cache_tag_id *new_tag_id)
 {
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct device_domain_info *info = dev_iommu_priv_get(new_tag_id->dev);
 	int ret;
 
-	ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB);
+	ret = cache_tag_assign_type(domain, new_tag_id, CACHE_TAG_NESTING_IOTLB);
 	if (ret || !info->ats_enabled)
 		return ret;
 
-	ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_NESTING_DEVTLB);
+	ret = cache_tag_assign_type(domain, new_tag_id, CACHE_TAG_NESTING_DEVTLB);
 	if (ret)
-		cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB);
+		cache_tag_unassign_type(domain, new_tag_id, CACHE_TAG_NESTING_IOTLB);
 
 	return ret;
 }
 
-static void __cache_tag_unassign_parent_domain(struct dmar_domain *domain, u16 did,
-					       struct device *dev, ioasid_t pasid)
+static void __cache_tag_unassign_parent_domain(struct dmar_domain *domain,
+					       struct cache_tag_id *tag_id)
 {
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-
-	cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB);
+	struct device_domain_info *info = dev_iommu_priv_get(tag_id->dev);
 
+	cache_tag_unassign_type(domain, tag_id, CACHE_TAG_NESTING_IOTLB);
 	if (info->ats_enabled)
-		cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_NESTING_DEVTLB);
+		cache_tag_unassign_type(domain, tag_id, CACHE_TAG_NESTING_DEVTLB);
 }
 
 static u16 domain_get_id_for_dev(struct dmar_domain *domain, struct device *dev)
@@ -199,16 +175,22 @@ static u16 domain_get_id_for_dev(struct dmar_domain *domain, struct device *dev)
 int cache_tag_assign_domain(struct dmar_domain *domain,
 			    struct device *dev, ioasid_t pasid)
 {
-	u16 did = domain_get_id_for_dev(domain, dev);
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct cache_tag_id new_tag_id = {
+		.pasid = pasid,
+		.iommu = info->iommu,
+		.dev = dev,
+		.domain_id = domain_get_id_for_dev(domain, dev),
+	};
 	int ret;
 
-	ret = __cache_tag_assign_domain(domain, did, dev, pasid);
+	ret = __cache_tag_assign_domain(domain, &new_tag_id);
 	if (ret || domain->domain.type != IOMMU_DOMAIN_NESTED)
 		return ret;
 
-	ret = __cache_tag_assign_parent_domain(domain->s2_domain, did, dev, pasid);
+	ret = __cache_tag_assign_parent_domain(domain->s2_domain, &new_tag_id);
 	if (ret)
-		__cache_tag_unassign_domain(domain, did, dev, pasid);
+		__cache_tag_unassign_domain(domain, &new_tag_id);
 
 	return ret;
 }
@@ -223,11 +205,17 @@ int cache_tag_assign_domain(struct dmar_domain *domain,
 void cache_tag_unassign_domain(struct dmar_domain *domain,
 			       struct device *dev, ioasid_t pasid)
 {
-	u16 did = domain_get_id_for_dev(domain, dev);
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct cache_tag_id tag_id = {
+		.pasid = pasid,
+		.iommu = info->iommu,
+		.dev = dev,
+		.domain_id = domain_get_id_for_dev(domain, dev)
+	};
 
-	__cache_tag_unassign_domain(domain, did, dev, pasid);
+	__cache_tag_unassign_domain(domain, &tag_id);
 	if (domain->domain.type == IOMMU_DOMAIN_NESTED)
-		__cache_tag_unassign_parent_domain(domain->s2_domain, did, dev, pasid);
+		__cache_tag_unassign_parent_domain(domain->s2_domain, &tag_id);
 }
 
 static unsigned long calculate_psi_aligned_address(unsigned long start,

-- 
2.43.0



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ