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-next>] [day] [month] [year] [list]
Message-Id: <20210107093340.15279-1-ajaykumar.rs@samsung.com>
Date:   Thu,  7 Jan 2021 15:03:40 +0530
From:   Ajay Kumar <ajaykumar.rs@...sung.com>
To:     iommu@...ts.linux-foundation.org,
        linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
        joro@...tes.org, robh+dt@...nel.org, mark.rutland@....com,
        will@...nel.org, robin.murphy@....com
Cc:     Ajay Kumar <ajaykumar.rs@...sung.com>
Subject: [PATCH] iommu/arm-smmu-v3: Handle duplicated Stream IDs from other
 masters

When PCI function drivers(ex:pci-endpoint-test) are probed for already
initialized PCIe-RC(Root Complex), and PCIe-RC is already bound to SMMU,
then we encounter a situation where the function driver tries to attach
itself to the smmu with the same stream-id as PCIe-RC and re-initialize
an already initialized STE. This causes ste_live BUG_ON() in the driver.

There is an already existing check in the driver to manage duplicated ids
if duplicated ids are added in same master device, but there can be
scenarios like above where we need to extend the check for other masters
using the same stream-id.

Signed-off-by: Ajay Kumar <ajaykumar.rs@...sung.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index e634bbe60573..a91c3c0e9ee8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2022,10 +2022,26 @@ static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
 	return step;
 }
 
+static bool arm_smmu_check_duplicated_sid(struct arm_smmu_master *master,
+								int sid)
+{
+	int i;
+
+	for (i = 0; i < master->num_sids; ++i)
+		if (master->sids[i] == sid)
+			return true;
+
+	return false;
+}
+
 static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
 {
+	bool sid_in_other_masters;
 	int i, j;
 	struct arm_smmu_device *smmu = master->smmu;
+	unsigned long flags;
+	struct arm_smmu_domain *smmu_domain = master->domain;
+	struct arm_smmu_master *other_masters;
 
 	for (i = 0; i < master->num_sids; ++i) {
 		u32 sid = master->sids[i];
@@ -2038,6 +2054,23 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
 		if (j < i)
 			continue;
 
+		/* Check for stream-ID duplication in masters in given domain */
+		sid_in_other_masters = false;
+		spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+		list_for_each_entry(other_masters, &smmu_domain->devices,
+								domain_head) {
+			sid_in_other_masters =
+				arm_smmu_check_duplicated_sid(other_masters,
+									sid);
+			if (sid_in_other_masters)
+				break;
+		}
+		spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+
+		/* Skip STE re-init if stream-id found in other masters */
+		if (sid_in_other_masters)
+			continue;
+
 		arm_smmu_write_strtab_ent(master, sid, step);
 	}
 }
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