// SPDX-License-Identifier: GPL-2.0
/*
 * Virtual I/O topology
 *
 * The Virtual I/O Translation Table (VIOT) describes the topology of
 * para-virtual IOMMUs and the endpoints they manage. The OS uses it to
 * initialize devices in the right order, preventing endpoints from issuing DMA
 * before their IOMMU is ready.
 *
 * When binding a driver to a device, before calling the device driver's probe()
 * method, the driver infrastructure calls dma_configure(). At that point the
 * VIOT driver looks for an IOMMU associated to the device in the VIOT table.
 * If an IOMMU exists and has been initialized, the VIOT driver initializes the
 * device's IOMMU fwspec, allowing the DMA infrastructure to invoke the IOMMU
 * ops when the device driver configures DMA mappings. If an IOMMU exists and
 * hasn't yet been initialized, VIOT returns -EPROBE_DEFER to postpone probing
 * the device until the IOMMU is available.
 */
#define pr_fmt(fmt) "ACPI: VIOT: " fmt

#include <linux/acpi_viot.h>
#include <linux/fwnode.h>
#include <linux/iommu.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/platform_device.h>

struct viot_iommu {
	/* Node offset within the table */
	unsigned int			offset;
	struct fwnode_handle		*fwnode;
	struct list_head		list;
};

struct viot_endpoint {
	union {
		/* PCI range */
		struct {
			u16		segment_start;
			u16		segment_end;
			u16		bdf_start;
			u16		bdf_end;
		};
		/* MMIO */
		u64			address;
	};
	u32				endpoint_id;
	struct viot_iommu		*viommu;
	struct list_head		list;
};

static struct acpi_table_viot *viot;
static LIST_HEAD(viot_iommus);
static LIST_HEAD(viot_pci_ranges);
static LIST_HEAD(viot_mmio_endpoints);

static int __init viot_check_bounds(const struct acpi_viot_header *hdr)
{
	struct acpi_viot_header *start, *end, *hdr_end;

	start = ACPI_ADD_PTR(struct acpi_viot_header, viot,
			     max_t(size_t, sizeof(*viot), viot->node_offset));
	end = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->header.length);
	hdr_end = ACPI_ADD_PTR(struct acpi_viot_header, hdr, sizeof(*hdr));

	if (hdr < start || hdr_end > end) {
		pr_err(FW_BUG "Node pointer overflows\n");
		return -EOVERFLOW;
	}
	if (hdr->length < sizeof(*hdr)) {
		pr_err(FW_BUG "Empty node\n");
		return -EINVAL;
	}
	return 0;
}

static int __init viot_get_pci_iommu_fwnode(struct viot_iommu *viommu,
					    u16 segment, u16 bdf)
{
	struct pci_dev *pdev;
	struct fwnode_handle *fwnode;

	pdev = pci_get_domain_bus_and_slot(segment, PCI_BUS_NUM(bdf),
					   bdf & 0xff);
	if (!pdev) {
		pr_err("Could not find PCI IOMMU\n");
		return -ENODEV;
	}

	fwnode = dev_fwnode(&pdev->dev);
	if (!fwnode) {
		/*
		 * PCI devices aren't necessarily described by ACPI. Create a
		 * fwnode so the IOMMU subsystem can identify this device.
		 */
		fwnode = acpi_alloc_fwnode_static();
		if (!fwnode) {
			pci_dev_put(pdev);
			return -ENOMEM;
		}
		set_primary_fwnode(&pdev->dev, fwnode);
	}
	viommu->fwnode = dev_fwnode(&pdev->dev);
	pci_dev_put(pdev);
	return 0;
}

static int __init viot_get_mmio_iommu_fwnode(struct viot_iommu *viommu,
					     u64 address)
{
	struct acpi_device *adev;
	struct resource res = {
		.start	= address,
		.end	= address,
		.flags	= IORESOURCE_MEM,
	};

	adev = acpi_resource_consumer(&res);
	if (!adev) {
		pr_err("Could not find MMIO IOMMU\n");
		return -EINVAL;
	}
	viommu->fwnode = &adev->fwnode;
	return 0;
}

static struct viot_iommu * __init viot_get_iommu(unsigned int offset)
{
	int ret;
	struct viot_iommu *viommu;
	struct acpi_viot_header *hdr = ACPI_ADD_PTR(struct acpi_viot_header,
						    viot, offset);
	union {
		struct acpi_viot_virtio_iommu_pci pci;
		struct acpi_viot_virtio_iommu_mmio mmio;
	} *node = (void *)hdr;

	list_for_each_entry(viommu, &viot_iommus, list)
		if (viommu->offset == offset)
			return viommu;

	if (viot_check_bounds(hdr))
		return NULL;

	viommu = kzalloc(sizeof(*viommu), GFP_KERNEL);
	if (!viommu)
		return NULL;

	viommu->offset = offset;
	switch (hdr->type) {
	case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
		if (hdr->length < sizeof(node->pci))
			goto err_free;

		ret = viot_get_pci_iommu_fwnode(viommu, node->pci.segment,
						node->pci.bdf);
		break;
	case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
		if (hdr->length < sizeof(node->mmio))
			goto err_free;

		ret = viot_get_mmio_iommu_fwnode(viommu,
						 node->mmio.base_address);
		break;
	default:
		ret = -EINVAL;
	}
	if (ret)
		goto err_free;

