Memory inconsistency when mmap()ping

Russell King - ARM Linux linux at arm.linux.org.uk
Wed Jan 2 11:13:41 EST 2013


On Wed, Jan 02, 2013 at 12:38:47PM +0100, Christoph M. wrote:
> On Wed, Jan 2, 2013 at 11:21 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Wed, Jan 02, 2013 at 10:59:55AM +0100, Christoph M. wrote:
> >> I'm experiencing a strange problem when mmap()ping memory
> >> to userspace on ARM-based Linux System.
> >
> > You're running into the standard problems with virtually tagged caches.
> 
> On bootup the kernel reports this:
> [    0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction c
> ache
> 
> So the cache should be physically tagged and I would expect that there are
> no aliasing problems.
> 
> >> Now to the technical details:
> >>  * The memory is allocated using kzalloc(PAGE_SIZE, GFP_KERNEL);
> >>  * The event counter is a u32 value which is stored at offset 0 of
> >>    the buffer.
> >>  * When accessing (read/write) the buffer from kernelspace a call
> >>    to mb() is done afterwards.
> >>  * My mmap() code does this:
> >>      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> >
> > And doing that will violate the requirements of the ARMv7 architecture
> > that all mappings of the same physical memory space will be of the same
> > type (let alone, have the same attributes.)
> 
> Is such a mapping possible for sharing a physical page between
> userspace and kernelspace?
> If yes, how is such a mapping, using the same attributes, done?

Don't use pgprot_noncached() - you'll then have the same memory type
and cacheability as the kernel mapping and everything should work on
PIPT and non-aliasing VIPT caches.

It _won't_ work on VIVT or aliasing VIPT caches though.

> > The kernel mapping will still be 'memory like' and 'cacheable', maybe
> > even with write-allocation.
> 
> Does this mean, that using uncached memory for my buffer (and use
> an uncached mapping for userspace) should work?

That will work but its hard to make kernel memory uncached.

> If yes, can you point me in the right direction, to get uncached memory
> from the kernel?
> 
> >From what I understand now is, that my buffer is mapped twice:
>  * using caches in kernelspace and
>  * uncached in userspace
> This not allowed for the ARMv7 architecture and causes the problems
> I encountered.
> So I need a solution to either map the page either cached or uncached
> on both sides (userspace and kernelspace).
> Is this correct?

Correct.



More information about the linux-arm mailing list