do_mmap: give addr argument a chance even if not MAP_FIXED
hugectl relies on that to check if a range is free Change-Id: I97963eef15c866f642e884b063b5caf5d827c776
This commit is contained in:
committed by
Dominique Martinet
parent
9a0eb915fb
commit
f17c30da07
@@ -1702,13 +1702,18 @@ SYSCALL_DECLARE(mmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define VALID_DUMMY_ADDR ((region->user_start + PTL3_SIZE - 1) & ~(PTL3_SIZE - 1))
|
#define VALID_DUMMY_ADDR ((region->user_start + PTL3_SIZE - 1) & ~(PTL3_SIZE - 1))
|
||||||
addr = (flags & MAP_FIXED)? addr0: VALID_DUMMY_ADDR;
|
addr = addr0;
|
||||||
len = (len0 + pgsize - 1) & ~(pgsize - 1);
|
len = (len0 + pgsize - 1) & ~(pgsize - 1);
|
||||||
|
recheck:
|
||||||
if ((addr & (pgsize - 1))
|
if ((addr & (pgsize - 1))
|
||||||
|| (len == 0)
|
|| (len == 0)
|
||||||
|| !(flags & (MAP_SHARED | MAP_PRIVATE))
|
|| !(flags & (MAP_SHARED | MAP_PRIVATE))
|
||||||
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
|
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
|
||||||
|| (off0 & (pgsize - 1))) {
|
|| (off0 & (pgsize - 1))) {
|
||||||
|
if (!(flags & MAP_FIXED) && addr != VALID_DUMMY_ADDR) {
|
||||||
|
addr = VALID_DUMMY_ADDR;
|
||||||
|
goto recheck;
|
||||||
|
}
|
||||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):EINVAL\n",
|
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):EINVAL\n",
|
||||||
addr0, len0, prot, flags0, fd, off0);
|
addr0, len0, prot, flags0, fd, off0);
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
@@ -1718,6 +1723,10 @@ SYSCALL_DECLARE(mmap)
|
|||||||
if (addr < region->user_start
|
if (addr < region->user_start
|
||||||
|| region->user_end <= addr
|
|| region->user_end <= addr
|
||||||
|| len > (region->user_end - region->user_start)) {
|
|| len > (region->user_end - region->user_start)) {
|
||||||
|
if (!(flags & MAP_FIXED) && addr != VALID_DUMMY_ADDR) {
|
||||||
|
addr = VALID_DUMMY_ADDR;
|
||||||
|
goto recheck;
|
||||||
|
}
|
||||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
||||||
addr0, len0, prot, flags0, fd, off0);
|
addr0, len0, prot, flags0, fd, off0);
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
|
|||||||
@@ -1533,13 +1533,21 @@ static int search_free_space(size_t len, int pgshift, uintptr_t *addrp)
|
|||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
struct vm_regions *region = &thread->vm->region;
|
struct vm_regions *region = &thread->vm->region;
|
||||||
intptr_t addr;
|
intptr_t addr;
|
||||||
int error;
|
int error = 0;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
size_t pgsize = (size_t)1 << pgshift;
|
size_t pgsize = (size_t)1 << pgshift;
|
||||||
|
|
||||||
dkprintf("%s: len: %lu, pgshift: %d\n",
|
dkprintf("%s: len: %lu, pgshift: %d\n",
|
||||||
__FUNCTION__, len, pgshift);
|
__FUNCTION__, len, pgshift);
|
||||||
|
|
||||||
|
/* try given addr first */
|
||||||
|
addr = *addrp;
|
||||||
|
if (addr != 0) {
|
||||||
|
range = lookup_process_memory_range(thread->vm, addr, addr+len);
|
||||||
|
if (range == NULL)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
addr = region->map_end;
|
addr = region->map_end;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
addr = (addr + pgsize - 1) & ~(pgsize - 1);
|
addr = (addr + pgsize - 1) & ~(pgsize - 1);
|
||||||
@@ -1560,7 +1568,6 @@ static int search_free_space(size_t len, int pgshift, uintptr_t *addrp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
region->map_end = addr + len;
|
region->map_end = addr + len;
|
||||||
error = 0;
|
|
||||||
*addrp = addr;
|
*addrp = addr;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|||||||
Reference in New Issue
Block a user