Loading drivers/iommu/arm-smmu.c +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading include/linux/iommu.h +13 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -543,7 +549,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); Loading Loading @@ -867,6 +874,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) Loading Loading
drivers/iommu/arm-smmu.c +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
include/linux/iommu.h +13 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -543,7 +549,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); Loading Loading @@ -867,6 +874,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) Loading