On Thu, Feb 04, 2010 at 10:57:49PM +0500, Anton Maksimenkov wrote:
> 2010/2/3 Owain Ainsworth <zer...@googlemail.com>:
> > ...you can't just go straight to the start of the map.
> > Say i386 where W^X is done using segments. if you dump
> > something right at the other end of the segment, that pretty much screws
> > it. Perhaps going back to the min hint for the protection and trying to
> > push just a little bit down may work?
> 
> 2010/2/4 Ariane van der Steldt <ari...@stack.nl>:
> > mmap(..., MAP_FIXED) requires a search by addr.
> > uvm_map_findspace() should also be able to take an addr constraint:
> > like Oga said, i386 has a segmented view of memory wrt W^X.
> ...
> > One more problem you may face, is uvm_km_getpage starvation. If it
> > happens, you'll be unable to allocate a vm_map_entry. In your design,
> > you'll need 2 per allocation most of the time. If that's too much
> > pressure, the kernel may starve itself and be unable to create new
> > entries, becoming completely jammed. This is a problem on any
> > non-pmap_direct architectures (like i386).
> I remember about MAP_FIXED, just not mentioned it in my not-so-short message 
> ;)
> And I don't want 2 vm_map_entry per allocation, I only need to keep
> each vm_map_entry in both trees. One vm_map_entry can contain 2
> separate RB_TREE entries (for both trees), so each tree can work with
> that vm_map_entry independantly.

Oh, I didn't explain clearly what I meant there.

Suppose you have a 4MB entry with free memory.
You need to allocate, say, 4kB. This would split the entry in:
[1] free range in front of allocation
[2] allocated range
[3] free range behind allocation

So from 1 entry to 3 entries, hence the 2 entries per allocation.

> Can anyone explain me what is the problem with i386 segments? Or
> better supply some links to docs which explain it.
> I don't understand what you mean - MAP_FIXED flag is the problem or it
> used as workaround for some problem?

The idea is that one part of the memory is executable, the other half is
not. We like the executable code of a process to be mapped in the
executable half, while we want data to not be in that part.
Paper by Theo has a good explanation on how the i386 works:
http://cvs.openbsd.org/papers/ven05-deraadt/index.html

Implementation can be seen in uvm_map_hint (the part between
#ifdef __i386__).

Wrt MAP_FIXED: it indicates that the caller wants the allocation on this
specific address. So you're not allowed to choose. This may mean the
range has to be broken in 3 parts, hence requiring 2 additional
map_entry (on top of the one you're editing).
Since the current code only requires one new entry, you'll be eating
entries twice as fast, which may starve uvm_km_getpage.

Ciao,
-- 
Ariane

Reply via email to