public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: uClinux development list <uclinux-dev@uclinux.org>
Cc: dhowells@redhat.com, stefani@seibold.net,
	linux-kernel@vger.kernel.org, jie.zhang@analog.com
Subject: Re: [uClinux-dev] [PATCH 5/7] NOMMU: Avoiding duplicate icache flushes of shared maps
Date: Tue, 15 Dec 2009 10:52:46 +0000	[thread overview]
Message-ID: <24260.1260874366@redhat.com> (raw)
In-Reply-To: <20091215004143.GA15785@shareable.org>

Jamie Lokier <jamie@shareable.org> wrote:

> This looks like it won't work in the following sequence:
> 
>     process A maps MAP_SHARED, PROT_READ|PROT_EXEC (flushes icache)
>     process B maps MAP_SHARED, PROT_READ|PROT_WRITE
>         and proceeds to modify the data
>     process C maps MAP_SHARED, PROT_READ|PROT_EXEC (no icache flush)

Assuming all the above refer to the same piece of RAM, there's no reason that
process A will will continue to function correctly executing from the first
mapping if process B writes to that RAM through the second mapping.

There's also no point doing an icache flush unless you first flush the dcache
back to the RAM - and we don't know to do that because the O/S does not know
whether the RAM has been changed.  So we'd have to do an unconditional dcache
flush too for the entire RAM segment.

I'd prefer to leave this to the writers.  If they're mad enough to write
shared code that undergoes runtime modification, and then want to run it on
NOMMU...

So my question back to you is: would it work anyway?

Note that some arches have a specific cache flushing system call.  Perhaps
this should be extended to all.

> What about icache flushes in these cases:
> 
> When using mprotect() PROT_READ|PROT_WRITE -> PROT_READ|PROT_EXEC,
> e.g. as an FDPIC implementation may do when updating PLT entries.

There is no mprotect() on NOMMU, at least not at the moment.  It may be
reasonable to add support for someone turning on/off the PROT_EXEC and
PROT_WRITE bits, and make it flush dcache to RAM when WRITE is turned off, and
flush the icache when EXEC is turned on, in that order.

However, as Mike said, we don't do this in FDPIC.  The code sections are
immutable blobs, and are mapped MAP_PRIVATE, PROT_READ|PROT_EXEC from the
start.  That way, mmap() will share them for us and even do XIP without special
support in userspace.  FDPIC uses a non-executable GOT in the data area, and
loads the function pointer and new GOT pointer out of it before making a call.

> And when calling msync(), like this:
> 
>     process A maps MAP_SHARED, PROT_READ|PROT_EXEC (flushes icache)
>     process B maps MAP_SHARED, PROT_READ|PROT_WRITE
>         and proceeds to modify the data
>     process A calls msync()
>         and proceeds to execute the modified contents

Similarly, we don't provide msync().  On NOMMU, memory mappings cannot be
shared from disks that aren't based direct-access (quasi-)memory (e.g. ramfs,
MTD).

We could, perhaps, partially implement msync() to flush the appropriate caches.
We might even be able to add extra flags to msync() so that it can flush just
the CPU caches - that would obviate the need for separate syscalls for this
purpose.

> Do you think the mprotect() and msync() calls should flush icache in
> those cases?

I don't see that msync() should flush the icache at all.  It's purpose is to
flush data to the backing store.

Also, don't forget that under NOMMU conditions, you have no idea if the data
has been modified.

> But in the first example above, I don't see how process C could be
> expected to know it must flush icache, and process B could just be an
> "optimised with writable mmap" file copy, so it shouldn't have
> responsibility for icache either.

It's manually executing off of a MAP_SHARED region, a region that others have
open for write.  It has to look after its own semantics.  This applied too to
process A.

> If seen arguments for it, and arguments that the executing process can
> be expected to explicitly flush icache itself in those cases because
> it knows what it is doing.  (Personally I lean towards the kernel
> should be doing it.  IRIX interestingly offers both alternatives, with
> a PROT_EXEC_NOFLUSH).

I disagree, at least in the case of MAP_SHARED regions.  You need to manage
your own coherency.  Again, see process A vs process B.

> Or is icache fully flushed on every context switch on all nommu
> architectures anyway, and defined to do so?

That would be a sure performance killer, and, in any case, wouldn't help on an
SMP system.

David

  parent reply	other threads:[~2009-12-15 10:53 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-10 13:57 [PATCH 1/7] security: do not check mmap_min_addr on nommu systems David Howells
2009-12-10 13:58 ` [PATCH 2/7] NOMMU: Provide per-task stack usage through /proc for NOMMU David Howells
2009-12-14 23:33   ` Mike Frysinger
2009-12-10 13:58 ` [PATCH 3/7] NOMMU: fix malloc performance by adding uninitialized flag David Howells
2009-12-10 13:58 ` [PATCH 4/7] FDPIC: Respect PT_GNU_STACK exec protection markings when creating NOMMU stack David Howells
2009-12-10 13:58 ` [PATCH 5/7] NOMMU: Avoiding duplicate icache flushes of shared maps David Howells
2009-12-14 23:55   ` Mike Frysinger
2009-12-15  0:41   ` [uClinux-dev] " Jamie Lokier
2009-12-15  4:52     ` Mike Frysinger
2009-12-15 10:52     ` David Howells [this message]
2009-12-10 13:58 ` [PATCH 6/7] NOMMU: Use copy_*_user_page() in access_process_vm() David Howells
2009-12-14 23:51   ` Mike Frysinger
2009-12-10 13:58 ` [PATCH 7/7] NOMMU: ramfs: Drop unused local var David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=24260.1260874366@redhat.com \
    --to=dhowells@redhat.com \
    --cc=jie.zhang@analog.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stefani@seibold.net \
    --cc=uclinux-dev@uclinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox