Message ID | 7942c970d1071643f3763de6eaf6d55a3945a069.1456225103.git.brian.starkey@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, 29 Feb 2016 16:09:24 +0000 Brian Starkey <brian.starkey@arm.com> wrote: > Use memset_io() for DMA_MEMORY_IO mappings which are mapped as I/O > memory, and regular memset() for DMA_MEMORY_MAP mappings. > > This fixes the below alignment fault on arm64 for DMA_MEMORY_IO > mappings, where memset() uses the DC ZVA instruction which is > invalid on device memory. What's the urgency of this fix? "Hair on fire needed in stable asap" or "Nice to have in there for 4.6" or what?
Hi Andrew, On Mon, Feb 29, 2016 at 03:17:49PM -0800, Andrew Morton wrote: >On Mon, 29 Feb 2016 16:09:24 +0000 Brian Starkey <brian.starkey@arm.com> wrote: > >> Use memset_io() for DMA_MEMORY_IO mappings which are mapped as I/O >> memory, and regular memset() for DMA_MEMORY_MAP mappings. >> >> This fixes the below alignment fault on arm64 for DMA_MEMORY_IO >> mappings, where memset() uses the DC ZVA instruction which is >> invalid on device memory. > >What's the urgency of this fix? "Hair on fire needed in stable asap" >or "Nice to have in there for 4.6" or what? > No-one else is complaining so probably not the former. If it could make 4.6 though that would be grand. As for stable, anything before 3.15 doesn't hit the fault (on arm64) because memset() is different, so probably not needed there. For anything after that this patch in isolation isn't a full fix, because dma_init_coherent_memory() will still use the wrong mapping function for DMA_MEMORY_MAP. In that case, I think it needs to be the whole series or nothing. I don't have a strong opinion either way, but perhaps someone else does. Thanks Brian
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 25bb398..bdf28f7 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -187,7 +187,10 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, */ *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); *ret = mem->virt_base + (pageno << PAGE_SHIFT); - memset(*ret, 0, size); + if (mem->flags & DMA_MEMORY_MAP) + memset(*ret, 0, size); + else + memset_io(*ret, 0, size); spin_unlock_irqrestore(&mem->spinlock, flags); return 1;