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

Commit 100eafb2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu/arm-smmu: avoid calling request_irq in atomic context"

parents dda68784 778f9aa4
Loading
Loading
Loading
Loading
+25 −22
Original line number Diff line number Diff line
@@ -868,10 +868,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
static int arm_smmu_init_domain_context(struct iommu_domain *domain,
					struct arm_smmu_device *smmu)
{
	int irq, ret, start;
	int irq, start, ret = 0;
	unsigned long flags;
	struct arm_smmu_domain *smmu_domain = domain->priv;
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;

	spin_lock_irqsave(&smmu_domain->lock, flags);
	if (smmu_domain->smmu)
		goto out_unlock;

	if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) {
		/*
		 * We will likely want to change this if/when KVM gets
@@ -890,7 +895,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
	ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
				      smmu->num_context_banks);
	if (IS_ERR_VALUE(ret))
		return ret;
		goto out_unlock;

	cfg->cbndx = ret;
	if (smmu->version == 1) {
@@ -900,6 +905,10 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		cfg->irptndx = cfg->cbndx;
	}

	ACCESS_ONCE(smmu_domain->smmu) = smmu;
	arm_smmu_init_context_bank(smmu_domain);
	spin_unlock_irqrestore(&smmu_domain->lock, flags);

	irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
	ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED,
			  "arm-smmu-context-fault", domain);
@@ -907,15 +916,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
			cfg->irptndx, irq);
		cfg->irptndx = INVALID_IRPTNDX;
		goto out_free_context;
	}

	smmu_domain->smmu = smmu;
	arm_smmu_init_context_bank(smmu_domain);
	return 0;

out_free_context:
	__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
out_unlock:
	spin_unlock_irqrestore(&smmu_domain->lock, flags);
	return ret;
}

@@ -1172,11 +1178,10 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,

static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
	int ret = -EINVAL;
	int ret;
	struct arm_smmu_domain *smmu_domain = domain->priv;
	struct arm_smmu_device *smmu;
	struct arm_smmu_device *smmu, *dom_smmu;
	struct arm_smmu_master_cfg *cfg;
	unsigned long flags;

	smmu = dev_get_master_dev(dev)->archdata.iommu;
	if (!smmu) {
@@ -1188,20 +1193,22 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
	 * Sanity check the domain. We don't support domains across
	 * different SMMUs.
	 */
	spin_lock_irqsave(&smmu_domain->lock, flags);
	if (!smmu_domain->smmu) {
	dom_smmu = ACCESS_ONCE(smmu_domain->smmu);
	if (!dom_smmu) {
		/* Now that we have a master, we can finalise the domain */
		ret = arm_smmu_init_domain_context(domain, smmu);
		if (IS_ERR_VALUE(ret))
			goto err_unlock;
	} else if (smmu_domain->smmu != smmu) {
			return ret;

		dom_smmu = smmu_domain->smmu;
	}

	if (dom_smmu != smmu) {
		dev_err(dev,
			"cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n",
			dev_name(smmu_domain->smmu->dev),
			dev_name(smmu->dev));
		goto err_unlock;
			dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
		return -EINVAL;
	}
	spin_unlock_irqrestore(&smmu_domain->lock, flags);

	/* Looks ok, so add the device to the domain */
	cfg = find_smmu_master_cfg(smmu_domain->smmu, dev);
@@ -1209,10 +1216,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
		return -ENODEV;

	return arm_smmu_domain_add_master(smmu_domain, cfg);

err_unlock:
	spin_unlock_irqrestore(&smmu_domain->lock, flags);
	return ret;
}

static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)