Message ID | 20250409095825.1014521-1-stanislaw.gruszka@linux.intel.com |
---|---|
State | New |
Headers | show |
Series | media: intel/ipu6: Fix dma mask for non-secure mode | expand |
On Wed, Apr 09, 2025 at 11:58:25AM +0200, Stanislaw Gruszka wrote: > We use dma_get_mask() of auxdev device for calculate iova pfn limit. > This is always 32 bit mask as we do not initialize the mask (and we can > not do so, since dev->dev_mask is NULL anyways for auxdev). > > Since we need 31 bit mask for non-secure mode create wrapper of > alloc_iova() which use mmu_info->aperture_end. This give us always > the correct mask. > > Fixes: daabc5c64703 ("media: ipu6: not override the dma_ops of device in driver") > Cc: stable@vger.kernel.org > Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> <snip> > void __iomem *base, int mmid, > const struct ipu6_hw_variants *hw); > @@ -70,4 +76,11 @@ void ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, > size_t size); > phys_addr_t ipu6_mmu_iova_to_phys(struct ipu6_mmu_info *mmu_info, > dma_addr_t iova); > + > +static inline struct iova *ipu_alloc_iova(struct ipu6_mmu *mmu, > + unsigned long n_pages) Before posing one of my vim macro accidentally mangled this patch. Will send v2. Regards Stanislaw
Hi Stanislaw, kernel test robot noticed the following build errors: [auto build test ERROR on linuxtv-media-pending/master] [also build test ERROR on linus/master v6.15-rc1 next-20250409] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Stanislaw-Gruszka/media-intel-ipu6-Fix-dma-mask-for-non-secure-mode/20250409-180044 base: https://git.linuxtv.org/media-ci/media-pending.git master patch link: https://lore.kernel.org/r/20250409095825.1014521-1-stanislaw.gruszka%40linux.intel.com patch subject: [PATCH] media: intel/ipu6: Fix dma mask for non-secure mode config: i386-buildonly-randconfig-001-20250409 (https://download.01.org/0day-ci/archive/20250409/202504092031.rZzXFFce-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250409/202504092031.rZzXFFce-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202504092031.rZzXFFce-lkp@intel.com/ All error/warnings (new ones prefixed by >>): drivers/media/pci/intel/ipu6/ipu6-dma.c: In function 'ipu6_dma_alloc': >> drivers/media/pci/intel/ipu6/ipu6-dma.c:174:16: error: implicit declaration of function 'ipu6_alloc_iova'; did you mean 'ipu_alloc_iova'? [-Werror=implicit-function-declaration] 174 | iova = ipu6_alloc_iova(mmu, count); | ^~~~~~~~~~~~~~~ | ipu_alloc_iova >> drivers/media/pci/intel/ipu6/ipu6-dma.c:174:14: warning: assignment to 'struct iova *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 174 | iova = ipu6_alloc_iova(mmu, count); | ^ drivers/media/pci/intel/ipu6/ipu6-dma.c: In function 'ipu6_dma_map_sg': drivers/media/pci/intel/ipu6/ipu6-dma.c:399:14: warning: assignment to 'struct iova *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 399 | iova = ipu6_alloc_iova(mmu, npages); | ^ cc1: some warnings being treated as errors -- drivers/media/pci/intel/ipu6/ipu6-mmu.c: In function 'allocate_trash_buffer': >> drivers/media/pci/intel/ipu6/ipu6-mmu.c:424:16: error: implicit declaration of function 'ipu6_alloc_iova'; did you mean 'ipu_alloc_iova'? [-Werror=implicit-function-declaration] 424 | iova = ipu6_alloc_iova(mmu, n_pages); | ^~~~~~~~~~~~~~~ | ipu_alloc_iova >> drivers/media/pci/intel/ipu6/ipu6-mmu.c:424:14: warning: assignment to 'struct iova *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 424 | iova = ipu6_alloc_iova(mmu, n_pages); | ^ cc1: some warnings being treated as errors vim +174 drivers/media/pci/intel/ipu6/ipu6-dma.c 151 152 void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, 153 dma_addr_t *dma_handle, gfp_t gfp, 154 unsigned long attrs) 155 { 156 struct device *dev = &sys->auxdev.dev; 157 struct pci_dev *pdev = sys->isp->pdev; 158 dma_addr_t pci_dma_addr, ipu6_iova; 159 struct ipu6_mmu *mmu = sys->mmu; 160 struct vm_info *info; 161 unsigned long count; 162 struct page **pages; 163 struct iova *iova; 164 unsigned int i; 165 int ret; 166 167 info = kzalloc(sizeof(*info), GFP_KERNEL); 168 if (!info) 169 return NULL; 170 171 size = PAGE_ALIGN(size); 172 count = PHYS_PFN(size); 173 > 174 iova = ipu6_alloc_iova(mmu, count); 175 if (!iova) 176 goto out_kfree; 177 178 pages = __alloc_buffer(size, gfp, attrs); 179 if (!pages) 180 goto out_free_iova; 181 182 dev_dbg(dev, "dma_alloc: size %zu iova low pfn %lu, high pfn %lu\n", 183 size, iova->pfn_lo, iova->pfn_hi); 184 for (i = 0; iova->pfn_lo + i <= iova->pfn_hi; i++) { 185 pci_dma_addr = dma_map_page_attrs(&pdev->dev, pages[i], 0, 186 PAGE_SIZE, DMA_BIDIRECTIONAL, 187 attrs); 188 dev_dbg(dev, "dma_alloc: mapped pci_dma_addr %pad\n", 189 &pci_dma_addr); 190 if (dma_mapping_error(&pdev->dev, pci_dma_addr)) { 191 dev_err(dev, "pci_dma_mapping for page[%d] failed", i); 192 goto out_unmap; 193 } 194 195 ret = ipu6_mmu_map(mmu->dmap->mmu_info, 196 PFN_PHYS(iova->pfn_lo + i), pci_dma_addr, 197 PAGE_SIZE); 198 if (ret) { 199 dev_err(dev, "ipu6_mmu_map for pci_dma[%d] %pad failed", 200 i, &pci_dma_addr); 201 dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, 202 PAGE_SIZE, DMA_BIDIRECTIONAL, 203 attrs); 204 goto out_unmap; 205 } 206 } 207 208 info->vaddr = vmap(pages, count, VM_USERMAP, PAGE_KERNEL); 209 if (!info->vaddr) 210 goto out_unmap; 211 212 *dma_handle = PFN_PHYS(iova->pfn_lo); 213 214 info->pages = pages; 215 info->ipu6_iova = *dma_handle; 216 info->size = size; 217 list_add(&info->list, &mmu->vma_list); 218 219 return info->vaddr; 220 221 out_unmap: 222 while (i--) { 223 ipu6_iova = PFN_PHYS(iova->pfn_lo + i); 224 pci_dma_addr = ipu6_mmu_iova_to_phys(mmu->dmap->mmu_info, 225 ipu6_iova); 226 dma_unmap_page_attrs(&pdev->dev, pci_dma_addr, PAGE_SIZE, 227 DMA_BIDIRECTIONAL, attrs); 228 229 ipu6_mmu_unmap(mmu->dmap->mmu_info, ipu6_iova, PAGE_SIZE); 230 } 231 232 __free_buffer(pages, size, attrs); 233 234 out_free_iova: 235 __free_iova(&mmu->dmap->iovad, iova); 236 out_kfree: 237 kfree(info); 238 239 return NULL; 240 } 241 EXPORT_SYMBOL_NS_GPL(ipu6_dma_alloc, "INTEL_IPU6"); 242
Stanislaw, Thanks for the patch. On 4/9/25 5:58 PM, Stanislaw Gruszka wrote: > We use dma_get_mask() of auxdev device for calculate iova pfn limit. > This is always 32 bit mask as we do not initialize the mask (and we can > not do so, since dev->dev_mask is NULL anyways for auxdev). Indeed. > > Since we need 31 bit mask for non-secure mode create wrapper of > alloc_iova() which use mmu_info->aperture_end. This give us always > the correct mask. > > Fixes: daabc5c64703 ("media: ipu6: not override the dma_ops of device in driver") > Cc: stable@vger.kernel.org > Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> > --- > drivers/media/pci/intel/ipu6/ipu6-dma.c | 6 ++---- > drivers/media/pci/intel/ipu6/ipu6-dma.h | 7 ------- > drivers/media/pci/intel/ipu6/ipu6-mmu.c | 3 +-- > drivers/media/pci/intel/ipu6/ipu6-mmu.h | 13 +++++++++++++ > 4 files changed, 16 insertions(+), 13 deletions(-) > > diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.c b/drivers/media/pci/intel/ipu6/ipu6-dma.c > index b34022bad83b..a1d4ec35f802 100644 > --- a/drivers/media/pci/intel/ipu6/ipu6-dma.c > +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.c > @@ -171,8 +171,7 @@ void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, > size = PAGE_ALIGN(size); > count = PHYS_PFN(size); > > - iova = alloc_iova(&mmu->dmap->iovad, count, > - PHYS_PFN(dma_get_mask(dev)), 0); How about directly call? iova = alloc_iova(&mmu->dmap->iovad, count, PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); Less change, better. > + iova = ipu6_alloc_iova(mmu, count); > if (!iova) > goto out_kfree; > > @@ -397,8 +396,7 @@ int ipu6_dma_map_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, > dev_dbg(dev, "dmamap trying to map %d ents %zu pages\n", > nents, npages); > > - iova = alloc_iova(&mmu->dmap->iovad, npages, > - PHYS_PFN(dma_get_mask(dev)), 0); > + iova = ipu6_alloc_iova(mmu, npages); > if (!iova) > return 0; > > diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.h b/drivers/media/pci/intel/ipu6/ipu6-dma.h > index b51244add9e6..0dd7c0556bd2 100644 > --- a/drivers/media/pci/intel/ipu6/ipu6-dma.h > +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.h > @@ -6,8 +6,6 @@ > > #include <linux/dma-map-ops.h> > #include <linux/dma-mapping.h> > -#include <linux/iova.h> > -#include <linux/iova.h> > #include <linux/scatterlist.h> > #include <linux/types.h> > > @@ -15,11 +13,6 @@ > > struct ipu6_mmu_info; > > -struct ipu6_dma_mapping { > - struct ipu6_mmu_info *mmu_info; > - struct iova_domain iovad; > -}; > - > void ipu6_dma_sync_single(struct ipu6_bus_device *sys, dma_addr_t dma_handle, > size_t size); > void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, > diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c > index 6d1c0b90169d..95eb17855847 100644 > --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c > +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c > @@ -421,8 +421,7 @@ static int allocate_trash_buffer(struct ipu6_mmu *mmu) > int ret; > > /* Allocate 8MB in iova range */ > - iova = alloc_iova(&mmu->dmap->iovad, n_pages, > - PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); > + iova = ipu6_alloc_iova(mmu, n_pages); > if (!iova) { > dev_err(mmu->dev, "cannot allocate iova range for trash\n"); > return -ENOMEM; > diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.h b/drivers/media/pci/intel/ipu6/ipu6-mmu.h > index 8e40b4a66d7d..7f3860796762 100644 > --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.h > +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.h > @@ -7,6 +7,7 @@ > #define ISYS_MMID 1 > #define PSYS_MMID 0 > > +#include <linux/iova.h> > #include <linux/list.h> > #include <linux/spinlock_types.h> > #include <linux/types.h> > @@ -58,6 +59,11 @@ struct ipu6_mmu { > void (*tlb_invalidate)(struct ipu6_mmu *mmu); > }; > > +struct ipu6_dma_mapping { > + struct ipu6_mmu_info *mmu_info; > + struct iova_domain iovad; > +}; > + > struct ipu6_mmu *ipu6_mmu_init(struct device *dev, > void __iomem *base, int mmid, > const struct ipu6_hw_variants *hw); > @@ -70,4 +76,11 @@ void ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, > size_t size); > phys_addr_t ipu6_mmu_iova_to_phys(struct ipu6_mmu_info *mmu_info, > dma_addr_t iova); > + > +static inline struct iova *ipu_alloc_iova(struct ipu6_mmu *mmu, > + unsigned long n_pages) > +{ > + return alloc_iova(&mmu->dmap->iovad, n_pages, > + PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); > +} > #endif >
Hi Bingbu, On Thu, Apr 10, 2025 at 02:53:45PM +0800, Bingbu Cao wrote: > Stanislaw, > > Thanks for the patch. > > On 4/9/25 5:58 PM, Stanislaw Gruszka wrote: > > We use dma_get_mask() of auxdev device for calculate iova pfn limit. > > This is always 32 bit mask as we do not initialize the mask (and we can > > not do so, since dev->dev_mask is NULL anyways for auxdev). > > Indeed. > > > > > Since we need 31 bit mask for non-secure mode create wrapper of > > alloc_iova() which use mmu_info->aperture_end. This give us always > > the correct mask. > > > > Fixes: daabc5c64703 ("media: ipu6: not override the dma_ops of device in driver") > > Cc: stable@vger.kernel.org > > Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> > > --- > > drivers/media/pci/intel/ipu6/ipu6-dma.c | 6 ++---- > > drivers/media/pci/intel/ipu6/ipu6-dma.h | 7 ------- > > drivers/media/pci/intel/ipu6/ipu6-mmu.c | 3 +-- > > drivers/media/pci/intel/ipu6/ipu6-mmu.h | 13 +++++++++++++ > > 4 files changed, 16 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.c b/drivers/media/pci/intel/ipu6/ipu6-dma.c > > index b34022bad83b..a1d4ec35f802 100644 > > --- a/drivers/media/pci/intel/ipu6/ipu6-dma.c > > +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.c > > @@ -171,8 +171,7 @@ void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, > > size = PAGE_ALIGN(size); > > count = PHYS_PFN(size); > > > > - iova = alloc_iova(&mmu->dmap->iovad, count, > > - PHYS_PFN(dma_get_mask(dev)), 0); > > How about directly call? > iova = alloc_iova(&mmu->dmap->iovad, count, > PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); > > Less change, better. Yes, direct call results in smaller/nicer fix, I will do this in v2. Regards Stanislaw
diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.c b/drivers/media/pci/intel/ipu6/ipu6-dma.c index b34022bad83b..a1d4ec35f802 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-dma.c +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.c @@ -171,8 +171,7 @@ void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, size = PAGE_ALIGN(size); count = PHYS_PFN(size); - iova = alloc_iova(&mmu->dmap->iovad, count, - PHYS_PFN(dma_get_mask(dev)), 0); + iova = ipu6_alloc_iova(mmu, count); if (!iova) goto out_kfree; @@ -397,8 +396,7 @@ int ipu6_dma_map_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, dev_dbg(dev, "dmamap trying to map %d ents %zu pages\n", nents, npages); - iova = alloc_iova(&mmu->dmap->iovad, npages, - PHYS_PFN(dma_get_mask(dev)), 0); + iova = ipu6_alloc_iova(mmu, npages); if (!iova) return 0; diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.h b/drivers/media/pci/intel/ipu6/ipu6-dma.h index b51244add9e6..0dd7c0556bd2 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-dma.h +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.h @@ -6,8 +6,6 @@ #include <linux/dma-map-ops.h> #include <linux/dma-mapping.h> -#include <linux/iova.h> -#include <linux/iova.h> #include <linux/scatterlist.h> #include <linux/types.h> @@ -15,11 +13,6 @@ struct ipu6_mmu_info; -struct ipu6_dma_mapping { - struct ipu6_mmu_info *mmu_info; - struct iova_domain iovad; -}; - void ipu6_dma_sync_single(struct ipu6_bus_device *sys, dma_addr_t dma_handle, size_t size); void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist, diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index 6d1c0b90169d..95eb17855847 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -421,8 +421,7 @@ static int allocate_trash_buffer(struct ipu6_mmu *mmu) int ret; /* Allocate 8MB in iova range */ - iova = alloc_iova(&mmu->dmap->iovad, n_pages, - PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); + iova = ipu6_alloc_iova(mmu, n_pages); if (!iova) { dev_err(mmu->dev, "cannot allocate iova range for trash\n"); return -ENOMEM; diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.h b/drivers/media/pci/intel/ipu6/ipu6-mmu.h index 8e40b4a66d7d..7f3860796762 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.h +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.h @@ -7,6 +7,7 @@ #define ISYS_MMID 1 #define PSYS_MMID 0 +#include <linux/iova.h> #include <linux/list.h> #include <linux/spinlock_types.h> #include <linux/types.h> @@ -58,6 +59,11 @@ struct ipu6_mmu { void (*tlb_invalidate)(struct ipu6_mmu *mmu); }; +struct ipu6_dma_mapping { + struct ipu6_mmu_info *mmu_info; + struct iova_domain iovad; +}; + struct ipu6_mmu *ipu6_mmu_init(struct device *dev, void __iomem *base, int mmid, const struct ipu6_hw_variants *hw); @@ -70,4 +76,11 @@ void ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, size_t size); phys_addr_t ipu6_mmu_iova_to_phys(struct ipu6_mmu_info *mmu_info, dma_addr_t iova); + +static inline struct iova *ipu_alloc_iova(struct ipu6_mmu *mmu, + unsigned long n_pages) +{ + return alloc_iova(&mmu->dmap->iovad, n_pages, + PHYS_PFN(mmu->dmap->mmu_info->aperture_end), 0); +} #endif
We use dma_get_mask() of auxdev device for calculate iova pfn limit. This is always 32 bit mask as we do not initialize the mask (and we can not do so, since dev->dev_mask is NULL anyways for auxdev). Since we need 31 bit mask for non-secure mode create wrapper of alloc_iova() which use mmu_info->aperture_end. This give us always the correct mask. Fixes: daabc5c64703 ("media: ipu6: not override the dma_ops of device in driver") Cc: stable@vger.kernel.org Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> --- drivers/media/pci/intel/ipu6/ipu6-dma.c | 6 ++---- drivers/media/pci/intel/ipu6/ipu6-dma.h | 7 ------- drivers/media/pci/intel/ipu6/ipu6-mmu.c | 3 +-- drivers/media/pci/intel/ipu6/ipu6-mmu.h | 13 +++++++++++++ 4 files changed, 16 insertions(+), 13 deletions(-)