Re: [PATCH v2 4/8] iommu/dma: Support granule > PAGE_SIZE in dma_map_sg
Hi Sven, I love your patch! Perhaps something to improve: [auto build test WARNING on iommu/next] [also build test WARNING on v5.14-rc7 next-20210827] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next config: x86_64-randconfig-r004-20210827 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4e1a164d7bd53653f79decc121afe784d2fde0a7) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/fa978f84667cfd7d8cb467899da60c08321798a5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 git checkout fa978f84667cfd7d8cb467899da60c08321798a5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/iommu/dma-iommu.c:935:18: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, ^ >> drivers/iommu/dma-iommu.c:935:18: warning: incompatible integer to pointer >> conversion passing 'int' to parameter of type 'struct page *' >> [-Wint-conversion] sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, ^ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ drivers/iommu/dma-iommu.c:982:9: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] phys_to_page(sg_phys(s) + sg_dma_address(s)), ^ drivers/iommu/dma-iommu.c:982:9: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct page *' [-Wint-conversion] phys_to_page(sg_phys(s) + sg_dma_address(s)), ^~~~ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ drivers/iommu/dma-iommu.c:1068:18: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] sg_set_page(s, phys_to_page(s_phys - s_iova_off), ^ drivers/iommu/dma-iommu.c:1068:18: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct page *' [-Wint-conversion] sg_set_page(s, phys_to_page(s_phys - s_iova_off), ^ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ 3 warnings and 3 errors generated. vim +935 drivers/iommu/dma-iommu.c 913 914 /* 915 * Prepare a successfully-mapped scatterlist to give back to the caller. 916 * 917 * At this point the segments are already laid out by iommu_dma_map_sg() to 918 * avoid individually crossing any boundaries, so we merely need to check a 919 * segment's start address to avoid concatenating across one. 920 */ 921 static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, 922 dma_addr_t dma_addr) 923 { 924 struct scatterlist *s, *cur = sg; 925 unsigned long seg_mask = dma_get_seg_boundary(dev); 926 unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); 927 int i, count = 0; 928 929 for_each_sg(sg, s, nents, i) { 930 /* Restore this segment's original unaligned fields first */ 931 unsigned int s_iova_off = sg_dma_address(s); 932 unsigned
Re: [PATCH v2 4/8] iommu/dma: Support granule > PAGE_SIZE in dma_map_sg
Hi Sven, I love your patch! Perhaps something to improve: [auto build test WARNING on iommu/next] [also build test WARNING on v5.14-rc7 next-20210827] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next config: x86_64-randconfig-m001-20210827 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/fa978f84667cfd7d8cb467899da60c08321798a5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 git checkout fa978f84667cfd7d8cb467899da60c08321798a5 # save the attached .config to linux build tree make W=1 ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/iommu/dma-iommu.c: In function '__finalise_sg': drivers/iommu/dma-iommu.c:935:18: error: implicit declaration of function 'phys_to_page'; did you mean 'pfn_to_page'? [-Werror=implicit-function-declaration] 935 | sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, | ^~~~ | pfn_to_page >> drivers/iommu/dma-iommu.c:935:18: warning: passing argument 2 of >> 'sg_set_page' makes pointer from integer without a cast [-Wint-conversion] 935 | sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, | ^ | | | int In file included from include/linux/dma-mapping.h:10, from include/linux/dma-map-ops.h:9, from drivers/iommu/dma-iommu.c:13: include/linux/scatterlist.h:110:69: note: expected 'struct page *' but argument is of type 'int' 110 | static inline void sg_set_page(struct scatterlist *sg, struct page *page, | ~^~~~ drivers/iommu/dma-iommu.c: In function '__invalidate_sg': drivers/iommu/dma-iommu.c:982:9: warning: passing argument 2 of 'sg_set_page' makes pointer from integer without a cast [-Wint-conversion] 982 | phys_to_page(sg_phys(s) + sg_dma_address(s)), | ^~~~ | | | int In file included from include/linux/dma-mapping.h:10, from include/linux/dma-map-ops.h:9, from drivers/iommu/dma-iommu.c:13: include/linux/scatterlist.h:110:69: note: expected 'struct page *' but argument is of type 'int' 110 | static inline void sg_set_page(struct scatterlist *sg, struct page *page, | ~^~~~ drivers/iommu/dma-iommu.c: In function 'iommu_dma_map_sg': drivers/iommu/dma-iommu.c:1068:18: warning: passing argument 2 of 'sg_set_page' makes pointer from integer without a cast [-Wint-conversion] 1068 | sg_set_page(s, phys_to_page(s_phys - s_iova_off), | ^ | | | int In file included from include/linux/dma-mapping.h:10, from include/linux/dma-map-ops.h:9, from drivers/iommu/dma-iommu.c:13: include/linux/scatterlist.h:110:69: note: expected 'struct page *' but argument is of type 'int' 110 | static inline void sg_set_page(struct scatterlist *sg, struct page *page, | ~^~~~ cc1: some warnings being treated as errors vim +/sg_set_page +935 drivers/iommu/dma-iommu.c 913 914 /* 915 * Prepare a successfully-mapped scatterlist to give back to the caller. 916 * 917 * At this point the segments are already laid out by iommu_dma_map_sg() to 918 * avoid individually crossing any boundaries, so we merely need to check a 919 * segment's start address to avoid concatenating across one. 920 */ 921 static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, 922 dma_addr_t dma_addr) 923 { 924 struct scatterlist *s, *cur = sg; 925 unsigned long seg_mask = dma_get_seg_boundary(dev); 926 unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); 927 int i, count = 0; 928 929 for_each_sg(sg, s, nents, i) { 930 /*
Re: [PATCH v2 4/8] iommu/dma: Support granule > PAGE_SIZE in dma_map_sg
Hi Sven, I love your patch! Perhaps something to improve: [auto build test WARNING on iommu/next] [also build test WARNING on v5.14-rc7 next-20210827] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next config: i386-randconfig-c001-20210827 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4e1a164d7bd53653f79decc121afe784d2fde0a7) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/fa978f84667cfd7d8cb467899da60c08321798a5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sven-Peter/Support-IOMMU-page-sizes-larger-than-the-CPU-page-size/20210828-233909 git checkout fa978f84667cfd7d8cb467899da60c08321798a5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/iommu/dma-iommu.c:935:18: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, ^ >> drivers/iommu/dma-iommu.c:935:18: warning: incompatible integer to pointer >> conversion passing 'int' to parameter of type 'struct page *' >> [-Wint-conversion] sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, ^ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ drivers/iommu/dma-iommu.c:982:9: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] phys_to_page(sg_phys(s) + sg_dma_address(s)), ^ drivers/iommu/dma-iommu.c:982:9: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct page *' [-Wint-conversion] phys_to_page(sg_phys(s) + sg_dma_address(s)), ^~~~ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ drivers/iommu/dma-iommu.c:1068:18: error: implicit declaration of function 'phys_to_page' [-Werror,-Wimplicit-function-declaration] sg_set_page(s, phys_to_page(s_phys - s_iova_off), ^ drivers/iommu/dma-iommu.c:1068:18: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'struct page *' [-Wint-conversion] sg_set_page(s, phys_to_page(s_phys - s_iova_off), ^ include/linux/scatterlist.h:110:69: note: passing argument to parameter 'page' here static inline void sg_set_page(struct scatterlist *sg, struct page *page, ^ 3 warnings and 3 errors generated. vim +935 drivers/iommu/dma-iommu.c 913 914 /* 915 * Prepare a successfully-mapped scatterlist to give back to the caller. 916 * 917 * At this point the segments are already laid out by iommu_dma_map_sg() to 918 * avoid individually crossing any boundaries, so we merely need to check a 919 * segment's start address to avoid concatenating across one. 920 */ 921 static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, 922 dma_addr_t dma_addr) 923 { 924 struct scatterlist *s, *cur = sg; 925 unsigned long seg_mask = dma_get_seg_boundary(dev); 926 unsigned int cur_len = 0, max_len = dma_get_max_seg_size(dev); 927 int i, count = 0; 928 929 for_each_sg(sg, s, nents, i) { 930 /* Restore this segment's original unaligned fields first */ 931 unsigned int s_iova_off = sg_dma_address(s); 932 unsigned int
[PATCH v2 4/8] iommu/dma: Support granule > PAGE_SIZE in dma_map_sg
Add support to iommu_dma_map_sg's impedance matching to also align sg_lists correctly when the IOMMU granule is larger than PAGE_SIZE. Co-developed-by: Robin Murphy Signed-off-by: Robin Murphy Signed-off-by: Sven Peter --- drivers/iommu/dma-iommu.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 64fbd9236820..a091cff5829d 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -932,8 +932,8 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, unsigned int s_length = sg_dma_len(s); unsigned int s_iova_len = s->length; - s->offset += s_iova_off; - s->length = s_length; + sg_set_page(s, phys_to_page(sg_phys(s) + s_iova_off), s_length, + s_iova_off & ~PAGE_MASK); sg_dma_address(s) = DMA_MAPPING_ERROR; sg_dma_len(s) = 0; @@ -977,10 +977,11 @@ static void __invalidate_sg(struct scatterlist *sg, int nents) int i; for_each_sg(sg, s, nents, i) { - if (sg_dma_address(s) != DMA_MAPPING_ERROR) - s->offset += sg_dma_address(s); if (sg_dma_len(s)) - s->length = sg_dma_len(s); + sg_set_page(s, + phys_to_page(sg_phys(s) + sg_dma_address(s)), + sg_dma_len(s), + sg_dma_address(s) & ~PAGE_MASK); sg_dma_address(s) = DMA_MAPPING_ERROR; sg_dma_len(s) = 0; } @@ -1056,15 +1057,16 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, * stashing the unaligned parts in the as-yet-unused DMA fields. */ for_each_sg(sg, s, nents, i) { - size_t s_iova_off = iova_offset(iovad, s->offset); + phys_addr_t s_phys = sg_phys(s); + size_t s_iova_off = iova_offset(iovad, s_phys); size_t s_length = s->length; size_t pad_len = (mask - iova_len + 1) & mask; sg_dma_address(s) = s_iova_off; sg_dma_len(s) = s_length; - s->offset -= s_iova_off; s_length = iova_align(iovad, s_length + s_iova_off); - s->length = s_length; + sg_set_page(s, phys_to_page(s_phys - s_iova_off), + s_length, s->offset & ~s_iova_off); /* * Due to the alignment of our single IOVA allocation, we can -- 2.25.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu