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  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 29 Nov 2023 21:10:30 -0400
From: Jason Gunthorpe <jgg@...dia.com>
To: acpica-devel@...ts.linux.dev,
	Andy Gross <agross@...nel.org>,
	Alim Akhtar <alim.akhtar@...sung.com>,
	Alyssa Rosenzweig <alyssa@...enzweig.io>,
	Bjorn Andersson <andersson@...nel.org>,
	AngeloGioacchino Del Regno <angelogioacchino.delregno@...labora.com>,
	asahi@...ts.linux.dev,
	Baolin Wang <baolin.wang@...ux.alibaba.com>,
	devicetree@...r.kernel.org,
	Frank Rowand <frowand.list@...il.com>,
	Hanjun Guo <guohanjun@...wei.com>,
	"Gustavo A. R. Silva" <gustavoars@...nel.org>,
	Heiko Stuebner <heiko@...ech.de>,
	iommu@...ts.linux.dev,
	Jean-Philippe Brucker <jean-philippe@...aro.org>,
	Jernej Skrabec <jernej.skrabec@...il.com>,
	Jonathan Hunter <jonathanh@...dia.com>,
	Joerg Roedel <joro@...tes.org>,
	Kees Cook <keescook@...omium.org>,
	Konrad Dybcio <konrad.dybcio@...aro.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>,
	Len Brown <lenb@...nel.org>,
	linux-acpi@...r.kernel.org,
	linux-arm-kernel@...ts.infradead.org,
	linux-arm-msm@...r.kernel.org,
	linux-hardening@...r.kernel.org,
	linux-mediatek@...ts.infradead.org,
	linux-rockchip@...ts.infradead.org,
	linux-samsung-soc@...r.kernel.org,
	linux-sunxi@...ts.linux.dev,
	linux-tegra@...r.kernel.org,
	Lorenzo Pieralisi <lpieralisi@...nel.org>,
	Marek Szyprowski <m.szyprowski@...sung.com>,
	Hector Martin <marcan@...can.st>,
	Matthias Brugger <matthias.bgg@...il.com>,
	Orson Zhai <orsonzhai@...il.com>,
	"Rafael J. Wysocki" <rafael@...nel.org>,
	Rob Clark <robdclark@...il.com>,
	Robert Moore <robert.moore@...el.com>,
	Rob Herring <robh+dt@...nel.org>,
	Robin Murphy <robin.murphy@....com>,
	Samuel Holland <samuel@...lland.org>,
	Sudeep Holla <sudeep.holla@....com>,
	Sven Peter <sven@...npeter.dev>,
	Thierry Reding <thierry.reding@...il.com>,
	Krishna Reddy <vdumpa@...dia.com>,
	virtualization@...ts.linux.dev,
	Chen-Yu Tsai <wens@...e.org>,
	Will Deacon <will@...nel.org>,
	Yong Wu <yong.wu@...iatek.com>,
	Chunyan Zhang <zhang.lyra@...il.com>
Cc: André Draszik <andre.draszik@...aro.org>,
	patches@...ts.linux.dev
Subject: [PATCH 23/30] iommu/viot: Add iommu_viot_get_single_iommu()

This is the ACPI VIOT version like iommu_of_get_single_iommu().

It parses the ACPI table, confirms all entries points to a single
iommu_driver and then returns a pointer to it.

Also cache the u32 id list in the iommu_probe_info and provide a getter
function which re-parses in case we overflow the cache.

