vm: if mmap address is given, try that first

Previously, the mmap address (if given) was merely used as a lower
bound, and then possibly overriden with a hint. Now, the mapping is
first tried at the exact given address. If that fails, the start of
the mmap range is used as lower bound (which is then still overridden
by the hint for efficiency).

This allows two pages to be mapped in at predefined addresses, where
the second address is lower than the first. That was not possible.
This commit is contained in:
David van Moolenbroek 2012-01-22 18:20:45 +01:00
parent c729ff0050
commit b91295a8d2

View file

@ -40,6 +40,7 @@ PUBLIC int do_mmap(message *m)
int r, n;
struct vmproc *vmp;
int mfflags = 0;
vir_bytes addr;
struct vir_region *vr = NULL;
if((r=vm_isokendpt(m->m_source, &n)) != OK) {
@ -81,10 +82,20 @@ PUBLIC int do_mmap(message *m)
if(len % VM_PAGE_SIZE)
len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
if(!(vr = map_page_region(vmp,
arch_vir2map(vmp,
m->VMM_ADDR ? m->VMM_ADDR : vmp->vm_stacktop),
VM_DATATOP, len, MAP_NONE, vrflags, mfflags))) {
vr = NULL;
if (m->VMM_ADDR) {
/* An address is given, first try at that address. */
addr = arch_vir2map(vmp, m->VMM_ADDR);
vr = map_page_region(vmp, addr, 0, len, MAP_NONE,
vrflags, mfflags);
}
if (!vr) {
/* No address given or address already in use. */
addr = arch_vir2map(vmp, vmp->vm_stacktop);
vr = map_page_region(vmp, addr, VM_DATATOP, len,
MAP_NONE, vrflags, mfflags);
}
if (!vr) {
return ENOMEM;
}
} else {