	list_add(&viommu->list, &viot_iommus);
	return viommu;

err_free:
	kfree(viommu);
	return NULL;
}

static int __init viot_parse_node(const struct acpi_viot_header *hdr)
{
	int ret = -EINVAL;
	struct list_head *list;
	struct viot_endpoint *ep;
	union {
		struct acpi_viot_mmio mmio;
		struct acpi_viot_pci_range pci;
	} *node = (void *)hdr;

	if (viot_check_bounds(hdr))
		return -EINVAL;

	if (hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI ||
	    hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO)
		return 0;

	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
	if (!ep)
		return -ENOMEM;

	switch (hdr->type) {
	case ACPI_VIOT_NODE_PCI_RANGE:
		if (hdr->length < sizeof(node->pci)) {
			pr_err(FW_BUG "Invalid PCI node size\n");
			goto err_free;
		}

		ep->segment_start = node->pci.segment_start;
		ep->segment_end = node->pci.segment_end;
		ep->bdf_start = node->pci.bdf_start;
		ep->bdf_end = node->pci.bdf_end;
		ep->endpoint_id = node->pci.endpoint_start;
		ep->viommu = viot_get_iommu(node->pci.output_node);
		list = &viot_pci_ranges;
		break;
	case ACPI_VIOT_NODE_MMIO:
		if (hdr->length < sizeof(node->mmio)) {
			pr_err(FW_BUG "Invalid MMIO node size\n");
			goto err_free;
		}

		ep->address = node->mmio.base_address;
		ep->endpoint_id = node->mmio.endpoint;
		ep->viommu = viot_get_iommu(node->mmio.output_node);
		list = &viot_mmio_endpoints;
		break;
	default:
		pr_warn("Unsupported node %x\n", hdr->type);
		ret = 0;
		goto err_free;
	}

	if (!ep->viommu) {
		pr_warn("No IOMMU node found\n");
		/*
		 * A future version of the table may use the node for other
		 * purposes. Keep parsing.
		 */
		ret = 0;
		goto err_free;
	}

	list_add(&ep->list, list);
	return 0;

err_free:
	kfree(ep);
	return ret;
}

/**
 * acpi_viot_early_init - Test the presence of VIOT and enable ACS
 *
 * If the VIOT does exist, ACS must be enabled. This cannot be
 * done in acpi_viot_init() which is called after the bus scan
 */
void __init acpi_viot_early_init(void)
{
#ifdef CONFIG_PCI
	acpi_status status;
	struct acpi_table_header *hdr;

	status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
	if (ACPI_FAILURE(status))
		return;
	pci_request_acs();
	acpi_put_table(hdr);
#endif
}

/**
 * acpi_viot_init - Parse the VIOT table
 *
 * Parse the VIOT table, prepare the list of endpoints to be used during DMA
 * setup of devices.
 */
void __init acpi_viot_init(void)
{
	int i;
	acpi_status status;
	struct acpi_table_header *hdr;
	struct acpi_viot_header *node;

	status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
	if (ACPI_FAILURE(status)) {
		if (status != AE_NOT_FOUND) {
			const char *msg = acpi_format_exception(status);

			pr_err("Failed to get table, %s\n", msg);
		}
		return;
	}

	viot = (void *)hdr;

	node = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->node_offset);
	for (i = 0; i < viot->node_count; i++) {
		if (viot_parse_node(node))
			return;

		node = ACPI_ADD_PTR(struct acpi_viot_header, node,
				    node->length);
	}

	acpi_put_table(hdr);
}

static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
			       u32 epid)
{
	if (!viommu || !IS_ENABLED(CONFIG_VIRTIO_IOMMU))
		return -ENODEV;

	/* We're not translating ourself */
	if (device_match_fwnode(dev, viommu->fwnode))
		return -EINVAL;

	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode);
}

static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
{
	u32 epid;
	struct viot_endpoint *ep;
	struct device *aliased_dev = data;
	u32 domain_nr = pci_domain_nr(pdev->bus);

	list_for_each_entry(ep, &viot_pci_ranges, list) {
		if (domain_nr >= ep->segment_start &&
		    domain_nr <= ep->segment_end &&
		    dev_id >= ep->bdf_start &&
		    dev_id <= ep->bdf_end) {
			epid = ((domain_nr - ep->segment_start) << 16) +
				dev_id - ep->bdf_start + ep->endpoint_id;

			return viot_dev_iommu_init(aliased_dev, ep->viommu,
						   epid);
		}
	}
	return -ENODEV;
}

static int viot_mmio_dev_iommu_init(struct platform_device *pdev)
{
	struct resource *mem;
	struct viot_endpoint *ep;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem)
		return -ENODEV;

	list_for_each_entry(ep, &viot_mmio_endpoints, list) {
		if (ep->address == mem->start)
			return viot_dev_iommu_init(&pdev->dev, ep->viommu,
						   ep->endpoint_id);
	}
	return -ENODEV;
}

/**
 * viot_iommu_configure - Setup IOMMU ops for an endpoint described by VIOT
 * @dev: the endpoint
 *
 * Return: 0 on success, <0 on failure
 */
int viot_iommu_configure(struct device *dev)
{
	if (dev_is_pci(dev))
		return pci_for_each_dma_alias(to_pci_dev(dev),
					      viot_pci_dev_iommu_init, dev);
	else if (dev_is_platform(dev))
		return viot_mmio_dev_iommu_init(to_platform_device(dev));
	return -ENODEV;
}
