Loading arch/arm64/configs/vendor/lahaina_QGKI.config +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ CONFIG_CMA_DIRECT_UTILIZATION=y CONFIG_CMA_PCP_LISTS=y CONFIG_DMA_COHERENT_HINT_CACHED=y CONFIG_PRIORITIZE_OOM_TASKS=y CONFIG_DMA_CONFIGURE_ALIGNMENT=y # CONFIG_ZONE_DEVICE is not set # CONFIG_BUG_ON_HW_MEM_ONLINE_FAIL is not set CONFIG_MSM_BT_POWER=m Loading drivers/iommu/Kconfig +16 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,22 @@ config IOMMU_IOVA_ALIGNMENT The order is expressed a power of two multiplied by the PAGE_SIZE. If unsure, leave the default value "9". config DMA_CONFIGURE_ALIGNMENT bool "Configure IOVA alignment" help Currently the IOVA framework automatically applies IOVA alignment to provided IOVAs based on the requested IOVA size and the alignment configs which are enabled. Some clients who don't require any IOVA alignment would benefit from the reduced fragmentation that would result from disabling IOVA alignment. Enable this option to allow clients to disable IOVA alignment on an IOMMU domain. If unsure, say N. endif menuconfig IOMMU_SUPPORT Loading drivers/iommu/dma-iommu.c +21 −0 Original line number Diff line number Diff line Loading @@ -400,6 +400,27 @@ int iommu_dma_enable_best_fit_algo(struct device *dev) } EXPORT_SYMBOL(iommu_dma_enable_best_fit_algo); #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT /* * Should be called prior to using dma-apis. */ int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { struct iommu_domain *domain; struct iova_domain *iovad; domain = iommu_get_domain_for_dev(dev); if (!domain || !domain->iova_cookie) return -EINVAL; iovad = &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad; iovad->force_no_align = force_no_align; return 0; } EXPORT_SYMBOL(iommu_dma_configure_alignment); #endif /** * dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API * page flags. Loading drivers/iommu/iova.c +8 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,9 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, rb_link_node(&iovad->anchor.node, NULL, &iovad->rbroot.rb_node); rb_insert_color(&iovad->anchor.node, &iovad->rbroot); iovad->best_fit = false; #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT iovad->force_no_align = false; #endif init_iova_rcaches(iovad); } EXPORT_SYMBOL_GPL(init_iova_domain); Loading Loading @@ -385,6 +388,11 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, if (!new_iova) return NULL; #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT if (iovad->force_no_align) size_aligned = false; #endif if (iovad->best_fit) { ret = __alloc_and_insert_iova_best_fit(iovad, size, limit_pfn + 1, new_iova, size_aligned); Loading include/linux/dma-iommu.h +16 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,16 @@ int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base, int iommu_dma_enable_best_fit_algo(struct device *dev); #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT int iommu_dma_configure_alignment(struct device *dev, bool force_no_align); #else /* CONFIG_DMA_CONFIGURE_ALIGNMENT */ static inline int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { return -ENOTSUPP; } #endif #else /* CONFIG_IOMMU_DMA */ struct iommu_domain; Loading Loading @@ -110,5 +120,11 @@ static inline int iommu_dma_enable_best_fit_algo(struct device *dev) return -ENODEV; } static inline int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { return -ENODEV; } #endif /* CONFIG_IOMMU_DMA */ #endif /* __DMA_IOMMU_H */ Loading
arch/arm64/configs/vendor/lahaina_QGKI.config +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ CONFIG_CMA_DIRECT_UTILIZATION=y CONFIG_CMA_PCP_LISTS=y CONFIG_DMA_COHERENT_HINT_CACHED=y CONFIG_PRIORITIZE_OOM_TASKS=y CONFIG_DMA_CONFIGURE_ALIGNMENT=y # CONFIG_ZONE_DEVICE is not set # CONFIG_BUG_ON_HW_MEM_ONLINE_FAIL is not set CONFIG_MSM_BT_POWER=m Loading
drivers/iommu/Kconfig +16 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,22 @@ config IOMMU_IOVA_ALIGNMENT The order is expressed a power of two multiplied by the PAGE_SIZE. If unsure, leave the default value "9". config DMA_CONFIGURE_ALIGNMENT bool "Configure IOVA alignment" help Currently the IOVA framework automatically applies IOVA alignment to provided IOVAs based on the requested IOVA size and the alignment configs which are enabled. Some clients who don't require any IOVA alignment would benefit from the reduced fragmentation that would result from disabling IOVA alignment. Enable this option to allow clients to disable IOVA alignment on an IOMMU domain. If unsure, say N. endif menuconfig IOMMU_SUPPORT Loading
drivers/iommu/dma-iommu.c +21 −0 Original line number Diff line number Diff line Loading @@ -400,6 +400,27 @@ int iommu_dma_enable_best_fit_algo(struct device *dev) } EXPORT_SYMBOL(iommu_dma_enable_best_fit_algo); #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT /* * Should be called prior to using dma-apis. */ int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { struct iommu_domain *domain; struct iova_domain *iovad; domain = iommu_get_domain_for_dev(dev); if (!domain || !domain->iova_cookie) return -EINVAL; iovad = &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad; iovad->force_no_align = force_no_align; return 0; } EXPORT_SYMBOL(iommu_dma_configure_alignment); #endif /** * dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API * page flags. Loading
drivers/iommu/iova.c +8 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,9 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, rb_link_node(&iovad->anchor.node, NULL, &iovad->rbroot.rb_node); rb_insert_color(&iovad->anchor.node, &iovad->rbroot); iovad->best_fit = false; #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT iovad->force_no_align = false; #endif init_iova_rcaches(iovad); } EXPORT_SYMBOL_GPL(init_iova_domain); Loading Loading @@ -385,6 +388,11 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, if (!new_iova) return NULL; #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT if (iovad->force_no_align) size_aligned = false; #endif if (iovad->best_fit) { ret = __alloc_and_insert_iova_best_fit(iovad, size, limit_pfn + 1, new_iova, size_aligned); Loading
include/linux/dma-iommu.h +16 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,16 @@ int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base, int iommu_dma_enable_best_fit_algo(struct device *dev); #ifdef CONFIG_DMA_CONFIGURE_ALIGNMENT int iommu_dma_configure_alignment(struct device *dev, bool force_no_align); #else /* CONFIG_DMA_CONFIGURE_ALIGNMENT */ static inline int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { return -ENOTSUPP; } #endif #else /* CONFIG_IOMMU_DMA */ struct iommu_domain; Loading Loading @@ -110,5 +120,11 @@ static inline int iommu_dma_enable_best_fit_algo(struct device *dev) return -ENODEV; } static inline int iommu_dma_configure_alignment(struct device *dev, bool force_no_align) { return -ENODEV; } #endif /* CONFIG_IOMMU_DMA */ #endif /* __DMA_IOMMU_H */