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

Commit 7931d3dd authored by Vijayanand Jitta's avatar Vijayanand Jitta
Browse files

iommu: add a function to get MID/PID/BID info



For certain use cases SID remains same and when an
smmu page fault occurs it becomes difficult for client
to identify which of the usecases is actually causing
the fault. In such cases MID/PID/BID info can help.
So, add a function for the same so that clients can
call this from their fault handler and get the info.

Change-Id: Ia720641224f908287ae1d66908ab12def82bbbab
Signed-off-by: default avatarVijayanand Jitta <vjitta@codeaurora.org>
parent 1f2a0ad6
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -1271,6 +1271,43 @@ static phys_addr_t arm_smmu_verify_fault(struct iommu_domain *domain,
	return (phys_stimu == 0 ? phys_stimu_post_tlbiall : phys_stimu);
}

int iommu_get_fault_ids(struct iommu_domain *domain,
			struct iommu_fault_ids *f_ids)
{
	struct arm_smmu_domain *smmu_domain;
	struct arm_smmu_device *smmu;
	u32 fsr, fsynr1;
	int idx, ret;

	if (!domain || !f_ids)
		return -EINVAL;

	smmu_domain = to_smmu_domain(domain);
	smmu = smmu_domain->smmu;
	idx = smmu_domain->cfg.cbndx;

	ret = arm_smmu_power_on(smmu->pwr);
	if (ret)
		return ret;

	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);

	if (!(fsr & FSR_FAULT)) {
		arm_smmu_power_off(smmu, smmu->pwr);
		return -EINVAL;
	}

	fsynr1 = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSYNR1);
	arm_smmu_power_off(smmu, smmu->pwr);

	f_ids->bid = FIELD_GET(FSYNR1_BID, fsynr1);
	f_ids->pid = FIELD_GET(FSYNR1_PID, fsynr1);
	f_ids->mid = FIELD_GET(FSYNR1_MID, fsynr1);

	return 0;
}
EXPORT_SYMBOL(iommu_get_fault_ids);

static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
{
	int flags, ret, tmp;
+13 −1
Original line number Diff line number Diff line
@@ -65,6 +65,12 @@ typedef int (*iommu_mm_exit_handler_t)(struct device *dev, struct iommu_sva *,
				       void *);
typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault *, void *);

struct iommu_fault_ids {
	u32 bid;
	u32 pid;
	u32 mid;
};

struct iommu_domain_geometry {
	dma_addr_t aperture_start; /* First address that can be mapped    */
	dma_addr_t aperture_end;   /* Last address that can be mapped     */
@@ -544,7 +550,8 @@ extern bool iommu_is_iova_coherent(struct iommu_domain *domain,
				dma_addr_t iova);
extern void iommu_set_fault_handler(struct iommu_domain *domain,
			iommu_fault_handler_t handler, void *token);

extern int iommu_get_fault_ids(struct iommu_domain *domain,
				struct iommu_fault_ids *f_ids);
extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
extern int iommu_request_dm_for_dev(struct device *dev);
@@ -868,6 +875,11 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain,
				iommu_fault_handler_t handler, void *token)
{
}
static inline int iommu_get_fault_ids(struct iommu_domain *domain,
				struct iommu_fault_ids *f_ids)
{
	return -EINVAL;
}

static inline void iommu_get_resv_regions(struct device *dev,
					struct list_head *list)