Skip to content

Commit

Permalink
drm: apple: iomfb: Align buffer size on unmap/free as well
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jannau committed Jul 13, 2024
1 parent 4506bc5 commit ceb4e0a
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions drivers/gpu/drm/apple/iomfb_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,10 @@ static void dcpep_cb_unmap_piodma(struct apple_dcp *dcp,
}

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

/*
Expand Down Expand Up @@ -370,6 +373,7 @@ dcpep_cb_allocate_buffer(struct apple_dcp *dcp,
static u8 dcpep_cb_release_mem_desc(struct apple_dcp *dcp, u32 *mem_desc_id)
{
struct dcp_mem_descriptor *memdesc;
size_t size;
u32 id = *mem_desc_id;

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

memdesc = &dcp->memdesc[id];
size = ALIGN(memdesc->size, SZ_16K);
if (memdesc->buf) {
dma_free_coherent(dcp->dev, memdesc->size, memdesc->buf,
memdesc->dva);

dma_free_coherent(dcp->dev, size, memdesc->buf, memdesc->dva);
memdesc->buf = NULL;
memset(&memdesc->map, 0, sizeof(memdesc->map));
} else {
Expand Down

0 comments on commit ceb4e0a

Please sign in to comment.