[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250618132759.GO1376515@ziepe.ca>
Date: Wed, 18 Jun 2025 10:27:59 -0300
From: Jason Gunthorpe <jgg@...pe.ca>
To: Benjamin Gaignard <benjamin.gaignard@...labora.com>
Cc: joro@...tes.org, will@...nel.org, robin.murphy@....com, robh@...nel.org,
krzk+dt@...nel.org, conor+dt@...nel.org, heiko@...ech.de,
nicolas.dufresne@...labora.com, p.zabel@...gutronix.de,
mchehab@...nel.org, iommu@...ts.linux.dev,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-rockchip@...ts.infradead.org, linux-media@...r.kernel.org,
kernel@...labora.com
Subject: Re: [PATCH 3/5] iommu: Add verisilicon IOMMU driver
On Wed, Jun 18, 2025 at 02:04:19PM +0200, Benjamin Gaignard wrote:
>
> Le 17/06/2025 à 18:32, Jason Gunthorpe a écrit :
> > > + vsi_domain->dt_dma = dma_map_single(dma_dev, vsi_domain->dt,
> > > + SPAGE_SIZE, DMA_TO_DEVICE);
> > > + if (dma_mapping_error(dma_dev, vsi_domain->dt_dma)) {
> > > + dev_err(dma_dev, "DMA map error for DT\n");
> > > + goto err_free_dt;
> > > + }
> > > +
> > > + vsi_domain->pta = iommu_alloc_pages_sz(GFP_KERNEL | GFP_DMA32,
> > > + SPAGE_SIZE);
> > > + if (!vsi_domain->pta)
> > > + goto err_unmap_dt;
> > > +
> > > + vsi_domain->pta_dma = dma_map_single(dma_dev, vsi_domain->pta,
> > > + SPAGE_SIZE, DMA_TO_DEVICE);
> > > + if (dma_mapping_error(dma_dev, vsi_domain->pta_dma)) {
> > > + dev_err(dma_dev, "DMA map error for PTA\n");
> > > + goto err_free_pta;
> > > + }
> > > + vsi_domain->pta[0] = vsi_mk_pta(vsi_domain->dt_dma);
> > > +
> > > + vsi_table_flush(vsi_domain, vsi_domain->pta_dma, 1024);
> > > + vsi_table_flush(vsi_domain, vsi_domain->dt_dma, NUM_DT_ENTRIES);
> > dma_map_single already flushes, put things in the write order and no
> > need to double flush.
>
> I don't get your point here, for me it flush two different pieces of memory.
dma_map_single() already flushes the cache, you don't need to do it
again.
Do your memory writes then call dma_map_signle().
> > > + dte_index = vsi_iova_dte_index(iova);
> > > + dte_addr = &vsi_domain->dt[dte_index];
> > > + dte = *dte_addr;
> > > + if (vsi_dte_is_pt_valid(dte))
> > > + goto done;
> > > +
> > > + page_table = (u32 *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32);
> > > + if (!page_table)
> > > + return ERR_PTR(-ENOMEM);
> > Don't use get_zeroed_page for page table memory.
>
> I will use kmem_cache in v2
I mean you are supposed to iommu-pages.h for page table memory.
> > > + pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
> > > + if (dma_mapping_error(dma_dev, pt_dma)) {
> > > + dev_err(dma_dev, "DMA mapping error while allocating page table\n");
> > > + free_page((unsigned long)page_table);
> > > + return ERR_PTR(-ENOMEM);
> > > + }
> > > +
> > > + dte = vsi_mk_dte(pt_dma);
> > > + *dte_addr = dte;
> > > +
> > > + vsi_table_flush(vsi_domain, pt_dma, NUM_PT_ENTRIES);
> > > + vsi_table_flush(vsi_domain,
> > > + vsi_domain->dt_dma + dte_index * sizeof(u32), 1);
> > Double flushing again.
>
> Same here, for me I flushing two different memory area.
write to the page-table, then call dma_map_single(), don't flush it again.
> > > +static int vsi_iommu_map_iova(struct vsi_iommu_domain *vsi_domain, u32 *pte_addr,
> > > + dma_addr_t pte_dma, dma_addr_t iova,
> > > + phys_addr_t paddr, size_t size, int prot)
> > > +{
> > > + unsigned int pte_count;
> > > + unsigned int pte_total = size / SPAGE_SIZE;
> > > + phys_addr_t page_phys;
> > > +
> > > + assert_spin_locked(&vsi_domain->dt_lock);
> > > +
> > > + for (pte_count = 0; pte_count < pte_total; pte_count++) {
> > > + u32 pte = pte_addr[pte_count];
> > > +
> > > + if (vsi_pte_is_page_valid(pte))
> > > + goto unwind;
> > > +
> > > + pte_addr[pte_count] = vsi_mk_pte(paddr, prot);
> > So why is this:
> >
> > #define VSI_IOMMU_PGSIZE_BITMAP 0x007ff000
> >
> > If the sizes don't become encoded in the PTE? The bits beyond 4k
> > should reflect actual ability to store those sizes in PTEs, eg using
> > contiguous bits or something.
>
> The iommu use arrays to store up to 1024 4k pages indexes so the size
> isn't coded in the PTE bits but the numbers of used indexes for each arrays.
That isn't how it works, if the PTE bits don't code the size then you
don't set the VSI_IOMMU_PGSIZE_BITMAP. You just want SZ_4K for the way
this driver is written.
Jason
Powered by blists - more mailing lists