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] [thread-next>] [day] [month] [year] [list]
Date: Wed, 29 Nov 2023 21:10:31 -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 24/30] iommu/virtio: Move to iommu_fw_alloc_per_device_ids()

virtio supports a single iommu instance with multiple ids.

It has a combined ACPI (via the VIOT table) and OF probe path, add
iommu_viot_get_single_iommu() to respresent this.

It already has a per-instance structure, extend it with the ids[]
array and use iommu_fw_alloc_per_device_ids() to populate it.

Convert the rest of the funcs from calling dev_iommu_fwspec_get() to using
he per-device data and remove all use of fwspec.

Signed-off-by: Jason Gunthorpe <jgg@...dia.com>
---
 drivers/iommu/virtio-iommu.c | 67 +++++++++++++-----------------------
 1 file changed, 23 insertions(+), 44 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index b1a7b14a6c7a2f..767919bf848999 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -77,6 +77,8 @@ struct viommu_endpoint {
 	struct viommu_dev		*viommu;
 	struct viommu_domain		*vdomain;
 	struct list_head		resv_regions;
+	unsigned int			num_ids;
+	u32				ids[] __counted_by(num_ids);
 };
 
 struct viommu_request {
@@ -510,19 +512,16 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev,
 	return 0;
 }
 
-static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev)
+static int viommu_probe_endpoint(struct viommu_endpoint *vdev)
 {
 	int ret;
 	u16 type, len;
 	size_t cur = 0;
 	size_t probe_len;
+	struct device *dev = vdev->dev;
 	struct virtio_iommu_req_probe *probe;
 	struct virtio_iommu_probe_property *prop;
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
-
-	if (!fwspec->num_ids)
-		return -EINVAL;
+	struct viommu_dev *viommu = vdev->viommu;
 
 	probe_len = sizeof(*probe) + viommu->probe_size +
 		    sizeof(struct virtio_iommu_req_tail);
@@ -535,7 +534,7 @@ static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev)
 	 * For now, assume that properties of an endpoint that outputs multiple
 	 * IDs are consistent. Only probe the first one.
 	 */
-	probe->endpoint = cpu_to_le32(fwspec->ids[0]);
+	probe->endpoint = cpu_to_le32(vdev->ids[0]);
 
 	ret = viommu_send_req_sync(viommu, probe, probe_len);
 	if (ret)
@@ -721,7 +720,6 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	int i;
 	int ret = 0;
 	struct virtio_iommu_req_attach req;
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
 	struct viommu_domain *vdomain = to_viommu_domain(domain);
 
@@ -763,8 +761,8 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	if (vdomain->bypass)
 		req.flags |= cpu_to_le32(VIRTIO_IOMMU_ATTACH_F_BYPASS);
 
-	for (i = 0; i < fwspec->num_ids; i++) {
-		req.endpoint = cpu_to_le32(fwspec->ids[i]);
+	for (i = 0; i < vdev->num_ids; i++) {
+		req.endpoint = cpu_to_le32(vdev->ids[i]);
 
 		ret = viommu_send_req_sync(vdomain->viommu, &req, sizeof(req));
 		if (ret)
@@ -792,7 +790,6 @@ static void viommu_detach_dev(struct viommu_endpoint *vdev)
 	int i;
 	struct virtio_iommu_req_detach req;
 	struct viommu_domain *vdomain = vdev->vdomain;
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev);
 
 	if (!vdomain)
 		return;
@@ -802,8 +799,8 @@ static void viommu_detach_dev(struct viommu_endpoint *vdev)
 		.domain		= cpu_to_le32(vdomain->id),
 	};
 
-	for (i = 0; i < fwspec->num_ids; i++) {
-		req.endpoint = cpu_to_le32(fwspec->ids[i]);
+	for (i = 0; i < vdev->num_ids; i++) {
+		req.endpoint = cpu_to_le32(vdev->ids[i]);
 		WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req)));
 	}
 	vdomain->nr_endpoints--;
@@ -974,34 +971,21 @@ static void viommu_get_resv_regions(struct device *dev, struct list_head *head)
 static struct iommu_ops viommu_ops;
 static struct virtio_driver virtio_iommu_drv;
 
-static int viommu_match_node(struct device *dev, const void *data)
-{
-	return device_match_fwnode(dev->parent, data);
-}
-
-static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode)
-{
-	struct device *dev = driver_find_device(&virtio_iommu_drv.driver, NULL,
-						fwnode, viommu_match_node);
-	put_device(dev);
-
-	return dev ? dev_to_virtio(dev)->priv : NULL;
-}
-
-static struct iommu_device *viommu_probe_device(struct device *dev)
+static struct iommu_device *viommu_probe_device(struct iommu_probe_info *pinf)
 {
 	int ret;
+	struct viommu_dev *viommu;
 	struct viommu_endpoint *vdev;
-	struct viommu_dev *viommu = NULL;
-	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct device *dev = pinf->dev;
 
-	viommu = viommu_get_by_fwnode(fwspec->iommu_fwnode);
-	if (!viommu)
-		return ERR_PTR(-ENODEV);
+	viommu = iommu_viot_get_single_iommu(pinf, &viommu_ops,
+					     struct viommu_dev, iommu);
+	if (IS_ERR(viommu))
+		return ERR_CAST(viommu);
 
-	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
-	if (!vdev)
-		return ERR_PTR(-ENOMEM);
+	vdev = iommu_fw_alloc_per_device_ids(pinf, vdev);
+	if (IS_ERR(vdev))
+		return ERR_CAST(vdev);
 
 	vdev->dev = dev;
 	vdev->viommu = viommu;
@@ -1010,7 +994,7 @@ static struct iommu_device *viommu_probe_device(struct device *dev)
 
 	if (viommu->probe_size) {
 		/* Get additional information for this endpoint */
-		ret = viommu_probe_endpoint(viommu, dev);
+		ret = viommu_probe_endpoint(vdev);
 		if (ret)
 			goto err_free_dev;
 	}
@@ -1050,11 +1034,6 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
-{
-	return iommu_fwspec_add_ids(dev, args->args, 1);
-}
-
 static bool viommu_capable(struct device *dev, enum iommu_cap cap)
 {
 	switch (cap) {
@@ -1070,12 +1049,12 @@ static bool viommu_capable(struct device *dev, enum iommu_cap cap)
 static struct iommu_ops viommu_ops = {
 	.capable		= viommu_capable,
 	.domain_alloc		= viommu_domain_alloc,
-	.probe_device		= viommu_probe_device,
+	.probe_device_pinf	= viommu_probe_device,
 	.probe_finalize		= viommu_probe_finalize,
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
-	.of_xlate		= viommu_of_xlate,
+	.of_xlate		= iommu_dummy_of_xlate,
 	.owner			= THIS_MODULE,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= viommu_attach_dev,
-- 
2.42.0


Powered by blists - more mailing lists