Skip to content

Commit ceb4e0a

Browse files
committed
drm: apple: iomfb: Align buffer size on unmap/free as well
Fixes failure to unmap buffers in dcpep_cb_unmap_piodma() due to the unaligned size. Further along this causes kernel log splat when DCP tries to map the buffers again since thye IOVA is still in use. This causes no apparent issue although map_piodma callback signals an errror and returns 0 (unmapped as DVA). It's not clear why this presents only randomly. Possibly some build or uninitialized memory triggers this unmap/free and immediate allocate/map cycle in the DCP firmware. I never notices this with a clang-built kernel on j314c. It showed with gcc build with the Fedora config at least on 6.8.8 based kernels. This did not reproduce on j375d. Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 4506bc5 commit ceb4e0a

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/gpu/drm/apple/iomfb_template.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,10 @@ static void dcpep_cb_unmap_piodma(struct apple_dcp *dcp,
322322
}
323323

324324
/* use the piodma iommu domain to unmap from the right IOMMU */
325-
iommu_unmap(dcp->iommu_dom, memdesc->dva, memdesc->size);
325+
/* HACK: expect size to be 16K aligned since the iommu API only maps
326+
* full pages
327+
*/
328+
iommu_unmap(dcp->iommu_dom, memdesc->dva, ALIGN(memdesc->size, SZ_16K));
326329
}
327330

328331
/*
@@ -370,6 +373,7 @@ dcpep_cb_allocate_buffer(struct apple_dcp *dcp,
370373
static u8 dcpep_cb_release_mem_desc(struct apple_dcp *dcp, u32 *mem_desc_id)
371374
{
372375
struct dcp_mem_descriptor *memdesc;
376+
size_t size;
373377
u32 id = *mem_desc_id;
374378

375379
if (id >= DCP_MAX_MAPPINGS) {
@@ -385,10 +389,9 @@ static u8 dcpep_cb_release_mem_desc(struct apple_dcp *dcp, u32 *mem_desc_id)
385389
}
386390

387391
memdesc = &dcp->memdesc[id];
392+
size = ALIGN(memdesc->size, SZ_16K);
388393
if (memdesc->buf) {
389-
dma_free_coherent(dcp->dev, memdesc->size, memdesc->buf,
390-
memdesc->dva);
391-
394+
dma_free_coherent(dcp->dev, size, memdesc->buf, memdesc->dva);
392395
memdesc->buf = NULL;
393396
memset(&memdesc->map, 0, sizeof(memdesc->map));
394397
} else {

0 commit comments

Comments
 (0)