Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b02b091 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

x86/amd-iommu: Allow dev_data->alias to be NULL



Let dev_data->alias be just NULL if the device has no alias.

Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent ec9e79ef
Loading
Loading
Loading
Loading
+41 −36
Original line number Diff line number Diff line
@@ -183,6 +183,7 @@ static int iommu_init_device(struct device *dev)
		return -ENOMEM;

	alias = amd_iommu_alias_table[dev_data->devid];
	if (alias != dev_data->devid) {
		pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
		if (pdev)
			dev_data->alias = &pdev->dev;
@@ -190,6 +191,7 @@ static int iommu_init_device(struct device *dev)
			free_dev_data(dev_data);
			return -ENOTSUPP;
		}
	}

	dev->archdata.iommu = dev_data;

@@ -1604,16 +1606,19 @@ static void do_detach(struct iommu_dev_data *dev_data)
static int __attach_device(struct iommu_dev_data *dev_data,
			   struct protection_domain *domain)
{
	struct iommu_dev_data *alias_data;
	int ret;

	/* lock domain */
	spin_lock(&domain->lock);

	if (dev_data->alias != NULL) {
		struct iommu_dev_data *alias_data;

		alias_data = get_dev_data(dev_data->alias);

		ret = -EINVAL;
		if (!alias_data)
		return -EINVAL;

	/* lock domain */
	spin_lock(&domain->lock);
			goto out_unlock;

		/* Some sanity checks */
		ret = -EBUSY;
@@ -1626,7 +1631,6 @@ static int __attach_device(struct iommu_dev_data *dev_data,
			goto out_unlock;

		/* Do real assignment */
	if (dev_data->devid != alias_data->devid) {
		if (alias_data->domain == NULL)
			do_attach(alias_data, domain);

@@ -1696,8 +1700,8 @@ static void __detach_device(struct iommu_dev_data *dev_data)

	spin_lock_irqsave(&domain->lock, flags);

	if (dev_data->alias) {
		alias_data = get_dev_data(dev_data->alias);
	if (dev_data->devid != alias_data->devid) {
		if (atomic_dec_and_test(&alias_data->bind))
			do_detach(alias_data);
	}
@@ -1744,24 +1748,25 @@ static void detach_device(struct device *dev)
 */
static struct protection_domain *domain_for_device(struct device *dev)
{
	struct protection_domain *dom;
	struct iommu_dev_data *dev_data, *alias_data;
	struct protection_domain *dom = NULL;
	unsigned long flags;

	dev_data   = get_dev_data(dev);

	if (dev_data->domain)
		return dev_data->domain;

	if (dev_data->alias != NULL) {
		alias_data = get_dev_data(dev_data->alias);
	if (!alias_data)
		return NULL;

		read_lock_irqsave(&amd_iommu_devtable_lock, flags);
	dom = dev_data->domain;
	if (dom == NULL &&
	    alias_data->domain != NULL) {
		if (alias_data->domain != NULL) {
			__attach_device(dev_data, alias_data->domain);
			dom = alias_data->domain;
		}

		read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
	}

	return dom;
}