Loading arch/arm64/mm/dma-mapping.c +18 −24 Original line number Original line Diff line number Diff line Loading @@ -1979,26 +1979,18 @@ static int upstream_iommu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping) struct dma_iommu_mapping *mapping) { { struct iommu_domain *domain = mapping->domain; struct iommu_domain *domain = mapping->domain; struct iommu_group *group = dev->iommu_group; dma_addr_t base = mapping->base; dma_addr_t base = mapping->base; u64 size = mapping->bits << PAGE_SHIFT; u64 size = mapping->bits << PAGE_SHIFT; if (iommu_get_dma_cookie(domain)) if (iommu_get_dma_cookie(domain)) return -EINVAL; return -EINVAL; /* Need to attach to get geometry */ if (iommu_attach_group(domain, group)) goto out_put_cookie; if (iommu_dma_init_domain(domain, base, size, dev)) if (iommu_dma_init_domain(domain, base, size, dev)) goto out_detach_group; goto out_put_cookie; mapping->ops = &iommu_dma_ops; mapping->ops = &iommu_dma_ops; iommu_detach_group(domain, group); return 0; return 0; out_detach_group: iommu_detach_group(domain, group); out_put_cookie: out_put_cookie: iommu_put_dma_cookie(domain); iommu_put_dma_cookie(domain); return -EINVAL; return -EINVAL; Loading Loading @@ -2060,20 +2052,8 @@ static int arm_iommu_init_mapping(struct device *dev, { { int err = -EINVAL; int err = -EINVAL; int s1_bypass = 0, is_fast = 0, is_upstream = 0; int s1_bypass = 0, is_fast = 0, is_upstream = 0; struct iommu_group *group; dma_addr_t iova_end; dma_addr_t iova_end; group = dev->iommu_group; if (!group) { dev_err(dev, "No iommu associated with device\n"); return -EINVAL; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); return -EINVAL; } if (mapping->init) { if (mapping->init) { kref_get(&mapping->kref); kref_get(&mapping->kref); return 0; return 0; Loading Loading @@ -2128,14 +2108,28 @@ int arm_iommu_attach_device(struct device *dev, struct dma_iommu_mapping *mapping) struct dma_iommu_mapping *mapping) { { int err; int err; struct iommu_domain *domain = mapping->domain; struct iommu_group *group = dev->iommu_group; err = arm_iommu_init_mapping(dev, mapping); if (!group) { dev_err(dev, "No iommu associated with device\n"); return -EINVAL; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); return -EINVAL; } err = iommu_attach_group(domain, group); if (err) if (err) return err; return err; err = iommu_attach_group(mapping->domain, dev->iommu_group); err = arm_iommu_init_mapping(dev, mapping); if (err) if (err) { iommu_detach_group(domain, group); return err; return err; } dev->archdata.mapping = mapping; dev->archdata.mapping = mapping; set_dma_ops(dev, mapping->ops); set_dma_ops(dev, mapping->ops); Loading drivers/iommu/dma-mapping-fast.c +4 −29 Original line number Original line Diff line number Diff line Loading @@ -434,7 +434,8 @@ static int fast_smmu_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, int nents, enum dma_data_direction dir, unsigned long attrs) unsigned long attrs) { { return -EINVAL; /* 0 indicates error */ return 0; } } static void fast_smmu_unmap_sg(struct device *dev, static void fast_smmu_unmap_sg(struct device *dev, Loading Loading @@ -869,7 +870,6 @@ int fast_smmu_init_mapping(struct device *dev, { { int err; int err; struct iommu_domain *domain = mapping->domain; struct iommu_domain *domain = mapping->domain; struct iommu_group *group; struct iommu_pgtbl_info info; struct iommu_pgtbl_info info; u64 size = (u64)mapping->bits << PAGE_SHIFT; u64 size = (u64)mapping->bits << PAGE_SHIFT; Loading @@ -886,51 +886,26 @@ int fast_smmu_init_mapping(struct device *dev, fast_smmu_reserve_pci_windows(dev, mapping->fast); fast_smmu_reserve_pci_windows(dev, mapping->fast); group = dev->iommu_group; if (!group) { dev_err(dev, "No iommu associated with device\n"); err = -ENODEV; goto release_mapping; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); err = -EINVAL; goto release_mapping; } /* * Need to attach prior to calling DOMAIN_ATTR_PGTBL_INFO and then * detach to be in the expected state. Its a bit messy. */ if (iommu_attach_group(mapping->domain, group)) { err = -EINVAL; goto release_mapping; } if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO, if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO, &info)) { &info)) { dev_err(dev, "Couldn't get page table info\n"); dev_err(dev, "Couldn't get page table info\n"); err = -EINVAL; err = -EINVAL; goto detach_group; goto release_mapping; } } mapping->fast->pgtbl_pmds = info.pmds; mapping->fast->pgtbl_pmds = info.pmds; if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, &mapping->fast->is_smmu_pt_coherent)) { &mapping->fast->is_smmu_pt_coherent)) { err = -EINVAL; err = -EINVAL; goto detach_group; goto release_mapping; } } mapping->fast->notifier.notifier_call = fast_smmu_notify; mapping->fast->notifier.notifier_call = fast_smmu_notify; av8l_register_notify(&mapping->fast->notifier); av8l_register_notify(&mapping->fast->notifier); iommu_detach_group(mapping->domain, group); mapping->ops = &fast_smmu_dma_ops; mapping->ops = &fast_smmu_dma_ops; return 0; return 0; detach_group: iommu_detach_group(mapping->domain, group); release_mapping: release_mapping: kfree(mapping->fast->bitmap); kfree(mapping->fast->bitmap); kfree(mapping->fast); kfree(mapping->fast); Loading Loading
arch/arm64/mm/dma-mapping.c +18 −24 Original line number Original line Diff line number Diff line Loading @@ -1979,26 +1979,18 @@ static int upstream_iommu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping) struct dma_iommu_mapping *mapping) { { struct iommu_domain *domain = mapping->domain; struct iommu_domain *domain = mapping->domain; struct iommu_group *group = dev->iommu_group; dma_addr_t base = mapping->base; dma_addr_t base = mapping->base; u64 size = mapping->bits << PAGE_SHIFT; u64 size = mapping->bits << PAGE_SHIFT; if (iommu_get_dma_cookie(domain)) if (iommu_get_dma_cookie(domain)) return -EINVAL; return -EINVAL; /* Need to attach to get geometry */ if (iommu_attach_group(domain, group)) goto out_put_cookie; if (iommu_dma_init_domain(domain, base, size, dev)) if (iommu_dma_init_domain(domain, base, size, dev)) goto out_detach_group; goto out_put_cookie; mapping->ops = &iommu_dma_ops; mapping->ops = &iommu_dma_ops; iommu_detach_group(domain, group); return 0; return 0; out_detach_group: iommu_detach_group(domain, group); out_put_cookie: out_put_cookie: iommu_put_dma_cookie(domain); iommu_put_dma_cookie(domain); return -EINVAL; return -EINVAL; Loading Loading @@ -2060,20 +2052,8 @@ static int arm_iommu_init_mapping(struct device *dev, { { int err = -EINVAL; int err = -EINVAL; int s1_bypass = 0, is_fast = 0, is_upstream = 0; int s1_bypass = 0, is_fast = 0, is_upstream = 0; struct iommu_group *group; dma_addr_t iova_end; dma_addr_t iova_end; group = dev->iommu_group; if (!group) { dev_err(dev, "No iommu associated with device\n"); return -EINVAL; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); return -EINVAL; } if (mapping->init) { if (mapping->init) { kref_get(&mapping->kref); kref_get(&mapping->kref); return 0; return 0; Loading Loading @@ -2128,14 +2108,28 @@ int arm_iommu_attach_device(struct device *dev, struct dma_iommu_mapping *mapping) struct dma_iommu_mapping *mapping) { { int err; int err; struct iommu_domain *domain = mapping->domain; struct iommu_group *group = dev->iommu_group; err = arm_iommu_init_mapping(dev, mapping); if (!group) { dev_err(dev, "No iommu associated with device\n"); return -EINVAL; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); return -EINVAL; } err = iommu_attach_group(domain, group); if (err) if (err) return err; return err; err = iommu_attach_group(mapping->domain, dev->iommu_group); err = arm_iommu_init_mapping(dev, mapping); if (err) if (err) { iommu_detach_group(domain, group); return err; return err; } dev->archdata.mapping = mapping; dev->archdata.mapping = mapping; set_dma_ops(dev, mapping->ops); set_dma_ops(dev, mapping->ops); Loading
drivers/iommu/dma-mapping-fast.c +4 −29 Original line number Original line Diff line number Diff line Loading @@ -434,7 +434,8 @@ static int fast_smmu_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, int nents, enum dma_data_direction dir, unsigned long attrs) unsigned long attrs) { { return -EINVAL; /* 0 indicates error */ return 0; } } static void fast_smmu_unmap_sg(struct device *dev, static void fast_smmu_unmap_sg(struct device *dev, Loading Loading @@ -869,7 +870,6 @@ int fast_smmu_init_mapping(struct device *dev, { { int err; int err; struct iommu_domain *domain = mapping->domain; struct iommu_domain *domain = mapping->domain; struct iommu_group *group; struct iommu_pgtbl_info info; struct iommu_pgtbl_info info; u64 size = (u64)mapping->bits << PAGE_SHIFT; u64 size = (u64)mapping->bits << PAGE_SHIFT; Loading @@ -886,51 +886,26 @@ int fast_smmu_init_mapping(struct device *dev, fast_smmu_reserve_pci_windows(dev, mapping->fast); fast_smmu_reserve_pci_windows(dev, mapping->fast); group = dev->iommu_group; if (!group) { dev_err(dev, "No iommu associated with device\n"); err = -ENODEV; goto release_mapping; } if (iommu_get_domain_for_dev(dev)) { dev_err(dev, "Device already attached to other iommu_domain\n"); err = -EINVAL; goto release_mapping; } /* * Need to attach prior to calling DOMAIN_ATTR_PGTBL_INFO and then * detach to be in the expected state. Its a bit messy. */ if (iommu_attach_group(mapping->domain, group)) { err = -EINVAL; goto release_mapping; } if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO, if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO, &info)) { &info)) { dev_err(dev, "Couldn't get page table info\n"); dev_err(dev, "Couldn't get page table info\n"); err = -EINVAL; err = -EINVAL; goto detach_group; goto release_mapping; } } mapping->fast->pgtbl_pmds = info.pmds; mapping->fast->pgtbl_pmds = info.pmds; if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, &mapping->fast->is_smmu_pt_coherent)) { &mapping->fast->is_smmu_pt_coherent)) { err = -EINVAL; err = -EINVAL; goto detach_group; goto release_mapping; } } mapping->fast->notifier.notifier_call = fast_smmu_notify; mapping->fast->notifier.notifier_call = fast_smmu_notify; av8l_register_notify(&mapping->fast->notifier); av8l_register_notify(&mapping->fast->notifier); iommu_detach_group(mapping->domain, group); mapping->ops = &fast_smmu_dma_ops; mapping->ops = &fast_smmu_dma_ops; return 0; return 0; detach_group: iommu_detach_group(mapping->domain, group); release_mapping: release_mapping: kfree(mapping->fast->bitmap); kfree(mapping->fast->bitmap); kfree(mapping->fast); kfree(mapping->fast); Loading