[PATCH 1/1] arm64:lib: Use Linaro's memset routine to avoid DC instruction

Catalin Marinas catalin.marinas at arm.com
Fri May 8 01:55:25 PDT 2015


On Fri, May 08, 2015 at 03:23:22PM +1000, Wendy Liang wrote:
> Currently the DC ZVA is used to zero out memory which is causing unaligned
> fault due to the follows:
> "If the memory region being zeroed is any type of Device memory, these
> instructions give an alignment fault which is prioritized in the same way
> as other alignment faults that are determined by the memory type."
> from arm reference menual.

Which is the right thing to do. You are not supposed to use memset() on
Device memory, we have memset_io() for this.

> We have carved out top memory from DDR as the memory for the device from DTS:
> ----
> reserved-memory {
>                 #address-cells = <2>;
>                 #size-cells = <1>;
>                 ranges;
>                 rproc_0_reserved: rproc at 3ed000000 {
>                         no-map;
>                         reg = <0x0 0x3ed00000 0x1000000>;
>                 };
>         };
> 
>  amba {
>                 example at 0 {
>                         reg = <0x0 0x3ed00000 0x800000>;
> 			...
> 		};
> };
> ----

Why not using CMA?

> We use dma_coherent_declare_memory() to declare the memory for DMA operations.
> We use memset() initialize the memory with 0.
> memset calls dc zva to zeroing the memory however it thinks the memory
> is not part of system (somehow even it is part of DDR) and causing
> unalignment fault.

So dma_init_coherent_memory() uses ioremap() to map such mapping with
the Device attributes. It then stores this cookie in
dma_coherent_mem.virt_base losing any __iomem annotation and declaring
it safe for direct access (without the started I/O accessors). This is
wrong. In addition, the assumption we have for coherent DMA buffers is
that they are mapped as Normal memory (cacheable or non-cacheable,
depending on what coherency the SoC supports).

I'm not taking this patch, the correct fix is a combination of
dma_init_coherent_memory() and dma_alloc_from_coherent(). A quick hack
could be to use ioremap_wc() but it still doesn't look right to me
(well, it's fine only if flags are DMA_MEMORY_IO and
dma_alloc_from_coherent() would use memset_io when this flag is
detected but accesses to such buffer should be done with readl/writel).

-- 
Catalin



More information about the linux-arm-kernel mailing list