Skip to content

Commit b7d9aae

Browse files
willdeaconctmarinas
authored andcommitted
Revert "arm64: dma: Drop cache invalidation from arch_dma_prep_coherent()"
This reverts commit c44094e. Although the semantics of the DMA API require only a clean operation here, it turns out that the Qualcomm 'qcom_q6v5_mss' remoteproc driver (ab)uses the DMA API for transferring the modem firmware to the secure world via calls to Trustzone [1]. Once the firmware buffer has changed hands, _any_ access from the non-secure side (i.e. Linux) will be detected on the bus and result in a full system reset [2]. Although this is possible even with this revert in place (due to speculative reads via the cacheable linear alias of memory), anecdotally the problem occurs considerably more frequently when the lines have not been invalidated, assumedly due to some micro-architectural interactions with the cache hierarchy. Revert the offending change for now, along with a comment, so that the Qualcomm developers have time to fix the driver [3] to use a firmware buffer which does not have a cacheable alias in the linear map. Link: https://lore.kernel.org/r/[email protected] [1] Link: https://lore.kernel.org/r/CAMi1Hd3H2k1J8hJ6e-Miy5+nVDNzv6qQ3nN-9929B0GbHJkXEg@mail.gmail.com/ [2] Link: https://lore.kernel.org/r/20221206092152.GD15486@thinkpad [2] Reported-by: Amit Pundir <[email protected]> Reported-by: Manivannan Sadhasivam <[email protected]> Cc: Thorsten Leemhuis <[email protected]> Cc: Sibi Sankar <[email protected]> Signed-off-by: Will Deacon <[email protected]> Acked-by: Manivannan Sadhasivam <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 5b47348 commit b7d9aae

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

arch/arm64/mm/dma-mapping.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,22 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
3636
{
3737
unsigned long start = (unsigned long)page_address(page);
3838

39-
dcache_clean_poc(start, start + size);
39+
/*
40+
* The architecture only requires a clean to the PoC here in order to
41+
* meet the requirements of the DMA API. However, some vendors (i.e.
42+
* Qualcomm) abuse the DMA API for transferring buffers from the
43+
* non-secure to the secure world, resetting the system if a non-secure
44+
* access shows up after the buffer has been transferred:
45+
*
46+
* https://lore.kernel.org/r/[email protected]
47+
*
48+
* Using clean+invalidate appears to make this issue less likely, but
49+
* the drivers themselves still need fixing as the CPU could issue a
50+
* speculative read from the buffer via the linear mapping irrespective
51+
* of the cache maintenance we use. Once the drivers are fixed, we can
52+
* relax this to a clean operation.
53+
*/
54+
dcache_clean_inval_poc(start, start + size);
4055
}
4156

4257
#ifdef CONFIG_IOMMU_DMA

0 commit comments

Comments
 (0)