Signed-off-by: Jason Gunthorpe <jgg@...dia.com>
---
 drivers/acpi/scan.c          |  1 +
 drivers/iommu/Makefile       |  1 +
 drivers/iommu/viot_iommu.c   | 70 ++++++++++++++++++++++++++++++++++++
 include/linux/iommu-driver.h | 25 +++++++++++++
 4 files changed, 97 insertions(+)
 create mode 100644 drivers/iommu/viot_iommu.c

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index de36299c3b75bf..9ec01196573b6e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1571,6 +1571,7 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 	struct iommu_probe_info pinf = {
 		.dev = dev,
 		.is_dma_configure = true,
+		.is_acpi = true,
 	};
 
 	/* Serialise to make dev->iommu stable under our potential fwspec */
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 95ad9dbfbda022..9c35b106cecb2e 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_DART) += io-pgtable-dart.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU)	+= of_iommu.o
+obj-$(CONFIG_ACPI_VIOT)	+= viot_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
diff --git a/drivers/iommu/viot_iommu.c b/drivers/iommu/viot_iommu.c
new file mode 100644
index 00000000000000..e35bd4099e6c6a
--- /dev/null
+++ b/drivers/iommu/viot_iommu.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES
+ */
+#include <linux/acpi_viot.h>
+#include <linux/iommu.h>
+#include <linux/iommu-driver.h>
+
+struct parse_info {
+	struct iommu_probe_info *pinf;
+	const struct iommu_ops *ops;
+	u32 *ids;
+};
+
+static int parse_single_iommu(struct viot_iommu *viommu, u32 epid, void *_info)
+{
+	struct fwnode_handle *fwnode = viommu->fwnode;
+	struct parse_info *info = _info;
+	struct iommu_probe_info *pinf = info->pinf;
+	struct iommu_device *iommu;
+
+	/* We're not translating ourself */
+	if (device_match_fwnode(pinf->dev, fwnode))
+		return -ENODEV;
+
+	iommu = iommu_device_from_fwnode_pinf(pinf, info->ops, fwnode);
+	if (IS_ERR(iommu)) {
+		if (!IS_ENABLED(CONFIG_VIRTIO_IOMMU) &&
+		    iommu == ERR_PTR(-EPROBE_DEFER))
+			return -ENODEV;
+		return PTR_ERR(iommu);
+	}
+	iommu_fw_cache_id(pinf, epid);
+	return 0;
+}
+
+static int parse_read_ids(struct viot_iommu *viommu, u32 epid, void *_info)
+{
+	struct parse_info *info = _info;
+
+	*info->ids = epid;
+	(*info->ids)++;
+	return 0;
+}
+
+static int viot_get_u32_ids(struct iommu_probe_info *pinf, u32 *ids)
+{
+	struct parse_info info = { .pinf = pinf, .ids = ids };
+
+	return viot_iommu_for_each_id(pinf->dev, parse_read_ids, &info);
+}
+
+struct iommu_device *
+__iommu_viot_get_single_iommu(struct iommu_probe_info *pinf,
+			      const struct iommu_ops *ops)
+{
+	struct parse_info info = { .pinf = pinf, .ops = ops };
+	int err;
+
+	if (!pinf->is_dma_configure || !pinf->is_acpi)
+		return ERR_PTR(-ENODEV);
+
+	iommu_fw_clear_cache(pinf);
+	err = viot_iommu_for_each_id(pinf->dev, parse_single_iommu, &info);
+	if (err)
+		return ERR_PTR(err);
+	pinf->get_u32_ids = viot_get_u32_ids;
+	return iommu_fw_finish_get_single(pinf);
+}
+EXPORT_SYMBOL(__iommu_viot_get_single_iommu);
diff --git a/include/linux/iommu-driver.h b/include/linux/iommu-driver.h
index 632c7b4a389abe..ce0ba1f35bb5dc 100644
--- a/include/linux/iommu-driver.h
+++ b/include/linux/iommu-driver.h
@@ -45,6 +45,7 @@ struct iommu_probe_info {
 	u32 cached_ids[8];
 	bool defer_setup : 1;
 	bool is_dma_configure : 1;
+	bool is_acpi : 1;
 	bool cached_single_iommu : 1;
 };
 
@@ -188,4 +189,28 @@ static inline int iommu_dummy_of_xlate(struct device *dev,
 	return 0;
 }
 
+#define __iommu_first(a, b)                              \
+	({                                               \
+		struct iommu_device *a_dev = a;          \
+		a_dev != ERR_PTR(-ENODEV) ? a_dev : (b); \
+	})
+
+#if IS_ENABLED(CONFIG_ACPI_VIOT)
+struct iommu_device *
+__iommu_viot_get_single_iommu(struct iommu_probe_info *pinf,
+			      const struct iommu_ops *ops);
+#else
+static inline struct iommu_device *
+__iommu_viot_get_single_iommu(struct iommu_probe_info *pinf,
+			      const struct iommu_ops *ops)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif
+#define iommu_viot_get_single_iommu(pinf, ops, drv_struct, member)         \
+	container_of_err(                                                  \
+		__iommu_first(__iommu_viot_get_single_iommu(pinf, ops),    \
+			      __iommu_of_get_single_iommu(pinf, ops, -1)), \
+		drv_struct, member)
+
 #endif
-- 
2.42.0


Powered by blists - more mailing lists