On Wed, 6 Jul 2011, Arnd Bergmann wrote:
On Wednesday 06 July 2011, Russell King - ARM Linux wrote:
On Wed, Jul 06, 2011 at 04:51:49PM +0200, Arnd Bergmann wrote:
On Wednesday 06 July 2011, Russell King - ARM Linux wrote:
I don't see how. The pages get allocated from an unmapped area or memory, mapped into the kernel address space as uncached or wc and then cleared. This should be the same for lowmem or highmem pages.
You don't want to clear them via their uncached or WC mapping, but via their cached mapping _before_ they get their alternative mapping, and flush any cached out of that mapping - both L1 and L2 caches.
But there can't be any other mapping, which is the whole point of the exercise to use highmem. Quoting from the new dma_alloc_area() function:
c = arm_vmregion_alloc(&area->vm, align, size, gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); if (!c) return NULL; memset((void *)c->vm_start, 0, size);
area->vm here points to an uncached location, which means that we already zero the data through the uncached mapping. I don't see how it's getting worse than it is already.
If you get a highmem page, because the cache is VIPT, that page might still be cached even if it wasn't mapped. With a VIVT cache we must flush the cache whenever a highmem page is unmapped. There is no such restriction with VIPT i.e. ARMv6 and above. Therefore to make sure the highmem page you get doesn't have cache lines associated to it, you must first map it cacheable, then perform cache invalidation on it, and eventually remap it as non-cacheable. This is necessary because there is no way to perform cache maintenance on L1 cache using physical addresses unfortunately. See commit 7e5a69e83b for an example of what this entails (fortunately commit 3e4d3af501 made things much easier and therefore commit 39af22a79 greatly simplified things).
Nicolas